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

Commit 6ffff0f

Browse 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

File tree

4 files changed

+26
-7
lines changed

4 files changed

+26
-7
lines changed

doc/src/sgml/catalogs.sgml

+2
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

+14-6
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

+6-1
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

+4
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)