commit 0f82febd5aeddcf5a6e1a916e29d4b9b86bd483f
Author: okbob@github.com <pavel.stehule@gmail.com>
Date:   Tue Aug 18 17:47:12 2020 +0200

    namespace for each statement

diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 5a7e1a4444..f492c49513 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -912,6 +912,7 @@ stmt_perform	: K_PERFORM expr_until_semi
 						new->cmd_type = PLPGSQL_STMT_PERFORM;
 						new->lineno   = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->expr  = $2;
 
 						$$ = (PLpgSQL_stmt *)new;
@@ -926,6 +927,7 @@ stmt_call		: K_CALL
 						new->cmd_type = PLPGSQL_STMT_CALL;
 						new->lineno = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->expr = read_sql_stmt("CALL ");
 						new->is_call = true;
 
@@ -941,6 +943,7 @@ stmt_call		: K_CALL
 						new->cmd_type = PLPGSQL_STMT_CALL;
 						new->lineno = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->expr = read_sql_stmt("DO ");
 						new->is_call = false;
 
@@ -957,6 +960,7 @@ stmt_assign		: assign_var assign_operator expr_until_semi
 						new->cmd_type = PLPGSQL_STMT_ASSIGN;
 						new->lineno   = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->varno = $1->dno;
 						new->expr  = $3;
 
@@ -1396,6 +1400,7 @@ for_control		: for_variable K_IN
 							new = (PLpgSQL_stmt_forc *) palloc0(sizeof(PLpgSQL_stmt_forc));
 							new->cmd_type = PLPGSQL_STMT_FORC;
 							new->stmtid = ++plpgsql_curr_compile->nstatements;
+							new->ns = plpgsql_ns_top();
 							new->curvar = cursor->dno;
 
 							/* Should have had a single variable name */
@@ -1547,6 +1552,7 @@ for_control		: for_variable K_IN
 								new = palloc0(sizeof(PLpgSQL_stmt_fors));
 								new->cmd_type = PLPGSQL_STMT_FORS;
 								new->stmtid = ++plpgsql_curr_compile->nstatements;
+								new->ns = plpgsql_ns_top();
 								if ($1.row)
 								{
 									new->var = (PLpgSQL_variable *) $1.row;
@@ -1648,6 +1654,7 @@ stmt_foreach_a	: opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRA
 						new->cmd_type = PLPGSQL_STMT_FOREACH_A;
 						new->lineno = plpgsql_location_to_lineno(@2);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->label = $1;
 						new->slice = $4;
 						new->expr = $7;
@@ -2010,6 +2017,7 @@ stmt_dynexecute : K_EXECUTE
 						new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
 						new->lineno = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->query = expr;
 						new->into = false;
 						new->strict = false;
@@ -2067,6 +2075,7 @@ stmt_open		: K_OPEN cursor_variable
 						new->cmd_type = PLPGSQL_STMT_OPEN;
 						new->lineno = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->curvar = $2->dno;
 						new->cursor_options = CURSOR_OPT_FAST_PLAN;
 
@@ -2192,6 +2201,7 @@ stmt_close		: K_CLOSE cursor_variable ';'
 						new->cmd_type = PLPGSQL_STMT_CLOSE;
 						new->lineno = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->curvar = $2->dno;
 
 						$$ = (PLpgSQL_stmt *)new;
@@ -2213,6 +2223,7 @@ stmt_commit		: K_COMMIT opt_transaction_chain ';'
 						new->cmd_type = PLPGSQL_STMT_COMMIT;
 						new->lineno = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->chain = $2;
 
 						$$ = (PLpgSQL_stmt *)new;
@@ -2227,6 +2238,7 @@ stmt_rollback	: K_ROLLBACK opt_transaction_chain ';'
 						new->cmd_type = PLPGSQL_STMT_ROLLBACK;
 						new->lineno = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->chain = $2;
 
 						$$ = (PLpgSQL_stmt *)new;
@@ -2247,7 +2259,7 @@ stmt_set	: K_SET
 						new->cmd_type = PLPGSQL_STMT_SET;
 						new->lineno = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
-
+						new->ns = plpgsql_ns_top();
 						new->expr = read_sql_stmt("SET ");
 
 						$$ = (PLpgSQL_stmt *)new;
@@ -2260,6 +2272,7 @@ stmt_set	: K_SET
 						new->cmd_type = PLPGSQL_STMT_SET;
 						new->lineno = plpgsql_location_to_lineno(@1);
 						new->stmtid = ++plpgsql_curr_compile->nstatements;
+						new->ns = plpgsql_ns_top();
 						new->expr = read_sql_stmt("RESET ");
 
 						$$ = (PLpgSQL_stmt *)new;
@@ -3377,6 +3390,7 @@ make_return_query_stmt(int location)
 	new->cmd_type = PLPGSQL_STMT_RETURN_QUERY;
 	new->lineno = plpgsql_location_to_lineno(location);
 	new->stmtid = ++plpgsql_curr_compile->nstatements;
+	new->ns = plpgsql_ns_top();
 
 	/* check for RETURN QUERY EXECUTE */
 	if ((tok = yylex()) != K_EXECUTE)
@@ -4051,6 +4065,7 @@ make_case(int location, PLpgSQL_expr *t_expr,
 	new->cmd_type = PLPGSQL_STMT_CASE;
 	new->lineno = plpgsql_location_to_lineno(location);
 	new->stmtid = ++plpgsql_curr_compile->nstatements;
+	new->ns = plpgsql_ns_top();
 	new->t_expr = t_expr;
 	new->t_varno = 0;
 	new->case_when_list = case_when_list;
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index bec2429555..80e4210ebd 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -475,6 +475,9 @@ typedef struct PLpgSQL_stmt
 	 * per-statement metrics.
 	 */
 	unsigned int stmtid;
+
+	/* namespace chain visible to this statement */
+	PLpgSQL_nsitem *ns;
 } PLpgSQL_stmt;
 
 /*
@@ -515,6 +518,7 @@ typedef struct PLpgSQL_stmt_block
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	char	   *label;
 	List	   *body;			/* List of statements */
 	int			n_initvars;		/* Length of initvarnos[] */
@@ -530,6 +534,7 @@ typedef struct PLpgSQL_stmt_assign
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	int			varno;
 	PLpgSQL_expr *expr;
 } PLpgSQL_stmt_assign;
@@ -542,6 +547,7 @@ typedef struct PLpgSQL_stmt_perform
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *expr;
 } PLpgSQL_stmt_perform;
 
@@ -553,6 +559,7 @@ typedef struct PLpgSQL_stmt_call
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *expr;
 	bool		is_call;
 	PLpgSQL_variable *target;
@@ -566,6 +573,7 @@ typedef struct PLpgSQL_stmt_commit
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	bool		chain;
 } PLpgSQL_stmt_commit;
 
@@ -577,6 +585,7 @@ typedef struct PLpgSQL_stmt_rollback
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	bool		chain;
 } PLpgSQL_stmt_rollback;
 
@@ -588,6 +597,7 @@ typedef struct PLpgSQL_stmt_set
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *expr;
 } PLpgSQL_stmt_set;
 
@@ -608,6 +618,7 @@ typedef struct PLpgSQL_stmt_getdiag
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	bool		is_stacked;		/* STACKED or CURRENT diagnostics area? */
 	List	   *diag_items;		/* List of PLpgSQL_diag_item */
 } PLpgSQL_stmt_getdiag;
@@ -620,6 +631,7 @@ typedef struct PLpgSQL_stmt_if
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *cond;			/* boolean expression for THEN */
 	List	   *then_body;		/* List of statements */
 	List	   *elsif_list;		/* List of PLpgSQL_if_elsif structs */
@@ -644,6 +656,7 @@ typedef struct PLpgSQL_stmt_case
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *t_expr;		/* test expression, or NULL if none */
 	int			t_varno;		/* var to store test expression value into */
 	List	   *case_when_list; /* List of PLpgSQL_case_when structs */
@@ -669,6 +682,7 @@ typedef struct PLpgSQL_stmt_loop
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	char	   *label;
 	List	   *body;			/* List of statements */
 } PLpgSQL_stmt_loop;
@@ -681,6 +695,7 @@ typedef struct PLpgSQL_stmt_while
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	char	   *label;
 	PLpgSQL_expr *cond;
 	List	   *body;			/* List of statements */
@@ -694,6 +709,7 @@ typedef struct PLpgSQL_stmt_fori
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	char	   *label;
 	PLpgSQL_var *var;
 	PLpgSQL_expr *lower;
@@ -713,6 +729,7 @@ typedef struct PLpgSQL_stmt_forq
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	char	   *label;
 	PLpgSQL_variable *var;		/* Loop variable (record or row) */
 	List	   *body;			/* List of statements */
@@ -726,6 +743,7 @@ typedef struct PLpgSQL_stmt_fors
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	char	   *label;
 	PLpgSQL_variable *var;		/* Loop variable (record or row) */
 	List	   *body;			/* List of statements */
@@ -741,6 +759,7 @@ typedef struct PLpgSQL_stmt_forc
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	char	   *label;
 	PLpgSQL_variable *var;		/* Loop variable (record or row) */
 	List	   *body;			/* List of statements */
@@ -757,6 +776,7 @@ typedef struct PLpgSQL_stmt_dynfors
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	char	   *label;
 	PLpgSQL_variable *var;		/* Loop variable (record or row) */
 	List	   *body;			/* List of statements */
@@ -773,6 +793,7 @@ typedef struct PLpgSQL_stmt_foreach_a
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	char	   *label;
 	int			varno;			/* loop target variable */
 	int			slice;			/* slice dimension, or 0 */
@@ -788,6 +809,7 @@ typedef struct PLpgSQL_stmt_open
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	int			curvar;
 	int			cursor_options;
 	PLpgSQL_expr *argquery;
@@ -804,6 +826,7 @@ typedef struct PLpgSQL_stmt_fetch
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_variable *target;	/* target (record or row) */
 	int			curvar;			/* cursor variable to fetch from */
 	FetchDirection direction;	/* fetch direction */
@@ -821,6 +844,7 @@ typedef struct PLpgSQL_stmt_close
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	int			curvar;
 } PLpgSQL_stmt_close;
 
@@ -832,6 +856,7 @@ typedef struct PLpgSQL_stmt_exit
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	bool		is_exit;		/* Is this an exit or a continue? */
 	char	   *label;			/* NULL if it's an unlabeled EXIT/CONTINUE */
 	PLpgSQL_expr *cond;
@@ -845,6 +870,7 @@ typedef struct PLpgSQL_stmt_return
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *expr;
 	int			retvarno;
 } PLpgSQL_stmt_return;
@@ -857,6 +883,7 @@ typedef struct PLpgSQL_stmt_return_next
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *expr;
 	int			retvarno;
 } PLpgSQL_stmt_return_next;
@@ -869,6 +896,7 @@ typedef struct PLpgSQL_stmt_return_query
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *query;		/* if static query */
 	PLpgSQL_expr *dynquery;		/* if dynamic query (RETURN QUERY EXECUTE) */
 	List	   *params;			/* USING arguments for dynamic query */
@@ -882,6 +910,7 @@ typedef struct PLpgSQL_stmt_raise
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	int			elog_level;
 	char	   *condname;		/* condition name, SQLSTATE, or NULL */
 	char	   *message;		/* old-style message format literal, or NULL */
@@ -906,6 +935,7 @@ typedef struct PLpgSQL_stmt_assert
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *cond;
 	PLpgSQL_expr *message;
 } PLpgSQL_stmt_assert;
@@ -918,6 +948,7 @@ typedef struct PLpgSQL_stmt_execsql
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *sqlstmt;
 	bool		mod_stmt;		/* is the stmt INSERT/UPDATE/DELETE?  Note:
 								 * mod_stmt is set when we plan the query */
@@ -934,6 +965,7 @@ typedef struct PLpgSQL_stmt_dynexecute
 	PLpgSQL_stmt_type cmd_type;
 	int			lineno;
 	unsigned int stmtid;
+	PLpgSQL_nsitem *ns;
 	PLpgSQL_expr *query;		/* string expression */
 	bool		into;			/* INTO supplied? */
 	bool		strict;			/* INTO STRICT flag */
