summaryrefslogtreecommitdiff
path: root/contrib/pg_stat_statements/pg_stat_statements.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/pg_stat_statements/pg_stat_statements.c')
-rw-r--r--contrib/pg_stat_statements/pg_stat_statements.c33
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);