Funny representation in pg_stat_statements.query.

From: Kyotaro HORIGUCHI <horiguchi(dot)kyotaro(at)lab(dot)ntt(dot)co(dot)jp>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Funny representation in pg_stat_statements.query.
Date: 2014-01-17 08:37:01
Message-ID: 20140117.173701.144038424.horiguchi.kyotaro@lab.ntt.co.jp
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello, I noticed that pg_stat_statements.query can have funny values.

| =# select pg_stat_statements_reset();
| =# select current_timestamp(0);
| <snip>
| =# select query from pg_stat_statements;
| query
| ------------------------------------
| select ?(0);
| select pg_stat_statements_reset();

The same thing happenes for CURRENT_DATE, CURRENT_TIME, LOCALTIME
and LOCALTIMESTAMP which are specially treated, that is,
immediately replaced with a combination of a source function and
a typecast in gram.y.

The story is as follows,

At first, for instance, CURRENT_TIMESTAMP(0) is replaced with
'now()::timestamptz(0)' and "CURRENT_TIMESTAMP"'s location is
used as that of 'now' and the location of the const '1' of
LOCALTIME is used as that of the const '1' for 'timestamptz'.

Let's assume the orignal query was,

| pos: Query
| 0: SELECT
| 7: CURRENT_TIMESTAMP(
| 25: 0
| : );

This is parsed in gram.y as follows, the location for
'CURRENT_TIMESTAMP' above (7) is used as the location for the
CONST "now".

| TypeCast {
| TypeCast {
| A_Const("now")
| TypeName {names = ["text"], loc = -1 (undef) }
| loc = 7
| }
| Typename {names = ["timestamptz"], loc = -1 }
| typemods = [Const {1, loc = 25}]
| }

Then this is transformed into,

| FuncExpr {
| funcid = 'timestamptz'
| args = [
| CoerceViaIO {
| arg = Const {type = "text", value = "now", loc = 7 }
| loc = -1
| }
| Const { type = "int4", value = 1, loc = -1 }
| ]
| }

Finally pg_stat_statements picks the location '7' as a location
of some constant and replaces the token there with '?'
nevertheless it is originally the location of 'CURRENT_TIMESTAMP'
which is not a constant for users.

I found two ways to fix this issue. Both of them prevents wrong
masking but the original constant parameter ('0') becomes won't
be masked. This behavior seems sane enough for the porpose.

A. Making pg_stat_statements conscious of the token types to
prevent wrong masking.

20140117_remove_needless_location_setting.patch

B. Letting gram.y not set the location for the problematic nodes.

20140117_skip_nonconstants_on_nomalization.patch

I don't have firm idea which is preferable. Or the possible
another solution.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

Attachment Content-Type Size
20140117_remove_needless_location_setting.patch text/x-patch 2.9 KB
20140117_skip_nonconstants_on_nomalization.patch text/x-patch 982 bytes

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Jov 2014-01-17 09:12:06 improve the help message about psql -F
Previous Message Boszormenyi Zoltan 2014-01-17 08:00:28 Re: ECPG FETCH readahead, was: Re: ECPG fixes