diff options
Diffstat (limited to 'contrib/pg_stat_statements/pg_stat_statements.c')
| -rw-r--r-- | contrib/pg_stat_statements/pg_stat_statements.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index f2187167c5c..39208f80b5b 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -2954,9 +2954,8 @@ generate_normalized_query(JumbleState *jstate, const char *query, * have originated from within the authoritative parser, this should not be * a problem. * - * Duplicate constant pointers are possible, and will have their lengths - * marked as '-1', so that they are later ignored. (Actually, we assume the - * lengths were initialized as -1 to start with, and don't change them here.) + * Multiple constants can have the same location. We reset lengths of those + * past the first to -1 so that they can later be ignored. * * If query_loc > 0, then "query" has been advanced by that much compared to * the original string start, so we need to translate the provided locations @@ -2976,8 +2975,6 @@ fill_in_constant_lengths(JumbleState *jstate, const char *query, core_yy_extra_type yyextra; core_YYSTYPE yylval; YYLTYPE yylloc; - int last_loc = -1; - int i; /* * Sort the records by location so that we can process them in order while @@ -2998,23 +2995,29 @@ fill_in_constant_lengths(JumbleState *jstate, const char *query, yyextra.escape_string_warning = false; /* Search for each constant, in sequence */ - for (i = 0; i < jstate->clocations_count; i++) + for (int i = 0; i < jstate->clocations_count; i++) { - int loc = locs[i].location; + int loc; int tok; - /* Adjust recorded location if we're dealing with partial string */ - loc -= query_loc; - - Assert(loc >= 0); + /* Ignore constants after the first one in the same location */ + if (i > 0 && locs[i].location == locs[i - 1].location) + { + locs[i].length = -1; + continue; + } if (locs[i].squashed) continue; /* squashable list, ignore */ - if (loc <= last_loc) - continue; /* Duplicate constant, ignore */ + /* Adjust recorded location if we're dealing with partial string */ + loc = locs[i].location - query_loc; + Assert(loc >= 0); - /* Lex tokens until we find the desired constant */ + /* + * We have a valid location for a constant that's not a dupe. Lex + * tokens until we find the desired constant. + */ for (;;) { tok = core_yylex(&yylval, &yylloc, yyscanner); @@ -3060,8 +3063,6 @@ fill_in_constant_lengths(JumbleState *jstate, const char *query, /* If we hit end-of-string, give up, leaving remaining lengths -1 */ if (tok == 0) break; - - last_loc = loc; } scanner_finish(yyscanner); |
