mirror of https://github.com/postgres/postgres
Fix pg_stat_statements for MERGE
We weren't jumbling the merge action list, so wildly different commands would be considered to use the same query ID. Add that, mention it in the docs, and some test lines. Backpatch to 15. Author: Tatsu <bt22nakamorit@oss.nttdata.com> Reviewed-by: Julien Rouhaud <rjuju123@gmail.com> Discussion: https://postgr.es/m/d87e391694db75a038abc3b2597828e8@oss.nttdata.com
This commit is contained in:
parent
bed0927aeb
commit
249b0409b1
|
@ -222,12 +222,51 @@ SELECT * FROM test WHERE a IN (1, 2, 3, 4, 5);
|
|||
3 | c
|
||||
(8 rows)
|
||||
|
||||
-- MERGE
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED THEN UPDATE SET b = st.b || st.a::text;
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED THEN UPDATE SET b = test.b || st.a::text;
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED AND length(st.b) > 1 THEN UPDATE SET b = test.b || st.a::text;
|
||||
MERGE INTO test USING test st ON (st.a = test.a)
|
||||
WHEN NOT MATCHED THEN INSERT (a, b) VALUES (0, NULL);
|
||||
MERGE INTO test USING test st ON (st.a = test.a)
|
||||
WHEN NOT MATCHED THEN INSERT VALUES (0, NULL); -- same as above
|
||||
MERGE INTO test USING test st ON (st.a = test.a)
|
||||
WHEN NOT MATCHED THEN INSERT (b, a) VALUES (NULL, 0);
|
||||
MERGE INTO test USING test st ON (st.a = test.a)
|
||||
WHEN NOT MATCHED THEN INSERT (a) VALUES (0);
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED THEN DELETE;
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED THEN DO NOTHING;
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN NOT MATCHED THEN DO NOTHING;
|
||||
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
|
||||
query | calls | rows
|
||||
------------------------------------------------------------------------------+-------+------
|
||||
DELETE FROM test WHERE a > $1 | 1 | 1
|
||||
INSERT INTO test (a, b) VALUES ($1, $2), ($3, $4), ($5, $6) | 1 | 3
|
||||
INSERT INTO test VALUES(generate_series($1, $2), $3) | 1 | 10
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= $1) +| 1 | 6
|
||||
WHEN MATCHED AND length(st.b) > $2 THEN UPDATE SET b = test.b || st.a::text | |
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= $1) +| 1 | 6
|
||||
WHEN MATCHED THEN DELETE | |
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= $1) +| 1 | 0
|
||||
WHEN MATCHED THEN DO NOTHING | |
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= $1) +| 1 | 6
|
||||
WHEN MATCHED THEN UPDATE SET b = st.b || st.a::text | |
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= $1) +| 1 | 6
|
||||
WHEN MATCHED THEN UPDATE SET b = test.b || st.a::text | |
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= $1) +| 1 | 0
|
||||
WHEN NOT MATCHED THEN DO NOTHING | |
|
||||
MERGE INTO test USING test st ON (st.a = test.a) +| 1 | 0
|
||||
WHEN NOT MATCHED THEN INSERT (a) VALUES ($1) | |
|
||||
MERGE INTO test USING test st ON (st.a = test.a) +| 2 | 0
|
||||
WHEN NOT MATCHED THEN INSERT (a, b) VALUES ($1, $2) | |
|
||||
MERGE INTO test USING test st ON (st.a = test.a) +| 1 | 0
|
||||
WHEN NOT MATCHED THEN INSERT (b, a) VALUES ($1, $2) | |
|
||||
SELECT * FROM test ORDER BY a | 1 | 12
|
||||
SELECT * FROM test WHERE a > $1 ORDER BY a | 2 | 4
|
||||
SELECT * FROM test WHERE a IN ($1, $2, $3, $4, $5) | 1 | 8
|
||||
|
@ -235,7 +274,7 @@ SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
|
|||
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C" | 0 | 0
|
||||
UPDATE test SET b = $1 WHERE a = $2 | 6 | 6
|
||||
UPDATE test SET b = $1 WHERE a > $2 | 1 | 3
|
||||
(10 rows)
|
||||
(19 rows)
|
||||
|
||||
--
|
||||
-- INSERT, UPDATE, DELETE on test table to validate WAL generation metrics
|
||||
|
|
|
@ -100,6 +100,28 @@ SELECT * FROM test ORDER BY a;
|
|||
-- SELECT with IN clause
|
||||
SELECT * FROM test WHERE a IN (1, 2, 3, 4, 5);
|
||||
|
||||
-- MERGE
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED THEN UPDATE SET b = st.b || st.a::text;
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED THEN UPDATE SET b = test.b || st.a::text;
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED AND length(st.b) > 1 THEN UPDATE SET b = test.b || st.a::text;
|
||||
MERGE INTO test USING test st ON (st.a = test.a)
|
||||
WHEN NOT MATCHED THEN INSERT (a, b) VALUES (0, NULL);
|
||||
MERGE INTO test USING test st ON (st.a = test.a)
|
||||
WHEN NOT MATCHED THEN INSERT VALUES (0, NULL); -- same as above
|
||||
MERGE INTO test USING test st ON (st.a = test.a)
|
||||
WHEN NOT MATCHED THEN INSERT (b, a) VALUES (NULL, 0);
|
||||
MERGE INTO test USING test st ON (st.a = test.a)
|
||||
WHEN NOT MATCHED THEN INSERT (a) VALUES (0);
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED THEN DELETE;
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN MATCHED THEN DO NOTHING;
|
||||
MERGE INTO test USING test st ON (st.a = test.a AND st.a >= 4)
|
||||
WHEN NOT MATCHED THEN DO NOTHING;
|
||||
|
||||
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
|
||||
|
||||
--
|
||||
|
|
|
@ -487,7 +487,7 @@
|
|||
|
||||
<para>
|
||||
Plannable queries (that is, <command>SELECT</command>, <command>INSERT</command>,
|
||||
<command>UPDATE</command>, and <command>DELETE</command>) are combined into a single
|
||||
<command>UPDATE</command>, <command>DELETE</command>, and <command>MERGE</command>) are combined into a single
|
||||
<structname>pg_stat_statements</structname> entry whenever they have identical query
|
||||
structures according to an internal hash calculation. Typically, two
|
||||
queries will be considered the same for this purpose if they are
|
||||
|
@ -783,7 +783,7 @@
|
|||
<varname>pg_stat_statements.track_utility</varname> controls whether
|
||||
utility commands are tracked by the module. Utility commands are
|
||||
all those other than <command>SELECT</command>, <command>INSERT</command>,
|
||||
<command>UPDATE</command> and <command>DELETE</command>.
|
||||
<command>UPDATE</command>, <command>DELETE</command>, and <command>MERGE</command>.
|
||||
The default value is <literal>on</literal>.
|
||||
Only superusers can change this setting.
|
||||
</para>
|
||||
|
|
|
@ -2259,10 +2259,10 @@ expression_tree_walker_impl(Node *node,
|
|||
{
|
||||
MergeAction *action = (MergeAction *) node;
|
||||
|
||||
if (WALK(action->targetList))
|
||||
return true;
|
||||
if (WALK(action->qual))
|
||||
return true;
|
||||
if (WALK(action->targetList))
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case T_PartitionPruneStepOp:
|
||||
|
|
|
@ -248,6 +248,7 @@ JumbleQueryInternal(JumbleState *jstate, Query *query)
|
|||
JumbleExpr(jstate, (Node *) query->cteList);
|
||||
JumbleRangeTable(jstate, query->rtable);
|
||||
JumbleExpr(jstate, (Node *) query->jointree);
|
||||
JumbleExpr(jstate, (Node *) query->mergeActionList);
|
||||
JumbleExpr(jstate, (Node *) query->targetList);
|
||||
JumbleExpr(jstate, (Node *) query->onConflict);
|
||||
JumbleExpr(jstate, (Node *) query->returningList);
|
||||
|
@ -738,6 +739,16 @@ JumbleExpr(JumbleState *jstate, Node *node)
|
|||
JumbleExpr(jstate, (Node *) conf->exclRelTlist);
|
||||
}
|
||||
break;
|
||||
case T_MergeAction:
|
||||
{
|
||||
MergeAction *mergeaction = (MergeAction *) node;
|
||||
|
||||
APP_JUMB(mergeaction->matched);
|
||||
APP_JUMB(mergeaction->commandType);
|
||||
JumbleExpr(jstate, mergeaction->qual);
|
||||
JumbleExpr(jstate, (Node *) mergeaction->targetList);
|
||||
}
|
||||
break;
|
||||
case T_List:
|
||||
foreach(temp, (List *) node)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue