Re: Set query_id for query contained in utility statement

jian he <jian.universality@gmail.com>

From: jian he <jian.universality@gmail.com>
To: Michael Paquier <michael@paquier.xyz>
Cc: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>, PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Date: 2024-10-07T16:17:11Z
Lists: pgsql-hackers

Attachments

On Mon, Oct 7, 2024 at 1:39 PM Michael Paquier <michael@paquier.xyz> wrote:
>
> On Fri, Oct 04, 2024 at 08:16:00PM +0800, jian he wrote:
> > about v5 0001
> > select_with_parens:
> >             '(' select_no_parens ')'                { $$ = $2; }
> >             | '(' select_with_parens ')'            { $$ = $2; }
> >         ;
> >
> >
> >  toplevel | calls |                         query
> > ----------+-------+-------------------------------------------------------
> >  t        |     1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
> >  t        |     0 | SELECT toplevel, calls, query FROM pg_stat_statements+
> >           |       |   ORDER BY query COLLATE "C", toplevel
> >  t        |     1 | explain (select $1)
> >  f        |     1 | select $1);
> >
> > query "select $1);" looks weird. not sure how to improve it,
> > or this should be the expected behavior?
>
> GOod point, this is confusing.  The point is that having only
> stmt_location is not enough to detect where the element in the query
> you want to track is because it only points at its start location in
> the full query string.  In an ideal world, what we should have is its
> start and end, pass it down to pgss_store(), and store only this
> subquery between the start and end positions in the stats entry.
> Making that right through the parser may be challenging, though.
>

turns out UPDATE/DELETE/MERGE and other utilities stmt cannot have
arbitrary parenthesis with EXPLAIN.

attached patches can solve this specific problem.
(based on v5-0001-Track-location-to-extract-relevant-part-in-nested.patch)

the main gotcha is to add location information for the statement that
is being explained.
typedef struct ExplainStmt
{
    NodeTag        type;
    Node       *query;            /* the query (see comments above) */
    List       *options;        /* list of DefElem nodes */
    ParseLoc    location;        /* location of the statement being explained */
} ExplainStmt;

explain select 1;
explain (select 1);
explain (((select 1)));

the above 3 explained select queries will be normalized to one select query.

Commits

  1. Set query ID for inner queries of CREATE TABLE AS and DECLARE

  2. Track more precisely query locations for nested statements

  3. pg_stat_statements: Add tests for nested queries with level tracking

  4. Fix race condition in COMMIT PREPARED causing orphaned 2PC files