SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
(2 rows)
--- Multiple CoerceViaIO wrapping a constant. Will not squash
+-- Multiple CoerceViaIO are squashed
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
t
---
(1 row)
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
- query | calls
--------------------------------------------------------------------------+-------
- SELECT WHERE $1 IN ($2::text::int::text::int, $3::text::int::text::int) | 2
- SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
+ query | calls
+----------------------------------------------------+-------
+ SELECT WHERE $1 IN ($2 /*, ... */) | 2
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
(2 rows)
--
t
(1 row)
--- if there is only one level of RelabelType, the list will be squashable
+-- However many layers of RelabelType there are, the list will be squashable.
SELECT * FROM test_squash WHERE id IN
(1::oid, 2::oid, 3::oid, 4::oid, 5::oid, 6::oid, 7::oid, 8::oid, 9::oid);
id | data
{1,2,3,4,5,6,7,8,9}
(1 row)
--- if there is at least one element with multiple levels of RelabelType,
--- the list will not be squashable
SELECT * FROM test_squash WHERE id IN (1::oid, 2::oid::int::oid);
id | data
----+------
----+------
(0 rows)
+-- RelabelType together with CoerceViaIO is also squashable
+SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::oid::text::int::oid, 2::oid::int::oid]);
+ id | data
+----+------
+(0 rows)
+
+SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::text::int::oid, 2::oid::int::oid]);
+ id | data
+----+------
+(0 rows)
+
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
- query | calls
---------------------------------------------------------------------+-------
- SELECT * FROM test_squash WHERE id IN +| 1
- ($1 /*, ... */) |
- SELECT * FROM test_squash WHERE id IN ($1::oid, $2::oid::int::oid) | 2
- SELECT ARRAY[$1 /*, ... */] | 1
- SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
-(4 rows)
+ query | calls
+----------------------------------------------------+-------
+ SELECT * FROM test_squash WHERE id IN +| 5
+ ($1 /*, ... */) |
+ SELECT ARRAY[$1 /*, ... */] | 1
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t | 1
+(3 rows)
--
-- edge cases
(SELECT '"10"')::jsonb]);
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
--- Multiple CoerceViaIO wrapping a constant. Will not squash
+-- Multiple CoerceViaIO are squashed
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
SELECT WHERE 1 IN (1::text::int::text::int, 1::text::int::text::int);
SELECT WHERE 1 = ANY(ARRAY[1::text::int::text::int, 1::text::int::text::int]);
--
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
--- if there is only one level of RelabelType, the list will be squashable
+-- However many layers of RelabelType there are, the list will be squashable.
SELECT * FROM test_squash WHERE id IN
(1::oid, 2::oid, 3::oid, 4::oid, 5::oid, 6::oid, 7::oid, 8::oid, 9::oid);
SELECT ARRAY[1::oid, 2::oid, 3::oid, 4::oid, 5::oid, 6::oid, 7::oid, 8::oid, 9::oid];
--- if there is at least one element with multiple levels of RelabelType,
--- the list will not be squashable
SELECT * FROM test_squash WHERE id IN (1::oid, 2::oid::int::oid);
SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::oid, 2::oid::int::oid]);
+-- RelabelType together with CoerceViaIO is also squashable
+SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::oid::text::int::oid, 2::oid::int::oid]);
+SELECT * FROM test_squash WHERE id = ANY(ARRAY[1::text::int::oid, 2::oid::int::oid]);
SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
--
* Subroutine for _jumbleElements: Verify a few simple cases where we can
* deduce that the expression is a constant:
*
- * - Ignore a possible wrapping RelabelType and CoerceViaIO.
+ * - See through any wrapping RelabelType and CoerceViaIO layers.
* - If it's a FuncExpr, check that the function is a builtin
* cast and its arguments are Const.
* - Otherwise test if the expression is a simple Const.
static bool
IsSquashableConstant(Node *element)
{
- if (IsA(element, RelabelType))
- element = (Node *) ((RelabelType *) element)->arg;
-
- if (IsA(element, CoerceViaIO))
- element = (Node *) ((CoerceViaIO *) element)->arg;
-
+restart:
switch (nodeTag(element))
{
+ case T_RelabelType:
+ /* Unwrap RelabelType */
+ element = (Node *) ((RelabelType *) element)->arg;
+ goto restart;
+
+ case T_CoerceViaIO:
+ /* Unwrap CoerceViaIO */
+ element = (Node *) ((CoerceViaIO *) element)->arg;
+ goto restart;
+
+ case T_Const:
+ return true;
+
case T_FuncExpr:
{
FuncExpr *func = (FuncExpr *) element;
}
default:
- if (!IsA(element, Const))
- return false;
+ return false;
}
-
- return true;
}
/*