Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6ffff0f

Browse filesBrowse files
committed
Fix pg_prepared_statements.result_types for DML statements
Amendment to 84ad713: Not all prepared statements have a result descriptor. As currently coded, this would crash when reading pg_prepared_statements. Make those cases return null for result_types instead. Also add a test case for it.
1 parent e3dd7c0 commit 6ffff0f
Copy full SHA for 6ffff0f

File tree

4 files changed

+26
-7
lines changed
Filter options

4 files changed

+26
-7
lines changed

‎doc/src/sgml/catalogs.sgml

Copy file name to clipboardExpand all lines: doc/src/sgml/catalogs.sgml
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11511,6 +11511,8 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
1151111511
form of an array of <type>regtype</type>. The OID corresponding
1151211512
to an element of this array can be obtained by casting the
1151311513
<type>regtype</type> value to <type>oid</type>.
11514+
If the prepared statement does not provide a result (e.g., a DML
11515+
statement), then this field will be null.
1151411516
</para></entry>
1151511517
</row>
1151611518

‎src/backend/commands/prepare.c

Copy file name to clipboardExpand all lines: src/backend/commands/prepare.c
+14-6Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -684,15 +684,10 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
684684
while ((prep_stmt = hash_seq_search(&hash_seq)) != NULL)
685685
{
686686
TupleDesc result_desc;
687-
Oid *result_types;
688687
Datum values[8];
689688
bool nulls[8];
690689

691690
result_desc = prep_stmt->plansource->resultDesc;
692-
result_types = (Oid *) palloc(result_desc->natts * sizeof(Oid));
693-
694-
for (int i = 0; i < result_desc->natts; i++)
695-
result_types[i] = result_desc->attrs[i].atttypid;
696691

697692
MemSet(nulls, 0, sizeof(nulls));
698693

@@ -701,7 +696,20 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
701696
values[2] = TimestampTzGetDatum(prep_stmt->prepare_time);
702697
values[3] = build_regtype_array(prep_stmt->plansource->param_types,
703698
prep_stmt->plansource->num_params);
704-
values[4] = build_regtype_array(result_types, result_desc->natts);
699+
if (result_desc)
700+
{
701+
Oid *result_types;
702+
703+
result_types = (Oid *) palloc(result_desc->natts * sizeof(Oid));
704+
for (int i = 0; i < result_desc->natts; i++)
705+
result_types[i] = result_desc->attrs[i].atttypid;
706+
values[4] = build_regtype_array(result_types, result_desc->natts);
707+
}
708+
else
709+
{
710+
/* no result descriptor (for example, DML statement) */
711+
nulls[4] = true;
712+
}
705713
values[5] = BoolGetDatum(prep_stmt->from_sql);
706714
values[6] = Int64GetDatumFast(prep_stmt->plansource->num_generic_plans);
707715
values[7] = Int64GetDatumFast(prep_stmt->plansource->num_custom_plans);

‎src/test/regress/expected/prepare.out

Copy file name to clipboardExpand all lines: src/test/regress/expected/prepare.out
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ PREPARE q6 AS
159159
SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2;
160160
PREPARE q7(unknown) AS
161161
SELECT * FROM road WHERE thepath = $1;
162+
-- DML statements
163+
PREPARE q8 AS
164+
UPDATE tenk1 SET stringu1 = $2 WHERE unique1 = $1;
162165
SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements
163166
ORDER BY name;
164167
name | statement | parameter_types | result_types
@@ -177,7 +180,9 @@ SELECT name, statement, parameter_types, result_types FROM pg_prepared_statement
177180
| SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; | |
178181
q7 | PREPARE q7(unknown) AS +| {path} | {text,path}
179182
| SELECT * FROM road WHERE thepath = $1; | |
180-
(5 rows)
183+
q8 | PREPARE q8 AS +| {integer,name} |
184+
| UPDATE tenk1 SET stringu1 = $2 WHERE unique1 = $1; | |
185+
(6 rows)
181186

182187
-- test DEALLOCATE ALL;
183188
DEALLOCATE ALL;

‎src/test/regress/sql/prepare.sql

Copy file name to clipboardExpand all lines: src/test/regress/sql/prepare.sql
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ PREPARE q6 AS
7171
PREPARE q7(unknown) AS
7272
SELECT * FROM road WHERE thepath = $1;
7373

74+
-- DML statements
75+
PREPARE q8 AS
76+
UPDATE tenk1 SET stringu1 = $2 WHERE unique1 = $1;
77+
7478
SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements
7579
ORDER BY name;
7680

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.