Sorry for the late reply on this thread. On 14/8/2024 23:05, Imseih (AWS), Sami wrote: > There are no tests as this requires more discussion in a separate thread(?) > Unfortunately, TAP tests don't allow us to keep a connection and > manually permutate the order of queries sent to different connections. > But isolation tests are designed to do so. Of course, they aren't the > best if you need to compare values produced by various queries but see a > clumsy sketch doing that in the attachment.
It would be nice to use isolation tests as you have, those type of tests don't support psql meta-commands. We need \parse, \bind, \bind_named to test queryId for queries issued through extended query protocol. With TAP tests we can use query_until in BackgroundPsql to have one connection issue a command and another connection track the # of distinct queryIds expected. See the 007_query_id.pl of an example TAP test that could be added under test_misc. An INJECTION_POINT can also be added right before we call pgstat_report_query_id in plancache.c. This will allow us to test when we expect the queryId to change after a cache revalidation. Thoughts? > Also, while writing the test, I found out that now, JumbleQuery takes > into account constants of the A_Const node, and calls of the same > prepared statement with different parameters generate different > query_id. Is it a reason to introduce JumbleQuery options and allow > different logic of queryid generation? Can you start a new thread for this prepared statement scenario? -- Sami
# Copyright (c) 2021-2024, PostgreSQL Global Development Group # Check that query_id is advertised as expected. This requires a concurrent # session to check for the last query_id advertised by another session. use strict; use warnings FATAL => 'all'; use PostgreSQL::Test::Cluster; use PostgreSQL::Test::Utils; use Test::More; # declare global variables my $ret; my $node; my $psql_session1; my $psql_session2; # declare the helper functions sub test_num_unique_qids { my ($command, $expected_qids, $wait_for) = @_; $psql_session1->query_safe($command); $psql_session2->query_safe(q(INSERT INTO track_query_id SELECT query_id FROM pg_stat_activity WHERE application_name = 'query_id_test' AND rtrim(query) = 'SELECT * FROM test_query_id' AND query_id is NOT NULL and query_id <> 0;)); $ret = $psql_session2->query_safe( qq[ SELECT COUNT(DISTINCT query_id) FROM track_query_id; ]); is($ret, $expected_qids, "# of distinct queryIds"); } sub create_track_qid_table { $node->safe_psql("postgres", qq[CREATE TABLE track_query_id (query_id BIGINT);]); } sub create_test_qid_table { $node->safe_psql("postgres", qq[DROP TABLE IF EXISTS test_query_id;]); $node->safe_psql("postgres", qq[CREATE TABLE test_query_id (id INT);]); } # Setup the test ## create the node $node = PostgreSQL::Test::Cluster->new('main'); $node->init; $node->append_conf('postgresql.conf', 'compute_query_id = on'); $node->start; ## create the sessions ## session1 will run the queries and session2 will query pg_stat_activity ## for the last query_id of session1 and write it to track_query_id $psql_session1 = $node->background_psql('postgres'); $psql_session1->query_until(qr//, q(SET application_name = query_id_test;)); $psql_session2 = $node->background_psql('postgres'); create_track_qid_table(); # test 1 - check post-parse queryId is reported with extended query protocol # We expected 1 queryId to be reported so far. create_test_qid_table(); test_num_unique_qids("SELECT * FROM test_query_id \\parse n1\n", 1, qr//); # test 2 - check bind-execute queryId is reported in extended query protocol # Since we recreate the table of the underlysing named portal, we now expect # 2 queryIds to be reported. create_test_qid_table(); test_num_unique_qids("\\bind_named n1 \\g\n", 2, qr//); # Destroy the sessions and the node $psql_session1->quit; $psql_session2->quit; $node->stop; done_testing();