proposal - plpgsql unique statement id
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
Attachments:
plpgsql-statement-id.patchtext/x-patch; charset=US-ASCII; name=plpgsql-statement-id.patchDownload
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;
new->lineno = plpgsql_location_to_lineno(@2);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->label = $1;
new->body = $4.stmts;
$$ = (PLpgSQL_stmt *) new;
@@ -1338,6 +1348,7 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
new->cmd_type = PLPGSQL_STMT_DYNFORS;
+ new->stmtid = plpgsql_curr_compile->nstatements++;
if ($1.row)
{
new->var = (PLpgSQL_variable *) $1.row;
@@ -1383,6 +1394,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->curvar = cursor->dno;
/* Should have had a single variable name */
@@ -1497,6 +1509,7 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_fori));
new->cmd_type = PLPGSQL_STMT_FORI;
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->var = fvar;
new->reverse = reverse;
new->lower = expr1;
@@ -1531,6 +1544,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++;
if ($1.row)
{
new->var = (PLpgSQL_variable *) $1.row;
@@ -1631,6 +1645,7 @@ stmt_foreach_a : opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRA
new = palloc0(sizeof(PLpgSQL_stmt_foreach_a));
new->cmd_type = PLPGSQL_STMT_FOREACH_A;
new->lineno = plpgsql_location_to_lineno(@2);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->label = $1;
new->slice = $4;
new->expr = $7;
@@ -1677,6 +1692,7 @@ stmt_exit : exit_type opt_label opt_exitcond
new = palloc0(sizeof(PLpgSQL_stmt_exit));
new->cmd_type = PLPGSQL_STMT_EXIT;
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->is_exit = $1;
new->lineno = plpgsql_location_to_lineno(@1);
new->label = $2;
@@ -1768,6 +1784,7 @@ stmt_raise : K_RAISE
new->cmd_type = PLPGSQL_STMT_RAISE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->elog_level = ERROR; /* default */
new->condname = NULL;
new->message = NULL;
@@ -1912,6 +1929,7 @@ stmt_assert : K_ASSERT
new->cmd_type = PLPGSQL_STMT_ASSERT;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->cond = read_sql_expression2(',', ';',
", or ;",
@@ -1989,6 +2007,7 @@ stmt_dynexecute : K_EXECUTE
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->query = expr;
new->into = false;
new->strict = false;
@@ -2045,6 +2064,7 @@ stmt_open : K_OPEN cursor_variable
new = palloc0(sizeof(PLpgSQL_stmt_open));
new->cmd_type = PLPGSQL_STMT_OPEN;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->curvar = $2->dno;
new->cursor_options = CURSOR_OPT_FAST_PLAN;
@@ -2169,6 +2189,7 @@ stmt_close : K_CLOSE cursor_variable ';'
new = palloc(sizeof(PLpgSQL_stmt_close));
new->cmd_type = PLPGSQL_STMT_CLOSE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->curvar = $2->dno;
$$ = (PLpgSQL_stmt *)new;
@@ -2189,6 +2210,7 @@ stmt_commit : K_COMMIT ';'
new = palloc(sizeof(PLpgSQL_stmt_commit));
new->cmd_type = PLPGSQL_STMT_COMMIT;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
$$ = (PLpgSQL_stmt *)new;
}
@@ -2201,6 +2223,7 @@ stmt_rollback : K_ROLLBACK ';'
new = palloc(sizeof(PLpgSQL_stmt_rollback));
new->cmd_type = PLPGSQL_STMT_ROLLBACK;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
$$ = (PLpgSQL_stmt *)new;
}
@@ -2213,6 +2236,8 @@ stmt_set : K_SET
new = palloc0(sizeof(PLpgSQL_stmt_set));
new->cmd_type = PLPGSQL_STMT_SET;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
+
new->expr = read_sql_stmt("SET ");
$$ = (PLpgSQL_stmt *)new;
@@ -2224,6 +2249,7 @@ stmt_set : K_SET
new = palloc0(sizeof(PLpgSQL_stmt_set));
new->cmd_type = PLPGSQL_STMT_SET;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->expr = read_sql_stmt("RESET ");
$$ = (PLpgSQL_stmt *)new;
@@ -3006,6 +3032,7 @@ make_execsql_stmt(int firsttoken, int location)
execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
execsql->lineno = plpgsql_location_to_lineno(location);
+ execsql->stmtid = plpgsql_curr_compile->nstatements++;
execsql->sqlstmt = expr;
execsql->into = have_into;
execsql->strict = have_strict;
@@ -3031,6 +3058,7 @@ read_fetch_direction(void)
*/
fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch));
fetch->cmd_type = PLPGSQL_STMT_FETCH;
+ fetch->stmtid = plpgsql_curr_compile->nstatements++;
/* set direction defaults: */
fetch->direction = FETCH_FORWARD;
fetch->how_many = 1;
@@ -3183,6 +3211,7 @@ make_return_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return));
new->cmd_type = PLPGSQL_STMT_RETURN;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->expr = NULL;
new->retvarno = -1;
@@ -3270,6 +3299,7 @@ make_return_next_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return_next));
new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->expr = NULL;
new->retvarno = -1;
@@ -3332,6 +3362,7 @@ make_return_query_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return_query));
new->cmd_type = PLPGSQL_STMT_RETURN_QUERY;
+ new->stmtid = plpgsql_curr_compile->nstatements++;
new->lineno = plpgsql_location_to_lineno(location);
/* check for RETURN QUERY EXECUTE */
@@ -4003,6 +4034,7 @@ make_case(int location, PLpgSQL_expr *t_expr,
new = palloc(sizeof(PLpgSQL_stmt_case));
new->cmd_type = PLPGSQL_STMT_CASE;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = plpgsql_curr_compile->nstatements++;
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 f6c35a5049..c6bf270594 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -448,6 +448,7 @@ typedef struct PLpgSQL_stmt
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
} PLpgSQL_stmt;
/*
@@ -487,6 +488,7 @@ typedef struct PLpgSQL_stmt_block
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
List *body; /* List of statements */
int n_initvars; /* Length of initvarnos[] */
@@ -501,6 +503,7 @@ typedef struct PLpgSQL_stmt_assign
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
int varno;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_assign;
@@ -512,6 +515,7 @@ typedef struct PLpgSQL_stmt_perform
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_perform;
@@ -522,6 +526,7 @@ typedef struct PLpgSQL_stmt_call
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
bool is_call;
PLpgSQL_variable *target;
@@ -534,6 +539,7 @@ typedef struct PLpgSQL_stmt_commit
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
} PLpgSQL_stmt_commit;
/*
@@ -543,6 +549,7 @@ typedef struct PLpgSQL_stmt_rollback
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
} PLpgSQL_stmt_rollback;
/*
@@ -552,6 +559,7 @@ typedef struct PLpgSQL_stmt_set
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_set;
@@ -571,6 +579,7 @@ typedef struct PLpgSQL_stmt_getdiag
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
bool is_stacked; /* STACKED or CURRENT diagnostics area? */
List *diag_items; /* List of PLpgSQL_diag_item */
} PLpgSQL_stmt_getdiag;
@@ -582,6 +591,7 @@ typedef struct PLpgSQL_stmt_if
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *cond; /* boolean expression for THEN */
List *then_body; /* List of statements */
List *elsif_list; /* List of PLpgSQL_if_elsif structs */
@@ -605,6 +615,7 @@ typedef struct PLpgSQL_stmt_case
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
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 */
@@ -628,6 +639,7 @@ typedef struct PLpgSQL_case_when
typedef struct PLpgSQL_stmt_loop
{
PLpgSQL_stmt_type cmd_type;
+ int stmtid;
int lineno;
char *label;
List *body; /* List of statements */
@@ -640,6 +652,7 @@ typedef struct PLpgSQL_stmt_while
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_expr *cond;
List *body; /* List of statements */
@@ -652,6 +665,7 @@ typedef struct PLpgSQL_stmt_fori
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_var *var;
PLpgSQL_expr *lower;
@@ -670,6 +684,7 @@ typedef struct PLpgSQL_stmt_forq
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -682,6 +697,7 @@ typedef struct PLpgSQL_stmt_fors
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -696,6 +712,7 @@ typedef struct PLpgSQL_stmt_forc
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -711,6 +728,7 @@ typedef struct PLpgSQL_stmt_dynfors
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -726,6 +744,7 @@ typedef struct PLpgSQL_stmt_foreach_a
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
int varno; /* loop target variable */
int slice; /* slice dimension, or 0 */
@@ -740,6 +759,7 @@ typedef struct PLpgSQL_stmt_open
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
int curvar;
int cursor_options;
PLpgSQL_expr *argquery;
@@ -755,6 +775,7 @@ typedef struct PLpgSQL_stmt_fetch
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_variable *target; /* target (record or row) */
int curvar; /* cursor variable to fetch from */
FetchDirection direction; /* fetch direction */
@@ -771,6 +792,7 @@ typedef struct PLpgSQL_stmt_close
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
int curvar;
} PLpgSQL_stmt_close;
@@ -781,6 +803,7 @@ typedef struct PLpgSQL_stmt_exit
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
bool is_exit; /* Is this an exit or a continue? */
char *label; /* NULL if it's an unlabelled EXIT/CONTINUE */
PLpgSQL_expr *cond;
@@ -793,6 +816,7 @@ typedef struct PLpgSQL_stmt_return
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
int retvarno;
} PLpgSQL_stmt_return;
@@ -804,6 +828,7 @@ typedef struct PLpgSQL_stmt_return_next
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
int retvarno;
} PLpgSQL_stmt_return_next;
@@ -815,6 +840,7 @@ typedef struct PLpgSQL_stmt_return_query
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *query; /* if static query */
PLpgSQL_expr *dynquery; /* if dynamic query (RETURN QUERY EXECUTE) */
List *params; /* USING arguments for dynamic query */
@@ -827,6 +853,7 @@ typedef struct PLpgSQL_stmt_raise
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
int elog_level;
char *condname; /* condition name, SQLSTATE, or NULL */
char *message; /* old-style message format literal, or NULL */
@@ -850,6 +877,7 @@ typedef struct PLpgSQL_stmt_assert
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *cond;
PLpgSQL_expr *message;
} PLpgSQL_stmt_assert;
@@ -861,6 +889,7 @@ typedef struct PLpgSQL_stmt_execsql
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *sqlstmt;
bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? Note:
* mod_stmt is set when we plan the query */
@@ -876,6 +905,7 @@ typedef struct PLpgSQL_stmt_dynexecute
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *query; /* string expression */
bool into; /* INTO supplied? */
bool strict; /* INTO STRICT flag */
@@ -972,6 +1002,9 @@ typedef struct PLpgSQL_function
/* function body parsetree */
PLpgSQL_stmt_block *action;
+ /* number of statements inside functions */
+ int nstatements;
+
/* these fields change when the function is used */
struct PLpgSQL_execstate *cur_estate;
unsigned long use_count;
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
pá 4. 1. 2019 v 13:58 odesílatel Peter Eisentraut <
peter.eisentraut@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
Show quoted text
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
plpgsql-statement-id-02.patchtext/x-patch; charset=US-ASCII; name=plpgsql-statement-id-02.patchDownload
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 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;
@@ -1304,6 +1313,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;
new->lineno = plpgsql_location_to_lineno(@2);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->label = $1;
new->body = $4.stmts;
$$ = (PLpgSQL_stmt *) new;
@@ -1333,6 +1343,7 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
new->cmd_type = PLPGSQL_STMT_DYNFORS;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
if ($1.row)
{
new->var = (PLpgSQL_variable *) $1.row;
@@ -1378,6 +1389,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->curvar = cursor->dno;
/* Should have had a single variable name */
@@ -1492,6 +1504,7 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_fori));
new->cmd_type = PLPGSQL_STMT_FORI;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->var = fvar;
new->reverse = reverse;
new->lower = expr1;
@@ -1526,6 +1539,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;
if ($1.row)
{
new->var = (PLpgSQL_variable *) $1.row;
@@ -1626,6 +1640,7 @@ stmt_foreach_a : opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRA
new = palloc0(sizeof(PLpgSQL_stmt_foreach_a));
new->cmd_type = PLPGSQL_STMT_FOREACH_A;
new->lineno = plpgsql_location_to_lineno(@2);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->label = $1;
new->slice = $4;
new->expr = $7;
@@ -1672,6 +1687,7 @@ stmt_exit : exit_type opt_label opt_exitcond
new = palloc0(sizeof(PLpgSQL_stmt_exit));
new->cmd_type = PLPGSQL_STMT_EXIT;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->is_exit = $1;
new->lineno = plpgsql_location_to_lineno(@1);
new->label = $2;
@@ -1763,6 +1779,7 @@ stmt_raise : K_RAISE
new->cmd_type = PLPGSQL_STMT_RAISE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->elog_level = ERROR; /* default */
new->condname = NULL;
new->message = NULL;
@@ -1907,6 +1924,7 @@ stmt_assert : K_ASSERT
new->cmd_type = PLPGSQL_STMT_ASSERT;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->cond = read_sql_expression2(',', ';',
", or ;",
@@ -1984,6 +2002,7 @@ stmt_dynexecute : K_EXECUTE
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->query = expr;
new->into = false;
new->strict = false;
@@ -2040,6 +2059,7 @@ stmt_open : K_OPEN cursor_variable
new = palloc0(sizeof(PLpgSQL_stmt_open));
new->cmd_type = PLPGSQL_STMT_OPEN;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->curvar = $2->dno;
new->cursor_options = CURSOR_OPT_FAST_PLAN;
@@ -2164,6 +2184,7 @@ stmt_close : K_CLOSE cursor_variable ';'
new = palloc(sizeof(PLpgSQL_stmt_close));
new->cmd_type = PLPGSQL_STMT_CLOSE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->curvar = $2->dno;
$$ = (PLpgSQL_stmt *)new;
@@ -2184,6 +2205,7 @@ stmt_commit : K_COMMIT ';'
new = palloc(sizeof(PLpgSQL_stmt_commit));
new->cmd_type = PLPGSQL_STMT_COMMIT;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
$$ = (PLpgSQL_stmt *)new;
}
@@ -2196,6 +2218,7 @@ stmt_rollback : K_ROLLBACK ';'
new = palloc(sizeof(PLpgSQL_stmt_rollback));
new->cmd_type = PLPGSQL_STMT_ROLLBACK;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
$$ = (PLpgSQL_stmt *)new;
}
@@ -2208,6 +2231,8 @@ stmt_set : K_SET
new = palloc0(sizeof(PLpgSQL_stmt_set));
new->cmd_type = PLPGSQL_STMT_SET;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
+
new->expr = read_sql_stmt("SET ");
$$ = (PLpgSQL_stmt *)new;
@@ -2219,6 +2244,7 @@ stmt_set : K_SET
new = palloc0(sizeof(PLpgSQL_stmt_set));
new->cmd_type = PLPGSQL_STMT_SET;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->expr = read_sql_stmt("RESET ");
$$ = (PLpgSQL_stmt *)new;
@@ -3000,6 +3026,7 @@ make_execsql_stmt(int firsttoken, int location)
execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
execsql->lineno = plpgsql_location_to_lineno(location);
+ execsql->stmtid = ++plpgsql_curr_compile->nstatements;
execsql->sqlstmt = expr;
execsql->into = have_into;
execsql->strict = have_strict;
@@ -3025,6 +3052,7 @@ read_fetch_direction(void)
*/
fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch));
fetch->cmd_type = PLPGSQL_STMT_FETCH;
+ fetch->stmtid = ++plpgsql_curr_compile->nstatements;
/* set direction defaults: */
fetch->direction = FETCH_FORWARD;
fetch->how_many = 1;
@@ -3177,6 +3205,7 @@ make_return_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return));
new->cmd_type = PLPGSQL_STMT_RETURN;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->expr = NULL;
new->retvarno = -1;
@@ -3264,6 +3293,7 @@ make_return_next_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return_next));
new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->expr = NULL;
new->retvarno = -1;
@@ -3326,6 +3356,7 @@ make_return_query_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return_query));
new->cmd_type = PLPGSQL_STMT_RETURN_QUERY;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->lineno = plpgsql_location_to_lineno(location);
/* check for RETURN QUERY EXECUTE */
@@ -3997,6 +4028,7 @@ make_case(int location, PLpgSQL_expr *t_expr,
new = palloc(sizeof(PLpgSQL_stmt_case));
new->cmd_type = PLPGSQL_STMT_CASE;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
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 2dca49334a..f60b33b344 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -447,6 +447,12 @@ typedef struct PLpgSQL_stmt
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+
+ /*
+ * A profilers needs to hold metrics per statement. Integer
+ * statement identifier can be used as index to array of metrics.
+ */
+ int stmtid;
} PLpgSQL_stmt;
/*
@@ -486,6 +492,7 @@ typedef struct PLpgSQL_stmt_block
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
List *body; /* List of statements */
int n_initvars; /* Length of initvarnos[] */
@@ -500,6 +507,7 @@ typedef struct PLpgSQL_stmt_assign
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
int varno;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_assign;
@@ -511,6 +519,7 @@ typedef struct PLpgSQL_stmt_perform
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_perform;
@@ -521,6 +530,7 @@ typedef struct PLpgSQL_stmt_call
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
bool is_call;
PLpgSQL_variable *target;
@@ -533,6 +543,7 @@ typedef struct PLpgSQL_stmt_commit
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
} PLpgSQL_stmt_commit;
/*
@@ -542,6 +553,7 @@ typedef struct PLpgSQL_stmt_rollback
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
} PLpgSQL_stmt_rollback;
/*
@@ -551,6 +563,7 @@ typedef struct PLpgSQL_stmt_set
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_set;
@@ -570,6 +583,7 @@ typedef struct PLpgSQL_stmt_getdiag
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
bool is_stacked; /* STACKED or CURRENT diagnostics area? */
List *diag_items; /* List of PLpgSQL_diag_item */
} PLpgSQL_stmt_getdiag;
@@ -581,6 +595,7 @@ typedef struct PLpgSQL_stmt_if
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *cond; /* boolean expression for THEN */
List *then_body; /* List of statements */
List *elsif_list; /* List of PLpgSQL_if_elsif structs */
@@ -604,6 +619,7 @@ typedef struct PLpgSQL_stmt_case
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
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 */
@@ -627,6 +643,7 @@ typedef struct PLpgSQL_case_when
typedef struct PLpgSQL_stmt_loop
{
PLpgSQL_stmt_type cmd_type;
+ int stmtid;
int lineno;
char *label;
List *body; /* List of statements */
@@ -639,6 +656,7 @@ typedef struct PLpgSQL_stmt_while
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_expr *cond;
List *body; /* List of statements */
@@ -651,6 +669,7 @@ typedef struct PLpgSQL_stmt_fori
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_var *var;
PLpgSQL_expr *lower;
@@ -669,6 +688,7 @@ typedef struct PLpgSQL_stmt_forq
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -681,6 +701,7 @@ typedef struct PLpgSQL_stmt_fors
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -695,6 +716,7 @@ typedef struct PLpgSQL_stmt_forc
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -710,6 +732,7 @@ typedef struct PLpgSQL_stmt_dynfors
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -725,6 +748,7 @@ typedef struct PLpgSQL_stmt_foreach_a
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
char *label;
int varno; /* loop target variable */
int slice; /* slice dimension, or 0 */
@@ -739,6 +763,7 @@ typedef struct PLpgSQL_stmt_open
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
int curvar;
int cursor_options;
PLpgSQL_expr *argquery;
@@ -754,6 +779,7 @@ typedef struct PLpgSQL_stmt_fetch
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_variable *target; /* target (record or row) */
int curvar; /* cursor variable to fetch from */
FetchDirection direction; /* fetch direction */
@@ -770,6 +796,7 @@ typedef struct PLpgSQL_stmt_close
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
int curvar;
} PLpgSQL_stmt_close;
@@ -780,6 +807,7 @@ typedef struct PLpgSQL_stmt_exit
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
bool is_exit; /* Is this an exit or a continue? */
char *label; /* NULL if it's an unlabelled EXIT/CONTINUE */
PLpgSQL_expr *cond;
@@ -792,6 +820,7 @@ typedef struct PLpgSQL_stmt_return
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
int retvarno;
} PLpgSQL_stmt_return;
@@ -803,6 +832,7 @@ typedef struct PLpgSQL_stmt_return_next
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *expr;
int retvarno;
} PLpgSQL_stmt_return_next;
@@ -814,6 +844,7 @@ typedef struct PLpgSQL_stmt_return_query
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *query; /* if static query */
PLpgSQL_expr *dynquery; /* if dynamic query (RETURN QUERY EXECUTE) */
List *params; /* USING arguments for dynamic query */
@@ -826,6 +857,7 @@ typedef struct PLpgSQL_stmt_raise
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
int elog_level;
char *condname; /* condition name, SQLSTATE, or NULL */
char *message; /* old-style message format literal, or NULL */
@@ -849,6 +881,7 @@ typedef struct PLpgSQL_stmt_assert
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *cond;
PLpgSQL_expr *message;
} PLpgSQL_stmt_assert;
@@ -860,6 +893,7 @@ typedef struct PLpgSQL_stmt_execsql
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *sqlstmt;
bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? Note:
* mod_stmt is set when we plan the query */
@@ -875,6 +909,7 @@ typedef struct PLpgSQL_stmt_dynexecute
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ int stmtid;
PLpgSQL_expr *query; /* string expression */
bool into; /* INTO supplied? */
bool strict; /* INTO STRICT flag */
@@ -971,6 +1006,9 @@ typedef struct PLpgSQL_function
/* function body parsetree */
PLpgSQL_stmt_block *action;
+ /* number of statements inside functions */
+ int nstatements;
+
/* these fields change when the function is used */
struct PLpgSQL_execstate *cur_estate;
unsigned long use_count;
On 04/01/2019 15:07, Pavel Stehule wrote:
pá 4. 1. 2019 v 13:58 odesílatel Peter Eisentraut
<peter.eisentraut@2ndquadrant.com
<mailto:peter.eisentraut@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. Ipropose
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
pá 18. 1. 2019 v 8:56 odesílatel Peter Eisentraut <
peter.eisentraut@2ndquadrant.com> napsal:
On 04/01/2019 15:07, Pavel Stehule wrote:
pá 4. 1. 2019 v 13:58 odesílatel Peter Eisentraut
<peter.eisentraut@2ndquadrant.com
<mailto:peter.eisentraut@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
Related, should stmtid be unsigned int rather than signed int?
done
Regards
Pavel
Show quoted text
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
plpgsql-statement-id-03.patchtext/x-patch; charset=US-ASCII; name=plpgsql-statement-id-03.patchDownload
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 = 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 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;
@@ -1304,6 +1313,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;
new->lineno = plpgsql_location_to_lineno(@2);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->label = $1;
new->body = $4.stmts;
$$ = (PLpgSQL_stmt *) new;
@@ -1333,6 +1343,7 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
new->cmd_type = PLPGSQL_STMT_DYNFORS;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
if ($1.row)
{
new->var = (PLpgSQL_variable *) $1.row;
@@ -1378,6 +1389,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->curvar = cursor->dno;
/* Should have had a single variable name */
@@ -1492,6 +1504,7 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_fori));
new->cmd_type = PLPGSQL_STMT_FORI;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->var = fvar;
new->reverse = reverse;
new->lower = expr1;
@@ -1526,6 +1539,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;
if ($1.row)
{
new->var = (PLpgSQL_variable *) $1.row;
@@ -1626,6 +1640,7 @@ stmt_foreach_a : opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRA
new = palloc0(sizeof(PLpgSQL_stmt_foreach_a));
new->cmd_type = PLPGSQL_STMT_FOREACH_A;
new->lineno = plpgsql_location_to_lineno(@2);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->label = $1;
new->slice = $4;
new->expr = $7;
@@ -1672,6 +1687,7 @@ stmt_exit : exit_type opt_label opt_exitcond
new = palloc0(sizeof(PLpgSQL_stmt_exit));
new->cmd_type = PLPGSQL_STMT_EXIT;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->is_exit = $1;
new->lineno = plpgsql_location_to_lineno(@1);
new->label = $2;
@@ -1763,6 +1779,7 @@ stmt_raise : K_RAISE
new->cmd_type = PLPGSQL_STMT_RAISE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->elog_level = ERROR; /* default */
new->condname = NULL;
new->message = NULL;
@@ -1907,6 +1924,7 @@ stmt_assert : K_ASSERT
new->cmd_type = PLPGSQL_STMT_ASSERT;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->cond = read_sql_expression2(',', ';',
", or ;",
@@ -1984,6 +2002,7 @@ stmt_dynexecute : K_EXECUTE
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->query = expr;
new->into = false;
new->strict = false;
@@ -2040,6 +2059,7 @@ stmt_open : K_OPEN cursor_variable
new = palloc0(sizeof(PLpgSQL_stmt_open));
new->cmd_type = PLPGSQL_STMT_OPEN;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->curvar = $2->dno;
new->cursor_options = CURSOR_OPT_FAST_PLAN;
@@ -2164,6 +2184,7 @@ stmt_close : K_CLOSE cursor_variable ';'
new = palloc(sizeof(PLpgSQL_stmt_close));
new->cmd_type = PLPGSQL_STMT_CLOSE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->curvar = $2->dno;
$$ = (PLpgSQL_stmt *)new;
@@ -2184,6 +2205,7 @@ stmt_commit : K_COMMIT ';'
new = palloc(sizeof(PLpgSQL_stmt_commit));
new->cmd_type = PLPGSQL_STMT_COMMIT;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
$$ = (PLpgSQL_stmt *)new;
}
@@ -2196,6 +2218,7 @@ stmt_rollback : K_ROLLBACK ';'
new = palloc(sizeof(PLpgSQL_stmt_rollback));
new->cmd_type = PLPGSQL_STMT_ROLLBACK;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
$$ = (PLpgSQL_stmt *)new;
}
@@ -2208,6 +2231,8 @@ stmt_set : K_SET
new = palloc0(sizeof(PLpgSQL_stmt_set));
new->cmd_type = PLPGSQL_STMT_SET;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
+
new->expr = read_sql_stmt("SET ");
$$ = (PLpgSQL_stmt *)new;
@@ -2219,6 +2244,7 @@ stmt_set : K_SET
new = palloc0(sizeof(PLpgSQL_stmt_set));
new->cmd_type = PLPGSQL_STMT_SET;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->expr = read_sql_stmt("RESET ");
$$ = (PLpgSQL_stmt *)new;
@@ -3000,6 +3026,7 @@ make_execsql_stmt(int firsttoken, int location)
execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
execsql->lineno = plpgsql_location_to_lineno(location);
+ execsql->stmtid = ++plpgsql_curr_compile->nstatements;
execsql->sqlstmt = expr;
execsql->into = have_into;
execsql->strict = have_strict;
@@ -3025,6 +3052,7 @@ read_fetch_direction(void)
*/
fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch));
fetch->cmd_type = PLPGSQL_STMT_FETCH;
+ fetch->stmtid = ++plpgsql_curr_compile->nstatements;
/* set direction defaults: */
fetch->direction = FETCH_FORWARD;
fetch->how_many = 1;
@@ -3177,6 +3205,7 @@ make_return_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return));
new->cmd_type = PLPGSQL_STMT_RETURN;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->expr = NULL;
new->retvarno = -1;
@@ -3264,6 +3293,7 @@ make_return_next_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return_next));
new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->expr = NULL;
new->retvarno = -1;
@@ -3326,6 +3356,7 @@ make_return_query_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return_query));
new->cmd_type = PLPGSQL_STMT_RETURN_QUERY;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->lineno = plpgsql_location_to_lineno(location);
/* check for RETURN QUERY EXECUTE */
@@ -3997,6 +4028,7 @@ make_case(int location, PLpgSQL_expr *t_expr,
new = palloc(sizeof(PLpgSQL_stmt_case));
new->cmd_type = PLPGSQL_STMT_CASE;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
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 a7118b8386..f0c09e4f4f 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -447,6 +447,12 @@ typedef struct PLpgSQL_stmt
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+
+ /*
+ * A profilers needs to hold metrics per statement. Integer
+ * statement identifier can be used as index to array of metrics.
+ */
+ unsigned int stmtid;
} PLpgSQL_stmt;
/*
@@ -486,6 +492,7 @@ typedef struct PLpgSQL_stmt_block
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
List *body; /* List of statements */
int n_initvars; /* Length of initvarnos[] */
@@ -500,6 +507,7 @@ typedef struct PLpgSQL_stmt_assign
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
int varno;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_assign;
@@ -511,6 +519,7 @@ typedef struct PLpgSQL_stmt_perform
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_perform;
@@ -521,6 +530,7 @@ typedef struct PLpgSQL_stmt_call
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
bool is_call;
PLpgSQL_variable *target;
@@ -533,6 +543,7 @@ typedef struct PLpgSQL_stmt_commit
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
} PLpgSQL_stmt_commit;
/*
@@ -542,6 +553,7 @@ typedef struct PLpgSQL_stmt_rollback
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
} PLpgSQL_stmt_rollback;
/*
@@ -551,6 +563,7 @@ typedef struct PLpgSQL_stmt_set
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_set;
@@ -570,6 +583,7 @@ typedef struct PLpgSQL_stmt_getdiag
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
bool is_stacked; /* STACKED or CURRENT diagnostics area? */
List *diag_items; /* List of PLpgSQL_diag_item */
} PLpgSQL_stmt_getdiag;
@@ -581,6 +595,7 @@ typedef struct PLpgSQL_stmt_if
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *cond; /* boolean expression for THEN */
List *then_body; /* List of statements */
List *elsif_list; /* List of PLpgSQL_if_elsif structs */
@@ -604,6 +619,7 @@ typedef struct PLpgSQL_stmt_case
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
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 */
@@ -628,6 +644,7 @@ typedef struct PLpgSQL_stmt_loop
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
List *body; /* List of statements */
} PLpgSQL_stmt_loop;
@@ -639,6 +656,7 @@ typedef struct PLpgSQL_stmt_while
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_expr *cond;
List *body; /* List of statements */
@@ -651,6 +669,7 @@ typedef struct PLpgSQL_stmt_fori
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_var *var;
PLpgSQL_expr *lower;
@@ -669,6 +688,7 @@ typedef struct PLpgSQL_stmt_forq
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -681,6 +701,7 @@ typedef struct PLpgSQL_stmt_fors
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -695,6 +716,7 @@ typedef struct PLpgSQL_stmt_forc
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -710,6 +732,7 @@ typedef struct PLpgSQL_stmt_dynfors
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -725,6 +748,7 @@ typedef struct PLpgSQL_stmt_foreach_a
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
int varno; /* loop target variable */
int slice; /* slice dimension, or 0 */
@@ -739,6 +763,7 @@ typedef struct PLpgSQL_stmt_open
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
int curvar;
int cursor_options;
PLpgSQL_expr *argquery;
@@ -754,6 +779,7 @@ typedef struct PLpgSQL_stmt_fetch
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_variable *target; /* target (record or row) */
int curvar; /* cursor variable to fetch from */
FetchDirection direction; /* fetch direction */
@@ -770,6 +796,7 @@ typedef struct PLpgSQL_stmt_close
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
int curvar;
} PLpgSQL_stmt_close;
@@ -780,6 +807,7 @@ typedef struct PLpgSQL_stmt_exit
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
bool is_exit; /* Is this an exit or a continue? */
char *label; /* NULL if it's an unlabelled EXIT/CONTINUE */
PLpgSQL_expr *cond;
@@ -792,6 +820,7 @@ typedef struct PLpgSQL_stmt_return
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
int retvarno;
} PLpgSQL_stmt_return;
@@ -803,6 +832,7 @@ typedef struct PLpgSQL_stmt_return_next
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
int retvarno;
} PLpgSQL_stmt_return_next;
@@ -814,6 +844,7 @@ typedef struct PLpgSQL_stmt_return_query
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *query; /* if static query */
PLpgSQL_expr *dynquery; /* if dynamic query (RETURN QUERY EXECUTE) */
List *params; /* USING arguments for dynamic query */
@@ -826,6 +857,7 @@ typedef struct PLpgSQL_stmt_raise
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
int elog_level;
char *condname; /* condition name, SQLSTATE, or NULL */
char *message; /* old-style message format literal, or NULL */
@@ -849,6 +881,7 @@ typedef struct PLpgSQL_stmt_assert
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *cond;
PLpgSQL_expr *message;
} PLpgSQL_stmt_assert;
@@ -860,6 +893,7 @@ typedef struct PLpgSQL_stmt_execsql
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *sqlstmt;
bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? Note:
* mod_stmt is set when we plan the query */
@@ -875,6 +909,7 @@ typedef struct PLpgSQL_stmt_dynexecute
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *query; /* string expression */
bool into; /* INTO supplied? */
bool strict; /* INTO STRICT flag */
@@ -971,6 +1006,9 @@ typedef struct PLpgSQL_function
/* function body parsetree */
PLpgSQL_stmt_block *action;
+ /* number of statements inside functions */
+ unsigned int nstatements;
+
/* these fields change when the function is used */
struct PLpgSQL_execstate *cur_estate;
unsigned long use_count;
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
út 22. 1. 2019 v 14:55 odesílatel Peter Eisentraut <
peter.eisentraut@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
Show quoted text
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
plpgsql-statement-id-04.patchtext/x-patch; charset=US-ASCII; name=plpgsql-statement-id-04.patchDownload
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 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 +1299,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;
@@ -1304,6 +1314,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;
new->lineno = plpgsql_location_to_lineno(@2);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->label = $1;
new->body = $4.stmts;
$$ = (PLpgSQL_stmt *) new;
@@ -1333,6 +1344,7 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
new->cmd_type = PLPGSQL_STMT_DYNFORS;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
if ($1.row)
{
new->var = (PLpgSQL_variable *) $1.row;
@@ -1378,6 +1390,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->curvar = cursor->dno;
/* Should have had a single variable name */
@@ -1492,6 +1505,7 @@ for_control : for_variable K_IN
new = palloc0(sizeof(PLpgSQL_stmt_fori));
new->cmd_type = PLPGSQL_STMT_FORI;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->var = fvar;
new->reverse = reverse;
new->lower = expr1;
@@ -1526,6 +1540,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;
if ($1.row)
{
new->var = (PLpgSQL_variable *) $1.row;
@@ -1626,6 +1641,7 @@ stmt_foreach_a : opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRA
new = palloc0(sizeof(PLpgSQL_stmt_foreach_a));
new->cmd_type = PLPGSQL_STMT_FOREACH_A;
new->lineno = plpgsql_location_to_lineno(@2);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->label = $1;
new->slice = $4;
new->expr = $7;
@@ -1672,6 +1688,7 @@ stmt_exit : exit_type opt_label opt_exitcond
new = palloc0(sizeof(PLpgSQL_stmt_exit));
new->cmd_type = PLPGSQL_STMT_EXIT;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->is_exit = $1;
new->lineno = plpgsql_location_to_lineno(@1);
new->label = $2;
@@ -1763,6 +1780,7 @@ stmt_raise : K_RAISE
new->cmd_type = PLPGSQL_STMT_RAISE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->elog_level = ERROR; /* default */
new->condname = NULL;
new->message = NULL;
@@ -1907,6 +1925,7 @@ stmt_assert : K_ASSERT
new->cmd_type = PLPGSQL_STMT_ASSERT;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->cond = read_sql_expression2(',', ';',
", or ;",
@@ -1984,6 +2003,7 @@ stmt_dynexecute : K_EXECUTE
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->query = expr;
new->into = false;
new->strict = false;
@@ -2040,6 +2060,7 @@ stmt_open : K_OPEN cursor_variable
new = palloc0(sizeof(PLpgSQL_stmt_open));
new->cmd_type = PLPGSQL_STMT_OPEN;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->curvar = $2->dno;
new->cursor_options = CURSOR_OPT_FAST_PLAN;
@@ -2164,6 +2185,7 @@ stmt_close : K_CLOSE cursor_variable ';'
new = palloc(sizeof(PLpgSQL_stmt_close));
new->cmd_type = PLPGSQL_STMT_CLOSE;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->curvar = $2->dno;
$$ = (PLpgSQL_stmt *)new;
@@ -2184,6 +2206,7 @@ stmt_commit : K_COMMIT ';'
new = palloc(sizeof(PLpgSQL_stmt_commit));
new->cmd_type = PLPGSQL_STMT_COMMIT;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
$$ = (PLpgSQL_stmt *)new;
}
@@ -2196,6 +2219,7 @@ stmt_rollback : K_ROLLBACK ';'
new = palloc(sizeof(PLpgSQL_stmt_rollback));
new->cmd_type = PLPGSQL_STMT_ROLLBACK;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
$$ = (PLpgSQL_stmt *)new;
}
@@ -2208,6 +2232,8 @@ stmt_set : K_SET
new = palloc0(sizeof(PLpgSQL_stmt_set));
new->cmd_type = PLPGSQL_STMT_SET;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
+
new->expr = read_sql_stmt("SET ");
$$ = (PLpgSQL_stmt *)new;
@@ -2219,6 +2245,7 @@ stmt_set : K_SET
new = palloc0(sizeof(PLpgSQL_stmt_set));
new->cmd_type = PLPGSQL_STMT_SET;
new->lineno = plpgsql_location_to_lineno(@1);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->expr = read_sql_stmt("RESET ");
$$ = (PLpgSQL_stmt *)new;
@@ -3000,6 +3027,7 @@ make_execsql_stmt(int firsttoken, int location)
execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
execsql->lineno = plpgsql_location_to_lineno(location);
+ execsql->stmtid = ++plpgsql_curr_compile->nstatements;
execsql->sqlstmt = expr;
execsql->into = have_into;
execsql->strict = have_strict;
@@ -3025,6 +3053,7 @@ read_fetch_direction(void)
*/
fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch));
fetch->cmd_type = PLPGSQL_STMT_FETCH;
+ fetch->stmtid = ++plpgsql_curr_compile->nstatements;
/* set direction defaults: */
fetch->direction = FETCH_FORWARD;
fetch->how_many = 1;
@@ -3177,6 +3206,7 @@ make_return_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return));
new->cmd_type = PLPGSQL_STMT_RETURN;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->expr = NULL;
new->retvarno = -1;
@@ -3264,6 +3294,7 @@ make_return_next_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return_next));
new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->expr = NULL;
new->retvarno = -1;
@@ -3326,6 +3357,7 @@ make_return_query_stmt(int location)
new = palloc0(sizeof(PLpgSQL_stmt_return_query));
new->cmd_type = PLPGSQL_STMT_RETURN_QUERY;
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
new->lineno = plpgsql_location_to_lineno(location);
/* check for RETURN QUERY EXECUTE */
@@ -3997,6 +4029,7 @@ make_case(int location, PLpgSQL_expr *t_expr,
new = palloc(sizeof(PLpgSQL_stmt_case));
new->cmd_type = PLPGSQL_STMT_CASE;
new->lineno = plpgsql_location_to_lineno(location);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
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 a7118b8386..f0c09e4f4f 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -447,6 +447,12 @@ typedef struct PLpgSQL_stmt
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+
+ /*
+ * A profilers needs to hold metrics per statement. Integer
+ * statement identifier can be used as index to array of metrics.
+ */
+ unsigned int stmtid;
} PLpgSQL_stmt;
/*
@@ -486,6 +492,7 @@ typedef struct PLpgSQL_stmt_block
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
List *body; /* List of statements */
int n_initvars; /* Length of initvarnos[] */
@@ -500,6 +507,7 @@ typedef struct PLpgSQL_stmt_assign
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
int varno;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_assign;
@@ -511,6 +519,7 @@ typedef struct PLpgSQL_stmt_perform
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_perform;
@@ -521,6 +530,7 @@ typedef struct PLpgSQL_stmt_call
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
bool is_call;
PLpgSQL_variable *target;
@@ -533,6 +543,7 @@ typedef struct PLpgSQL_stmt_commit
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
} PLpgSQL_stmt_commit;
/*
@@ -542,6 +553,7 @@ typedef struct PLpgSQL_stmt_rollback
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
} PLpgSQL_stmt_rollback;
/*
@@ -551,6 +563,7 @@ typedef struct PLpgSQL_stmt_set
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
} PLpgSQL_stmt_set;
@@ -570,6 +583,7 @@ typedef struct PLpgSQL_stmt_getdiag
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
bool is_stacked; /* STACKED or CURRENT diagnostics area? */
List *diag_items; /* List of PLpgSQL_diag_item */
} PLpgSQL_stmt_getdiag;
@@ -581,6 +595,7 @@ typedef struct PLpgSQL_stmt_if
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *cond; /* boolean expression for THEN */
List *then_body; /* List of statements */
List *elsif_list; /* List of PLpgSQL_if_elsif structs */
@@ -604,6 +619,7 @@ typedef struct PLpgSQL_stmt_case
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
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 */
@@ -628,6 +644,7 @@ typedef struct PLpgSQL_stmt_loop
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
List *body; /* List of statements */
} PLpgSQL_stmt_loop;
@@ -639,6 +656,7 @@ typedef struct PLpgSQL_stmt_while
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_expr *cond;
List *body; /* List of statements */
@@ -651,6 +669,7 @@ typedef struct PLpgSQL_stmt_fori
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_var *var;
PLpgSQL_expr *lower;
@@ -669,6 +688,7 @@ typedef struct PLpgSQL_stmt_forq
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -681,6 +701,7 @@ typedef struct PLpgSQL_stmt_fors
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -695,6 +716,7 @@ typedef struct PLpgSQL_stmt_forc
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -710,6 +732,7 @@ typedef struct PLpgSQL_stmt_dynfors
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
PLpgSQL_variable *var; /* Loop variable (record or row) */
List *body; /* List of statements */
@@ -725,6 +748,7 @@ typedef struct PLpgSQL_stmt_foreach_a
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
char *label;
int varno; /* loop target variable */
int slice; /* slice dimension, or 0 */
@@ -739,6 +763,7 @@ typedef struct PLpgSQL_stmt_open
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
int curvar;
int cursor_options;
PLpgSQL_expr *argquery;
@@ -754,6 +779,7 @@ typedef struct PLpgSQL_stmt_fetch
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_variable *target; /* target (record or row) */
int curvar; /* cursor variable to fetch from */
FetchDirection direction; /* fetch direction */
@@ -770,6 +796,7 @@ typedef struct PLpgSQL_stmt_close
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
int curvar;
} PLpgSQL_stmt_close;
@@ -780,6 +807,7 @@ typedef struct PLpgSQL_stmt_exit
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
bool is_exit; /* Is this an exit or a continue? */
char *label; /* NULL if it's an unlabelled EXIT/CONTINUE */
PLpgSQL_expr *cond;
@@ -792,6 +820,7 @@ typedef struct PLpgSQL_stmt_return
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
int retvarno;
} PLpgSQL_stmt_return;
@@ -803,6 +832,7 @@ typedef struct PLpgSQL_stmt_return_next
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *expr;
int retvarno;
} PLpgSQL_stmt_return_next;
@@ -814,6 +844,7 @@ typedef struct PLpgSQL_stmt_return_query
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *query; /* if static query */
PLpgSQL_expr *dynquery; /* if dynamic query (RETURN QUERY EXECUTE) */
List *params; /* USING arguments for dynamic query */
@@ -826,6 +857,7 @@ typedef struct PLpgSQL_stmt_raise
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
int elog_level;
char *condname; /* condition name, SQLSTATE, or NULL */
char *message; /* old-style message format literal, or NULL */
@@ -849,6 +881,7 @@ typedef struct PLpgSQL_stmt_assert
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *cond;
PLpgSQL_expr *message;
} PLpgSQL_stmt_assert;
@@ -860,6 +893,7 @@ typedef struct PLpgSQL_stmt_execsql
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *sqlstmt;
bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? Note:
* mod_stmt is set when we plan the query */
@@ -875,6 +909,7 @@ typedef struct PLpgSQL_stmt_dynexecute
{
PLpgSQL_stmt_type cmd_type;
int lineno;
+ unsigned int stmtid;
PLpgSQL_expr *query; /* string expression */
bool into; /* INTO supplied? */
bool strict; /* INTO STRICT flag */
@@ -971,6 +1006,9 @@ typedef struct PLpgSQL_function
/* function body parsetree */
PLpgSQL_stmt_block *action;
+ /* number of statements inside functions */
+ unsigned int nstatements;
+
/* these fields change when the function is used */
struct PLpgSQL_execstate *cur_estate;
unsigned long use_count;
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
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> 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
čt 24. 1. 2019 v 23:08 odesílatel Tom Lane <tgl@sss.pgh.pa.us> napsal:
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> 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
Show quoted text
regards, tom lane
čt 24. 1. 2019 v 23:08 odesílatel Tom Lane <tgl@sss.pgh.pa.us> napsal:
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> 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
Show quoted text
regards, tom lane