Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit debad29

Browse files
author
Álvaro Herrera
committed
Improve jumble squashing through CoerceViaIO and RelabelType
There's no principled reason for query jumbling to only remove the first layer of RelabelType and CoerceViaIO. Change it to see through as many layers as there are.
1 parent 303ba05 commit debad29

File tree

3 files changed

+45
-31
lines changed

3 files changed

+45
-31
lines changed

contrib/pg_stat_statements/expected/squashing.out

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
645645
SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
646646
(2 rows)
647647

648-
-- Multiple CoerceViaIO wrapping a constant. Will not squash
648+
-- Multiple CoerceViaIO are squashed
649649
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
650650
t
651651
---
@@ -661,10 +661,10 @@ SELECT WHERE 1 = ANY(ARRAY[1::text::int::text::int, 1::text::int::text::int]);
661661
(1 row)
662662

663663
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
664-
query | calls
665-
-------------------------------------------------------------------------+-------
666-
SELECT WHERE $1 IN ($2::text::int::text::int, $3::text::int::text::int) | 2
667-
SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
664+
query | calls
665+
----------------------------------------------------+-------
666+
SELECT WHERE $1 IN ($2 /*, ... */) | 2
667+
SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
668668
(2 rows)
669669

670670
--
@@ -676,7 +676,7 @@ SELECT pg_stat_statements_reset() IS NOT NULL AS t;
676676
t
677677
(1 row)
678678

679-
-- if there is only one level of RelabelType, the list will be squashable
679+
-- However many layers of RelabelType there are, the list will be squashable.
680680
SELECT * FROM test_squash WHERE id IN
681681
(1::oid, 2::oid, 3::oid, 4::oid, 5::oid, 6::oid, 7::oid, 8::oid, 9::oid);
682682
id | data
@@ -689,8 +689,6 @@ SELECT ARRAY[1::oid, 2::oid, 3::oid, 4::oid, 5::oid, 6::oid, 7::oid, 8::oid, 9::
689689
{1,2,3,4,5,6,7,8,9}
690690
(1 row)
691691

692-
-- if there is at least one element with multiple levels of RelabelType,
693-
-- the list will not be squashable
694692
SELECT * FROM test_squash WHERE id IN (1::oid, 2::oid::int::oid);
695693
id | data
696694
----+------
@@ -701,15 +699,25 @@ SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::oid, 2::oid::int::oid]);
701699
----+------
702700
(0 rows)
703701

702+
-- RelabelType together with CoerceViaIO is also squashable
703+
SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::oid::text::int::oid, 2::oid::int::oid]);
704+
id | data
705+
----+------
706+
(0 rows)
707+
708+
SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::text::int::oid, 2::oid::int::oid]);
709+
id | data
710+
----+------
711+
(0 rows)
712+
704713
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
705-
query | calls
706-
--------------------------------------------------------------------+-------
707-
SELECT * FROM test_squash WHERE id IN +| 1
708-
($1 /*, ... */) |
709-
SELECT * FROM test_squash WHERE id IN ($1::oid, $2::oid::int::oid) | 2
710-
SELECT ARRAY[$1 /*, ... */] | 1
711-
SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
712-
(4 rows)
714+
query | calls
715+
----------------------------------------------------+-------
716+
SELECT * FROM test_squash WHERE id IN +| 5
717+
($1 /*, ... */) |
718+
SELECT ARRAY[$1 /*, ... */] | 1
719+
SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
720+
(3 rows)
713721

714722
--
715723
-- edge cases

contrib/pg_stat_statements/sql/squashing.sql

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ SELECT * FROM test_squash_jsonb WHERE data = ANY(ARRAY
234234
(SELECT '"10"')::jsonb]);
235235
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
236236

237-
-- Multiple CoerceViaIO wrapping a constant. Will not squash
237+
-- Multiple CoerceViaIO are squashed
238238
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
239239
SELECT WHERE 1 IN (1::text::int::text::int, 1::text::int::text::int);
240240
SELECT WHERE 1 = ANY(ARRAY[1::text::int::text::int, 1::text::int::text::int]);
@@ -245,14 +245,15 @@ SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
245245
--
246246

247247
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
248-
-- if there is only one level of RelabelType, the list will be squashable
248+
-- However many layers of RelabelType there are, the list will be squashable.
249249
SELECT * FROM test_squash WHERE id IN
250250
(1::oid, 2::oid, 3::oid, 4::oid, 5::oid, 6::oid, 7::oid, 8::oid, 9::oid);
251251
SELECT ARRAY[1::oid, 2::oid, 3::oid, 4::oid, 5::oid, 6::oid, 7::oid, 8::oid, 9::oid];
252-
-- if there is at least one element with multiple levels of RelabelType,
253-
-- the list will not be squashable
254252
SELECT * FROM test_squash WHERE id IN (1::oid, 2::oid::int::oid);
255253
SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::oid, 2::oid::int::oid]);
254+
-- RelabelType together with CoerceViaIO is also squashable
255+
SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::oid::text::int::oid, 2::oid::int::oid]);
256+
SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::text::int::oid, 2::oid::int::oid]);
256257
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
257258

258259
--

src/backend/nodes/queryjumblefuncs.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -414,22 +414,30 @@ RecordConstLocation(JumbleState *jstate, int location, int len)
414414
* Subroutine for _jumbleElements: Verify a few simple cases where we can
415415
* deduce that the expression is a constant:
416416
*
417-
* - Ignore a possible wrapping RelabelType and CoerceViaIO.
417+
* - See through any wrapping RelabelType and CoerceViaIO layers.
418418
* - If it's a FuncExpr, check that the function is a builtin
419419
* cast and its arguments are Const.
420420
* - Otherwise test if the expression is a simple Const.
421421
*/
422422
static bool
423423
IsSquashableConstant(Node *element)
424424
{
425-
if (IsA(element, RelabelType))
426-
element = (Node *) ((RelabelType *) element)->arg;
427-
428-
if (IsA(element, CoerceViaIO))
429-
element = (Node *) ((CoerceViaIO *) element)->arg;
430-
425+
restart:
431426
switch (nodeTag(element))
432427
{
428+
case T_RelabelType:
429+
/* Unwrap RelabelType */
430+
element = (Node *) ((RelabelType *) element)->arg;
431+
goto restart;
432+
433+
case T_CoerceViaIO:
434+
/* Unwrap CoerceViaIO */
435+
element = (Node *) ((CoerceViaIO *) element)->arg;
436+
goto restart;
437+
438+
case T_Const:
439+
return true;
440+
433441
case T_FuncExpr:
434442
{
435443
FuncExpr *func = (FuncExpr *) element;
@@ -468,11 +476,8 @@ IsSquashableConstant(Node *element)
468476
}
469477

470478
default:
471-
if (!IsA(element, Const))
472-
return false;
479+
return false;
473480
}
474-
475-
return true;
476481
}
477482

478483
/*

0 commit comments

Comments
 (0)