Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3c03b8c

Browse files
committed
pg_stat_statements: Fix parameter number gaps in normalized queries
pg_stat_statements anticipates that certain constant locations may berecorded multiple times and attempts to avoid calculating a length forthese locations in fill_in_constant_lengths().However, during generate_normalized_query() where normalized querystrings are generated, these locations are not excluded fromconsideration. This could increment the parameter number counter forevery recorded occurrence at such a location, leading to an incorrectnormalization in certain cases with gaps in the numbers reported.For example, take this query:SELECT WHERE '1' IN ('2'::int, '3'::int::text)Before this commit, it would be normalized like that, with gaps in theparameter numbers:SELECT WHERE $1 IN ($3::int, $4::int::text)However the correct, less confusing one should be like that:SELECT WHERE $1 IN ($2::int, $3::int::text)This commit fixes the computation of the parameter numbers to track thenumber of constants replaced with an $n by a separate counter instead ofthe iterator used to loop through the list of locations.The underlying query IDs are not changed, neither are the normalizedstrings for existing PGSS hash entries. New entries with freshnormalized queries would automatically get reshaped based on the newparameter numbering.Issue discovered while discussing a separate problem for HEAD, but thisaffects all the stable branches.Author: Sami Imseih <samimseih@gmail.com>Discussion:https://postgr.es/m/CAA5RZ0tzxvWXsacGyxrixdhy3tTTDfJQqxyFBRFh31nNHBQ5qA@mail.gmail.comBackpatch-through: 13
1 parent31ee5ec commit3c03b8c

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

‎contrib/pg_stat_statements/expected/pg_stat_statements.out

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,35 @@ SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
398398
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C" | 0 | 0
399399
(6 rows)
400400

401+
-- normalization of constants and parameters, with constant locations
402+
-- recorded one or more times.
403+
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
404+
t
405+
---
406+
t
407+
(1 row)
408+
409+
SELECT WHERE '1' IN ('1'::int, '3'::int::text);
410+
--
411+
(1 row)
412+
413+
SELECT WHERE (1, 2) IN ((1, 2), (2, 3));
414+
--
415+
(1 row)
416+
417+
SELECT WHERE (3, 4) IN ((5, 6), (8, 7));
418+
--
419+
(0 rows)
420+
421+
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
422+
query | calls
423+
------------------------------------------------------------------------+-------
424+
SELECT WHERE $1 IN ($2::int, $3::int::text) | 1
425+
SELECT WHERE ($1, $2) IN (($3, $4), ($5, $6)) | 2
426+
SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
427+
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C" | 0
428+
(4 rows)
429+
401430
--
402431
-- queries with locking clauses
403432
--

‎contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3278,6 +3278,7 @@ generate_normalized_query(pgssJumbleState *jstate, const char *query,
32783278
n_quer_loc=0,/* Normalized query byte location */
32793279
last_off=0,/* Offset from start for previous tok */
32803280
last_tok_len=0;/* Length (in bytes) of that tok */
3281+
intnum_constants_replaced=0;
32813282

32823283
/*
32833284
* Get constants' lengths (core system only gives us locations). Note
@@ -3321,7 +3322,8 @@ generate_normalized_query(pgssJumbleState *jstate, const char *query,
33213322

33223323
/* And insert a param symbol in place of the constant token */
33233324
n_quer_loc+=sprintf(norm_query+n_quer_loc,"$%d",
3324-
i+1+jstate->highest_extern_param_id);
3325+
num_constants_replaced+1+jstate->highest_extern_param_id);
3326+
num_constants_replaced++;
33253327

33263328
quer_loc=off+tok_len;
33273329
last_off=off;

‎contrib/pg_stat_statements/sql/pg_stat_statements.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,14 @@ SELECT PLUS_ONE(1);
201201

202202
SELECT query, calls, rowsFROM pg_stat_statementsORDER BY query COLLATE"C";
203203

204+
-- normalization of constants and parameters, with constant locations
205+
-- recorded one or more times.
206+
SELECT pg_stat_statements_reset()IS NOT NULLAS t;
207+
SELECTWHERE'1'IN ('1'::int,'3'::int::text);
208+
SELECTWHERE (1,2)IN ((1,2), (2,3));
209+
SELECTWHERE (3,4)IN ((5,6), (8,7));
210+
SELECT query, callsFROM pg_stat_statementsORDER BY query COLLATE"C";
211+
204212
--
205213
-- queries with locking clauses
206214
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp