Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9148440

Browse files
committed
Expose qurey ID in pg_stat_statements view.
The query ID is the internal hash identifier of the statement, and was not available in pg_stat_statements view so far. Daniel Farina, Sameer Thakur and Peter Geoghegan, reviewed by me.
1 parent ef32675 commit 9148440

7 files changed

+202
-71
lines changed

contrib/pg_stat_statements/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ MODULE_big = pg_stat_statements
44
OBJS = pg_stat_statements.o
55

66
EXTENSION = pg_stat_statements
7-
DATA = pg_stat_statements--1.1.sql pg_stat_statements--1.0--1.1.sql \
8-
pg_stat_statements--unpackaged--1.0.sql
7+
DATA = pg_stat_statements--1.2.sql pg_stat_statements--1.1--1.2.sql \
8+
pg_stat_statements--1.0--1.1.sql pg_stat_statements--unpackaged--1.0.sql
99

1010
ifdef USE_PGXS
1111
PG_CONFIG = pg_config
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* contrib/pg_stat_statements/pg_stat_statements--1.1--1.2.sql */
2+
3+
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
4+
\echo Use "ALTER EXTENSION pg_stat_statements UPDATE TO '1.2'" to load this file. \quit
5+
6+
/* First we have to remove them from the extension */
7+
ALTER EXTENSION pg_stat_statements DROP VIEW pg_stat_statements;
8+
ALTER EXTENSION pg_stat_statements DROP FUNCTION pg_stat_statements();
9+
10+
/* Then we can drop them */
11+
DROP VIEW pg_stat_statements;
12+
DROP FUNCTION pg_stat_statements();
13+
14+
/* Now redefine */
15+
CREATE FUNCTION pg_stat_statements(
16+
OUT userid oid,
17+
OUT dbid oid,
18+
OUT queryid bigint,
19+
OUT query text,
20+
OUT calls int8,
21+
OUT total_time float8,
22+
OUT rows int8,
23+
OUT shared_blks_hit int8,
24+
OUT shared_blks_read int8,
25+
OUT shared_blks_dirtied int8,
26+
OUT shared_blks_written int8,
27+
OUT local_blks_hit int8,
28+
OUT local_blks_read int8,
29+
OUT local_blks_dirtied int8,
30+
OUT local_blks_written int8,
31+
OUT temp_blks_read int8,
32+
OUT temp_blks_written int8,
33+
OUT blk_read_time float8,
34+
OUT blk_write_time float8
35+
)
36+
RETURNS SETOF record
37+
AS 'MODULE_PATHNAME'
38+
LANGUAGE C;
39+
40+
CREATE VIEW pg_stat_statements AS
41+
SELECT * FROM pg_stat_statements();
42+
43+
GRANT SELECT ON pg_stat_statements TO PUBLIC;
Original file line numberDiff line numberDiff line change
@@ -1,43 +0,0 @@
1-
/* contrib/pg_stat_statements/pg_stat_statements--1.1.sql */
2-
3-
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
4-
\echo Use "CREATE EXTENSION pg_stat_statements" to load this file. \quit
5-
6-
-- Register functions.
7-
CREATE FUNCTION pg_stat_statements_reset()
8-
RETURNS void
9-
AS 'MODULE_PATHNAME'
10-
LANGUAGE C;
11-
12-
CREATE FUNCTION pg_stat_statements(
13-
OUT userid oid,
14-
OUT dbid oid,
15-
OUT query text,
16-
OUT calls int8,
17-
OUT total_time float8,
18-
OUT rows int8,
19-
OUT shared_blks_hit int8,
20-
OUT shared_blks_read int8,
21-
OUT shared_blks_dirtied int8,
22-
OUT shared_blks_written int8,
23-
OUT local_blks_hit int8,
24-
OUT local_blks_read int8,
25-
OUT local_blks_dirtied int8,
26-
OUT local_blks_written int8,
27-
OUT temp_blks_read int8,
28-
OUT temp_blks_written int8,
29-
OUT blk_read_time float8,
30-
OUT blk_write_time float8
31-
)
32-
RETURNS SETOF record
33-
AS 'MODULE_PATHNAME'
34-
LANGUAGE C;
35-
36-
-- Register a view on the function for ease of use.
37-
CREATE VIEW pg_stat_statements AS
38-
SELECT * FROM pg_stat_statements();
39-
40-
GRANT SELECT ON pg_stat_statements TO PUBLIC;
41-
42-
-- Don't want this to be available to non-superusers.
43-
REVOKE ALL ON FUNCTION pg_stat_statements_reset() FROM PUBLIC;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* contrib/pg_stat_statements/pg_stat_statements--1.2.sql */
2+
3+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
4+
\echo Use "CREATE EXTENSION pg_stat_statements" to load this file. \quit
5+
6+
-- Register functions.
7+
CREATE FUNCTION pg_stat_statements_reset()
8+
RETURNS void
9+
AS 'MODULE_PATHNAME'
10+
LANGUAGE C;
11+
12+
CREATE FUNCTION pg_stat_statements(
13+
OUT userid oid,
14+
OUT dbid oid,
15+
OUT queryid bigint,
16+
OUT query text,
17+
OUT calls int8,
18+
OUT total_time float8,
19+
OUT rows int8,
20+
OUT shared_blks_hit int8,
21+
OUT shared_blks_read int8,
22+
OUT shared_blks_dirtied int8,
23+
OUT shared_blks_written int8,
24+
OUT local_blks_hit int8,
25+
OUT local_blks_read int8,
26+
OUT local_blks_dirtied int8,
27+
OUT local_blks_written int8,
28+
OUT temp_blks_read int8,
29+
OUT temp_blks_written int8,
30+
OUT blk_read_time float8,
31+
OUT blk_write_time float8
32+
)
33+
RETURNS SETOF record
34+
AS 'MODULE_PATHNAME'
35+
LANGUAGE C;
36+
37+
-- Register a view on the function for ease of use.
38+
CREATE VIEW pg_stat_statements AS
39+
SELECT * FROM pg_stat_statements();
40+
41+
GRANT SELECT ON pg_stat_statements TO PUBLIC;
42+
43+
-- Don't want this to be available to non-superusers.
44+
REVOKE ALL ON FUNCTION pg_stat_statements_reset() FROM PUBLIC;

contrib/pg_stat_statements/pg_stat_statements.c

+52-10
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ PG_MODULE_MAGIC;
6767
#define PGSS_DUMP_FILE "global/pg_stat_statements.stat"
6868

6969
/* This constant defines the magic number in the stats file header */
70-
static const uint32 PGSS_FILE_HEADER = 0x20120328;
70+
static const uint32 PGSS_FILE_HEADER = 0x20131115;
71+
/* PostgreSQL major version number, changes in which invalidate all entries */
72+
static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100;
7173

7274
/* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
7375
#define USAGE_EXEC(duration) (1.0)
@@ -79,6 +81,16 @@ static const uint32 PGSS_FILE_HEADER = 0x20120328;
7981

8082
#define JUMBLE_SIZE 1024 /* query serialization buffer size */
8183

84+
/*
85+
* Extension version number, for supporting older extension versions' objects
86+
*/
87+
typedef enum pgssVersion
88+
{
89+
PGSS_V1_0 = 0,
90+
PGSS_V1_1,
91+
PGSS_V1_2
92+
} pgssVersion;
93+
8294
/*
8395
* Hashtable key that defines the identity of a hashtable entry. We separate
8496
* queries by user and by database even if they are otherwise identical.
@@ -390,6 +402,7 @@ pgss_shmem_startup(void)
390402
FILE *file;
391403
uint32 header;
392404
int32 num;
405+
int32 pgver;
393406
int32 i;
394407
int query_size;
395408
int buffer_size;
@@ -465,6 +478,8 @@ pgss_shmem_startup(void)
465478

466479
if (fread(&header, sizeof(uint32), 1, file) != 1 ||
467480
header != PGSS_FILE_HEADER ||
481+
fread(&pgver, sizeof(uint32), 1, file) != 1 ||
482+
pgver != PGSS_PG_MAJOR_VERSION ||
468483
fread(&num, sizeof(int32), 1, file) != 1)
469484
goto error;
470485

@@ -565,6 +580,8 @@ pgss_shmem_shutdown(int code, Datum arg)
565580

566581
if (fwrite(&PGSS_FILE_HEADER, sizeof(uint32), 1, file) != 1)
567582
goto error;
583+
if (fwrite(&PGSS_PG_MAJOR_VERSION, sizeof(uint32), 1, file) != 1)
584+
goto error;
568585
num_entries = hash_get_num_entries(pgss_hash);
569586
if (fwrite(&num_entries, sizeof(int32), 1, file) != 1)
570587
goto error;
@@ -1069,7 +1086,8 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
10691086
}
10701087

10711088
#define PG_STAT_STATEMENTS_COLS_V1_0 14
1072-
#define PG_STAT_STATEMENTS_COLS 18
1089+
#define PG_STAT_STATEMENTS_COLS_V1_1 18
1090+
#define PG_STAT_STATEMENTS_COLS 19
10731091

10741092
/*
10751093
* Retrieve statement statistics.
@@ -1086,7 +1104,7 @@ pg_stat_statements(PG_FUNCTION_ARGS)
10861104
bool is_superuser = superuser();
10871105
HASH_SEQ_STATUS hash_seq;
10881106
pgssEntry *entry;
1089-
bool sql_supports_v1_1_counters = true;
1107+
pgssVersion detected_version;
10901108

10911109
if (!pgss || !pgss_hash)
10921110
ereport(ERROR,
@@ -1107,8 +1125,21 @@ pg_stat_statements(PG_FUNCTION_ARGS)
11071125
/* Build a tuple descriptor for our result type */
11081126
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
11091127
elog(ERROR, "return type must be a row type");
1110-
if (tupdesc->natts == PG_STAT_STATEMENTS_COLS_V1_0)
1111-
sql_supports_v1_1_counters = false;
1128+
1129+
switch (tupdesc->natts)
1130+
{
1131+
case PG_STAT_STATEMENTS_COLS_V1_0:
1132+
detected_version = PGSS_V1_0;
1133+
break;
1134+
case PG_STAT_STATEMENTS_COLS_V1_1:
1135+
detected_version = PGSS_V1_1;
1136+
break;
1137+
case PG_STAT_STATEMENTS_COLS:
1138+
detected_version = PGSS_V1_2;
1139+
break;
1140+
default:
1141+
elog(ERROR, "pgss version unrecognized from tuple descriptor");
1142+
}
11121143

11131144
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
11141145
oldcontext = MemoryContextSwitchTo(per_query_ctx);
@@ -1140,6 +1171,9 @@ pg_stat_statements(PG_FUNCTION_ARGS)
11401171
{
11411172
char *qstr;
11421173

1174+
if (detected_version >= PGSS_V1_2)
1175+
values[i++] = Int64GetDatumFast((int64) entry->key.queryid);
1176+
11431177
qstr = (char *)
11441178
pg_do_encoding_conversion((unsigned char *) entry->query,
11451179
entry->query_len,
@@ -1150,7 +1184,12 @@ pg_stat_statements(PG_FUNCTION_ARGS)
11501184
pfree(qstr);
11511185
}
11521186
else
1187+
{
1188+
if (detected_version >= PGSS_V1_2)
1189+
nulls[i++] = true;
1190+
11531191
values[i++] = CStringGetTextDatum("<insufficient privilege>");
1192+
}
11541193

11551194
/* copy counters to a local variable to keep locking time short */
11561195
{
@@ -1170,24 +1209,27 @@ pg_stat_statements(PG_FUNCTION_ARGS)
11701209
values[i++] = Int64GetDatumFast(tmp.rows);
11711210
values[i++] = Int64GetDatumFast(tmp.shared_blks_hit);
11721211
values[i++] = Int64GetDatumFast(tmp.shared_blks_read);
1173-
if (sql_supports_v1_1_counters)
1212+
if (detected_version >= PGSS_V1_1)
11741213
values[i++] = Int64GetDatumFast(tmp.shared_blks_dirtied);
11751214
values[i++] = Int64GetDatumFast(tmp.shared_blks_written);
11761215
values[i++] = Int64GetDatumFast(tmp.local_blks_hit);
11771216
values[i++] = Int64GetDatumFast(tmp.local_blks_read);
1178-
if (sql_supports_v1_1_counters)
1217+
if (detected_version >= PGSS_V1_1)
11791218
values[i++] = Int64GetDatumFast(tmp.local_blks_dirtied);
11801219
values[i++] = Int64GetDatumFast(tmp.local_blks_written);
11811220
values[i++] = Int64GetDatumFast(tmp.temp_blks_read);
11821221
values[i++] = Int64GetDatumFast(tmp.temp_blks_written);
1183-
if (sql_supports_v1_1_counters)
1222+
if (detected_version >= PGSS_V1_1)
11841223
{
11851224
values[i++] = Float8GetDatumFast(tmp.blk_read_time);
11861225
values[i++] = Float8GetDatumFast(tmp.blk_write_time);
11871226
}
11881227

1189-
Assert(i == (sql_supports_v1_1_counters ?
1190-
PG_STAT_STATEMENTS_COLS : PG_STAT_STATEMENTS_COLS_V1_0));
1228+
Assert(i == (detected_version == PGSS_V1_0?
1229+
PG_STAT_STATEMENTS_COLS_V1_0:
1230+
detected_version == PGSS_V1_1?
1231+
PG_STAT_STATEMENTS_COLS_V1_1:
1232+
PG_STAT_STATEMENTS_COLS));
11911233

11921234
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
11931235
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# pg_stat_statements extension
22
comment = 'track execution statistics of all SQL statements executed'
3-
default_version = '1.1'
3+
default_version = '1.2'
44
module_pathname = '$libdir/pg_stat_statements'
55
relocatable = true

0 commit comments

Comments
 (0)