Re: proposal - plpgsql unique statement id

2019-01-25 Thread Pavel Stehule
čt 24. 1. 2019 v 23:08 odesílatel Tom Lane  napsal:

> Peter Eisentraut  writes:
> > committed
>
> Why didn't this patch modify the dumping logic in pl_funcs.c to print
> the IDs?  I'm not aware of other cases where we intentionally omit
> fields from debug-support printouts.
>

Currently we don't print lineno, what is maybe for user more important
information.

I looked to the code, and now I am thinking so it is little bit harder,
than I expected. Any new information can break output formatting

static void
dump_loop(PLpgSQL_stmt_loop *stmt)
{
dump_ind();
printf("LOOP\n");

dump_stmts(stmt->body);

dump_ind();
printf("ENDLOOP\n");
}

can looks like

static void
dump_loop(PLpgSQL_stmt_loop *stmt, int stmtid_width)
{
dump_ind();
printf("%*d LOOP\n", stmtid_width, stmt->stmtid);

dump_stmts(stmt->body);

dump_ind();
printf(" ENDLOOP\n");
}

It is some what do you expect ?

Regards

Maybe more simple


static void
dump_loop(PLpgSQL_stmt_loop *stmt, int stmtid_width)
{
dump_ind();
printf("LOOP {%d}\n",stmt->stmtid);

dump_stmts(stmt->body);

dump_ind();
printf(" ENDLOOP\n");
}

Pavel



> regards, tom lane
>


Re: proposal - plpgsql unique statement id

2019-01-24 Thread Pavel Stehule
čt 24. 1. 2019 v 23:08 odesílatel Tom Lane  napsal:

> Peter Eisentraut  writes:
> > committed
>
> Why didn't this patch modify the dumping logic in pl_funcs.c to print
> the IDs?  I'm not aware of other cases where we intentionally omit
> fields from debug-support printouts.
>

I had not a idea, so this field can be useful there. I'll send a patch with
it.

Regards

Pavel



> regards, tom lane
>


Re: proposal - plpgsql unique statement id

2019-01-24 Thread Tom Lane
Peter Eisentraut  writes:
> committed

Why didn't this patch modify the dumping logic in pl_funcs.c to print
the IDs?  I'm not aware of other cases where we intentionally omit
fields from debug-support printouts.

regards, tom lane



Re: proposal - plpgsql unique statement id

2019-01-24 Thread Peter Eisentraut
On 22/01/2019 19:04, Pavel Stehule wrote:
> It was missing, fixed, thank you for check

committed

-- 
Peter Eisentraut  http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services



Re: proposal - plpgsql unique statement id

2019-01-22 Thread Pavel Stehule
út 22. 1. 2019 v 14:55 odesílatel Peter Eisentraut <
peter.eisentr...@2ndquadrant.com> napsal:

> There are still a handful of places where a statement is created but no
> stmtid is assigned.  Can you check those?
>
> src/pl/plpgsql/src/pl_exec.c:2815
> src/pl/plpgsql/src/pl_exec.c:4580
>

These statements are "fake" very short life statements without processing
via statement switch.  Should not be counted, because are dynamically
created, dropped, and stmtid should be 0 or -1 (that means it should be int
again).
Now, for both cases, the stmtid is 0, due memset to 0.


> src/pl/plpgsql/src/pl_gram.y:907
>

It was missing, fixed, thank you for check

Regards

Pavel



> --
> Peter Eisentraut  http://www.2ndQuadrant.com/
> PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
>
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 2454386af8..e7de54fc93 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -368,6 +368,8 @@ do_compile(FunctionCallInfo fcinfo,
 
 	function->fn_prokind = procStruct->prokind;
 
+	function->nstatements = 0;
+
 	/*
 	 * Initialize the compiler, particularly the namespace stack.  The
 	 * outermost namespace contains function parameters and other special
@@ -911,6 +913,8 @@ plpgsql_compile_inline(char *proc_source)
  true);
 	function->found_varno = var->dno;
 
+	function->nstatements = 0;
+
 	/*
 	 * Now parse the function's text
 	 */
@@ -1020,6 +1024,7 @@ add_dummy_return(PLpgSQL_function *function)
 
 		new = palloc0(sizeof(PLpgSQL_stmt_block));
 		new->cmd_type = PLPGSQL_STMT_BLOCK;
+		new->stmtid = ++function->nstatements;
 		new->body = list_make1(function->action);
 
 		function->action = new;
@@ -1031,6 +1036,7 @@ add_dummy_return(PLpgSQL_function *function)
 
 		new = palloc0(sizeof(PLpgSQL_stmt_return));
 		new->cmd_type = PLPGSQL_STMT_RETURN;
+		new->stmtid = ++function->nstatements;
 		new->expr = NULL;
 		new->retvarno = function->out_param_varno;
 
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 59063976b3..20aded93aa 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -414,6 +414,7 @@ pl_block		: decl_sect K_BEGIN proc_sect exception_sect K_END opt_label
 
 		new->cmd_type	= PLPGSQL_STMT_BLOCK;
 		new->lineno		= plpgsql_location_to_lineno(@2);
+		new->stmtid		= ++plpgsql_curr_compile->nstatements;
 		new->label		= $1.label;
 		new->n_initvars = $1.n_initvars;
 		new->initvarnos = $1.initvarnos;
@@ -905,6 +906,7 @@ stmt_perform	: K_PERFORM expr_until_semi
 		new = palloc0(sizeof(PLpgSQL_stmt_perform));
 		new->cmd_type = PLPGSQL_STMT_PERFORM;
 		new->lineno   = plpgsql_location_to_lineno(@1);
+		new->stmtid   = ++plpgsql_curr_compile->nstatements;
 		new->expr  = $2;
 
 		$$ = (PLpgSQL_stmt *)new;
@@ -918,6 +920,7 @@ stmt_call		: K_CALL
 		new = palloc0(sizeof(PLpgSQL_stmt_call));
 		new->cmd_type = PLPGSQL_STMT_CALL;
 		new->lineno = plpgsql_location_to_lineno(@1);
+		new->stmtid = ++plpgsql_curr_compile->nstatements;
 		new->expr = read_sql_stmt("CALL ");
 		new->is_call = true;
 
@@ -932,6 +935,7 @@ stmt_call		: K_CALL
 		new = palloc0(sizeof(PLpgSQL_stmt_call));
 		new->cmd_type = PLPGSQL_STMT_CALL;
 		new->lineno = plpgsql_location_to_lineno(@1);
+		new->stmtid = ++plpgsql_curr_compile->nstatements;
 		new->expr = read_sql_stmt("DO ");
 		new->is_call = false;
 
@@ -947,6 +951,7 @@ stmt_assign		: assign_var assign_operator expr_until_semi
 		new = palloc0(sizeof(PLpgSQL_stmt_assign));
 		new->cmd_type = PLPGSQL_STMT_ASSIGN;
 		new->lineno   = plpgsql_location_to_lineno(@1);
+		new->stmtid   = ++plpgsql_curr_compile->nstatements;
 		new->varno = $1->dno;
 		new->expr  = $3;
 
@@ -962,6 +967,7 @@ stmt_getdiag	: K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
 		new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
 		new->cmd_type = PLPGSQL_STMT_GETDIAG;
 		new->lineno   = plpgsql_location_to_lineno(@1);
+		new->stmtid   = ++plpgsql_curr_compile->nstatements;
 		new->is_stacked = $2;
 		new->diag_items = $4;
 
@@ -1149,6 +1155,7 @@ stmt_if			: K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';'
 		new = palloc0(sizeof(PLpgSQL_stmt_if));
 		new->cmd_type	= PLPGSQL_STMT_IF;
 		new->lineno		= plpgsql_location_to_lineno(@1);
+		new->stmtid		= ++plpgsql_curr_compile->nstatements;
 		new->cond		= $2;
 		new->then_body	= $3;
 		new->elsif_list = $4;
@@ -1253,6 +1260,7 @@ stmt_loop		: opt_loop_label K_LOOP loop_body
 		new = palloc0(sizeof(PLpgSQL_stmt_loop));
 		new->cmd_type = PLPGSQL_STMT_LOOP;
 		new->lineno   = plpgsql_location_to_lineno(@2);
+		new->stmtid   = ++plpgsql_curr_compile->nstatements;
 		new->label	  = $1;
 		new->body	  = $3.stmts;
 
@@ -1270,6 +1278,7 @@ stmt_while		: opt_loop_label K_WHILE 

Re: proposal - plpgsql unique statement id

2019-01-22 Thread Peter Eisentraut
There are still a handful of places where a statement is created but no
stmtid is assigned.  Can you check those?

src/pl/plpgsql/src/pl_exec.c:2815
src/pl/plpgsql/src/pl_exec.c:4580
src/pl/plpgsql/src/pl_gram.y:907

-- 
Peter Eisentraut  http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services



Re: proposal - plpgsql unique statement id

2019-01-18 Thread Pavel Stehule
pá 18. 1. 2019 v 8:56 odesílatel Peter Eisentraut <
peter.eisentr...@2ndquadrant.com> napsal:

> On 04/01/2019 15:07, Pavel Stehule wrote:
> > pá 4. 1. 2019 v 13:58 odesílatel Peter Eisentraut
> >  > > napsal:
> >
> > On 13/11/2018 14:35, Pavel Stehule wrote:
> > > I am try to enhance plpgsql_check about profiler functionality and
> I
> > > have to solve how to identify every plpgsql statement across
> different
> > > sessions. There is lineno, but surely it should not be unique. I
> > propose
> > > introduce stmtid to every statement structure. This number will be
> > > unique inside function.
> >
> > That seems reasonable enough, although I wouldn't use 0 as a valid
> > stmtid.
> >
> > done
>
> Related, should stmtid be unsigned int rather than signed int?
>

done

Regards

Pavel

>
> --
> Peter Eisentraut  http://www.2ndQuadrant.com/
> PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
>
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 2454386af8..e7de54fc93 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -368,6 +368,8 @@ do_compile(FunctionCallInfo fcinfo,
 
 	function->fn_prokind = procStruct->prokind;
 
+	function->nstatements = 0;
+
 	/*
 	 * Initialize the compiler, particularly the namespace stack.  The
 	 * outermost namespace contains function parameters and other special
@@ -911,6 +913,8 @@ plpgsql_compile_inline(char *proc_source)
  true);
 	function->found_varno = var->dno;
 
+	function->nstatements = 0;
+
 	/*
 	 * Now parse the function's text
 	 */
@@ -1020,6 +1024,7 @@ add_dummy_return(PLpgSQL_function *function)
 
 		new = palloc0(sizeof(PLpgSQL_stmt_block));
 		new->cmd_type = PLPGSQL_STMT_BLOCK;
+		new->stmtid = ++function->nstatements;
 		new->body = list_make1(function->action);
 
 		function->action = new;
@@ -1031,6 +1036,7 @@ add_dummy_return(PLpgSQL_function *function)
 
 		new = palloc0(sizeof(PLpgSQL_stmt_return));
 		new->cmd_type = PLPGSQL_STMT_RETURN;
+		new->stmtid = ++function->nstatements;
 		new->expr = NULL;
 		new->retvarno = function->out_param_varno;
 
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 59063976b3..55c041c175 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -414,6 +414,7 @@ pl_block		: decl_sect K_BEGIN proc_sect exception_sect K_END opt_label
 
 		new->cmd_type	= PLPGSQL_STMT_BLOCK;
 		new->lineno		= plpgsql_location_to_lineno(@2);
+		new->stmtid 	= ++plpgsql_curr_compile->nstatements;
 		new->label		= $1.label;
 		new->n_initvars = $1.n_initvars;
 		new->initvarnos = $1.initvarnos;
@@ -918,6 +919,7 @@ stmt_call		: K_CALL
 		new = palloc0(sizeof(PLpgSQL_stmt_call));
 		new->cmd_type = PLPGSQL_STMT_CALL;
 		new->lineno = plpgsql_location_to_lineno(@1);
+		new->stmtid = ++plpgsql_curr_compile->nstatements;
 		new->expr = read_sql_stmt("CALL ");
 		new->is_call = true;
 
@@ -932,6 +934,7 @@ stmt_call		: K_CALL
 		new = palloc0(sizeof(PLpgSQL_stmt_call));
 		new->cmd_type = PLPGSQL_STMT_CALL;
 		new->lineno = plpgsql_location_to_lineno(@1);
+		new->stmtid = ++plpgsql_curr_compile->nstatements;
 		new->expr = read_sql_stmt("DO ");
 		new->is_call = false;
 
@@ -947,6 +950,7 @@ stmt_assign		: assign_var assign_operator expr_until_semi
 		new = palloc0(sizeof(PLpgSQL_stmt_assign));
 		new->cmd_type = PLPGSQL_STMT_ASSIGN;
 		new->lineno   = plpgsql_location_to_lineno(@1);
+		new->stmtid = ++plpgsql_curr_compile->nstatements;
 		new->varno = $1->dno;
 		new->expr  = $3;
 
@@ -962,6 +966,7 @@ stmt_getdiag	: K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
 		new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
 		new->cmd_type = PLPGSQL_STMT_GETDIAG;
 		new->lineno   = plpgsql_location_to_lineno(@1);
+		new->stmtid	  = ++plpgsql_curr_compile->nstatements;
 		new->is_stacked = $2;
 		new->diag_items = $4;
 
@@ -1149,6 +1154,7 @@ stmt_if			: K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';'
 		new = palloc0(sizeof(PLpgSQL_stmt_if));
 		new->cmd_type	= PLPGSQL_STMT_IF;
 		new->lineno		= plpgsql_location_to_lineno(@1);
+		new->stmtid		= ++plpgsql_curr_compile->nstatements;
 		new->cond		= $2;
 		new->then_body	= $3;
 		new->elsif_list = $4;
@@ -1253,6 +1259,7 @@ stmt_loop		: opt_loop_label K_LOOP loop_body
 		new = palloc0(sizeof(PLpgSQL_stmt_loop));
 		new->cmd_type = PLPGSQL_STMT_LOOP;
 		new->lineno   = plpgsql_location_to_lineno(@2);
+		new->stmtid   = ++plpgsql_curr_compile->nstatements;
 		new->label	  = $1;
 		new->body	  = $3.stmts;
 
@@ -1270,6 +1277,7 @@ stmt_while		: opt_loop_label K_WHILE expr_until_loop loop_body
 		new = palloc0(sizeof(PLpgSQL_stmt_while));
 		new->cmd_type = PLPGSQL_STMT_WHILE;
 		new->lineno   = 

Re: proposal - plpgsql unique statement id

2019-01-17 Thread Peter Eisentraut
On 04/01/2019 15:07, Pavel Stehule wrote:
> pá 4. 1. 2019 v 13:58 odesílatel Peter Eisentraut
>  > napsal:
> 
> On 13/11/2018 14:35, Pavel Stehule wrote:
> > I am try to enhance plpgsql_check about profiler functionality and I
> > have to solve how to identify every plpgsql statement across different
> > sessions. There is lineno, but surely it should not be unique. I
> propose
> > introduce stmtid to every statement structure. This number will be
> > unique inside function.
> 
> That seems reasonable enough, although I wouldn't use 0 as a valid
> stmtid.
> 
> done

Related, should stmtid be unsigned int rather than signed int?

-- 
Peter Eisentraut  http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services



Re: proposal - plpgsql unique statement id

2019-01-04 Thread Pavel Stehule
pá 4. 1. 2019 v 13:58 odesílatel Peter Eisentraut <
peter.eisentr...@2ndquadrant.com> napsal:

> On 13/11/2018 14:35, Pavel Stehule wrote:
> > I am try to enhance plpgsql_check about profiler functionality and I
> > have to solve how to identify every plpgsql statement across different
> > sessions. There is lineno, but surely it should not be unique. I propose
> > introduce stmtid to every statement structure. This number will be
> > unique inside function.
>
> That seems reasonable enough, although I wouldn't use 0 as a valid stmtid.
>

done


> A documenting comment near PLpgSQL_stmt might be nice.
>

 done

Regards

Pavel


> --
> Peter Eisentraut  http://www.2ndQuadrant.com/
> PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
>
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 0e9ea10596..9e98134c05 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -368,6 +368,8 @@ do_compile(FunctionCallInfo fcinfo,
 
 	function->fn_prokind = procStruct->prokind;
 
+	function->nstatements = 0;
+
 	/*
 	 * Initialize the compiler, particularly the namespace stack.  The
 	 * outermost namespace contains function parameters and other special
@@ -911,6 +913,8 @@ plpgsql_compile_inline(char *proc_source)
  true);
 	function->found_varno = var->dno;
 
+	function->nstatements = 0;
+
 	/*
 	 * Now parse the function's text
 	 */
@@ -1020,6 +1024,7 @@ add_dummy_return(PLpgSQL_function *function)
 
 		new = palloc0(sizeof(PLpgSQL_stmt_block));
 		new->cmd_type = PLPGSQL_STMT_BLOCK;
+		new->stmtid = ++function->nstatements;
 		new->body = list_make1(function->action);
 
 		function->action = new;
@@ -1031,6 +1036,7 @@ add_dummy_return(PLpgSQL_function *function)
 
 		new = palloc0(sizeof(PLpgSQL_stmt_return));
 		new->cmd_type = PLPGSQL_STMT_RETURN;
+		new->stmtid = ++function->nstatements;
 		new->expr = NULL;
 		new->retvarno = function->out_param_varno;
 
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 59063976b3..55c041c175 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -414,6 +414,7 @@ pl_block		: decl_sect K_BEGIN proc_sect exception_sect K_END opt_label
 
 		new->cmd_type	= PLPGSQL_STMT_BLOCK;
 		new->lineno		= plpgsql_location_to_lineno(@2);
+		new->stmtid 	= ++plpgsql_curr_compile->nstatements;
 		new->label		= $1.label;
 		new->n_initvars = $1.n_initvars;
 		new->initvarnos = $1.initvarnos;
@@ -918,6 +919,7 @@ stmt_call		: K_CALL
 		new = palloc0(sizeof(PLpgSQL_stmt_call));
 		new->cmd_type = PLPGSQL_STMT_CALL;
 		new->lineno = plpgsql_location_to_lineno(@1);
+		new->stmtid = ++plpgsql_curr_compile->nstatements;
 		new->expr = read_sql_stmt("CALL ");
 		new->is_call = true;
 
@@ -932,6 +934,7 @@ stmt_call		: K_CALL
 		new = palloc0(sizeof(PLpgSQL_stmt_call));
 		new->cmd_type = PLPGSQL_STMT_CALL;
 		new->lineno = plpgsql_location_to_lineno(@1);
+		new->stmtid = ++plpgsql_curr_compile->nstatements;
 		new->expr = read_sql_stmt("DO ");
 		new->is_call = false;
 
@@ -947,6 +950,7 @@ stmt_assign		: assign_var assign_operator expr_until_semi
 		new = palloc0(sizeof(PLpgSQL_stmt_assign));
 		new->cmd_type = PLPGSQL_STMT_ASSIGN;
 		new->lineno   = plpgsql_location_to_lineno(@1);
+		new->stmtid = ++plpgsql_curr_compile->nstatements;
 		new->varno = $1->dno;
 		new->expr  = $3;
 
@@ -962,6 +966,7 @@ stmt_getdiag	: K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
 		new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
 		new->cmd_type = PLPGSQL_STMT_GETDIAG;
 		new->lineno   = plpgsql_location_to_lineno(@1);
+		new->stmtid	  = ++plpgsql_curr_compile->nstatements;
 		new->is_stacked = $2;
 		new->diag_items = $4;
 
@@ -1149,6 +1154,7 @@ stmt_if			: K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';'
 		new = palloc0(sizeof(PLpgSQL_stmt_if));
 		new->cmd_type	= PLPGSQL_STMT_IF;
 		new->lineno		= plpgsql_location_to_lineno(@1);
+		new->stmtid		= ++plpgsql_curr_compile->nstatements;
 		new->cond		= $2;
 		new->then_body	= $3;
 		new->elsif_list = $4;
@@ -1253,6 +1259,7 @@ stmt_loop		: opt_loop_label K_LOOP loop_body
 		new = palloc0(sizeof(PLpgSQL_stmt_loop));
 		new->cmd_type = PLPGSQL_STMT_LOOP;
 		new->lineno   = plpgsql_location_to_lineno(@2);
+		new->stmtid   = ++plpgsql_curr_compile->nstatements;
 		new->label	  = $1;
 		new->body	  = $3.stmts;
 
@@ -1270,6 +1277,7 @@ stmt_while		: opt_loop_label K_WHILE expr_until_loop loop_body
 		new = palloc0(sizeof(PLpgSQL_stmt_while));
 		new->cmd_type = PLPGSQL_STMT_WHILE;
 		new->lineno   = plpgsql_location_to_lineno(@2);
+		new->stmtid	  = ++plpgsql_curr_compile->nstatements;
 		new->label	  = $1;
 		new->cond	  = $3;
 		new->body	  = $4.stmts;
@@ -1290,6 +1298,7 @@ stmt_for		: opt_loop_label K_FOR for_control 

Re: proposal - plpgsql unique statement id

2019-01-04 Thread Peter Eisentraut
On 13/11/2018 14:35, Pavel Stehule wrote:
> I am try to enhance plpgsql_check about profiler functionality and I
> have to solve how to identify every plpgsql statement across different
> sessions. There is lineno, but surely it should not be unique. I propose
> introduce stmtid to every statement structure. This number will be
> unique inside function.

That seems reasonable enough, although I wouldn't use 0 as a valid stmtid.

A documenting comment near PLpgSQL_stmt might be nice.

-- 
Peter Eisentraut  http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services



proposal - plpgsql unique statement id

2018-11-13 Thread Pavel Stehule
Hi

I am try to enhance plpgsql_check about profiler functionality and I have
to solve how to identify every plpgsql statement across different sessions.
There is lineno, but surely it should not be unique. I propose introduce
stmtid to every statement structure. This number will be unique inside
function.

Comments, notes?

Regards

Pavel
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 59460d2643..64ecfdbe2d 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -368,6 +368,8 @@ do_compile(FunctionCallInfo fcinfo,
 
 	function->fn_prokind = procStruct->prokind;
 
+	function->nstatements = 0;
+
 	/*
 	 * Initialize the compiler, particularly the namespace stack.  The
 	 * outermost namespace contains function parameters and other special
@@ -911,6 +913,8 @@ plpgsql_compile_inline(char *proc_source)
  true);
 	function->found_varno = var->dno;
 
+	function->nstatements = 0;
+
 	/*
 	 * Now parse the function's text
 	 */
@@ -1020,6 +1024,7 @@ add_dummy_return(PLpgSQL_function *function)
 
 		new = palloc0(sizeof(PLpgSQL_stmt_block));
 		new->cmd_type = PLPGSQL_STMT_BLOCK;
+		new->stmtid = function->nstatements++;
 		new->body = list_make1(function->action);
 
 		function->action = new;
@@ -1031,6 +1036,7 @@ add_dummy_return(PLpgSQL_function *function)
 
 		new = palloc0(sizeof(PLpgSQL_stmt_return));
 		new->cmd_type = PLPGSQL_STMT_RETURN;
+		new->stmtid = function->nstatements++;
 		new->expr = NULL;
 		new->retvarno = function->out_param_varno;
 
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 68e399f9cf..744156db2b 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -415,6 +415,7 @@ pl_block		: decl_sect K_BEGIN proc_sect exception_sect K_END opt_label
 
 		new->cmd_type	= PLPGSQL_STMT_BLOCK;
 		new->lineno		= plpgsql_location_to_lineno(@2);
+		new->stmtid 	= plpgsql_curr_compile->nstatements++;
 		new->label		= $1.label;
 		new->n_initvars = $1.n_initvars;
 		new->initvarnos = $1.initvarnos;
@@ -919,6 +920,7 @@ stmt_call		: K_CALL
 		new = palloc0(sizeof(PLpgSQL_stmt_call));
 		new->cmd_type = PLPGSQL_STMT_CALL;
 		new->lineno = plpgsql_location_to_lineno(@1);
+		new->stmtid 	= plpgsql_curr_compile->nstatements++;
 		new->expr = read_sql_stmt("CALL ");
 		new->is_call = true;
 
@@ -933,6 +935,7 @@ stmt_call		: K_CALL
 		new = palloc0(sizeof(PLpgSQL_stmt_call));
 		new->cmd_type = PLPGSQL_STMT_CALL;
 		new->lineno = plpgsql_location_to_lineno(@1);
+		new->stmtid 	= plpgsql_curr_compile->nstatements++;
 		new->expr = read_sql_stmt("DO ");
 		new->is_call = false;
 
@@ -948,6 +951,7 @@ stmt_assign		: assign_var assign_operator expr_until_semi
 		new = palloc0(sizeof(PLpgSQL_stmt_assign));
 		new->cmd_type = PLPGSQL_STMT_ASSIGN;
 		new->lineno   = plpgsql_location_to_lineno(@1);
+		new->stmtid 	= plpgsql_curr_compile->nstatements++;
 		new->varno = $1->dno;
 		new->expr  = $3;
 
@@ -963,6 +967,7 @@ stmt_getdiag	: K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
 		new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
 		new->cmd_type = PLPGSQL_STMT_GETDIAG;
 		new->lineno   = plpgsql_location_to_lineno(@1);
+		new->stmtid 	= plpgsql_curr_compile->nstatements++;
 		new->is_stacked = $2;
 		new->diag_items = $4;
 
@@ -1154,6 +1159,7 @@ stmt_if			: K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';'
 		new = palloc0(sizeof(PLpgSQL_stmt_if));
 		new->cmd_type	= PLPGSQL_STMT_IF;
 		new->lineno		= plpgsql_location_to_lineno(@1);
+		new->stmtid 	= plpgsql_curr_compile->nstatements++;
 		new->cond		= $2;
 		new->then_body	= $3;
 		new->elsif_list = $4;
@@ -1258,6 +1264,7 @@ stmt_loop		: opt_loop_label K_LOOP loop_body
 		new = palloc0(sizeof(PLpgSQL_stmt_loop));
 		new->cmd_type = PLPGSQL_STMT_LOOP;
 		new->lineno   = plpgsql_location_to_lineno(@2);
+		new->stmtid 	= plpgsql_curr_compile->nstatements++;
 		new->label	  = $1;
 		new->body	  = $3.stmts;
 
@@ -1275,6 +1282,7 @@ stmt_while		: opt_loop_label K_WHILE expr_until_loop loop_body
 		new = palloc0(sizeof(PLpgSQL_stmt_while));
 		new->cmd_type = PLPGSQL_STMT_WHILE;
 		new->lineno   = plpgsql_location_to_lineno(@2);
+		new->stmtid 	= plpgsql_curr_compile->nstatements++;
 		new->label	  = $1;
 		new->cond	  = $3;
 		new->body	  = $4.stmts;
@@ -1295,6 +1303,7 @@ stmt_for		: opt_loop_label K_FOR for_control loop_body
 
 			new = (PLpgSQL_stmt_fori *) $3;
 			new->lineno   = plpgsql_location_to_lineno(@2);
+			new->stmtid 	= plpgsql_curr_compile->nstatements++;
 			new->label	  = $1;
 			new->body	  = $4.stmts;
 			$$ = (PLpgSQL_stmt *) new;
@@ -1309,6 +1318,7 @@ stmt_for		: opt_loop_label K_FOR for_control loop_body
 			/* forq is the common supertype of all three */
 			new = (PLpgSQL_stmt_forq *) $3;