Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit7cd9b13

Browse files
committed
Expose object name error fields in PL/pgSQL.
Specifically, permit attaching them to the error in RAISE and retrievingthem from a caught error in GET STACKED DIAGNOSTICS. RAISE enforcesnothing about the content of the fields; for its purposes, they are justadditional string fields. Consequently, clarify in the protocol andlibpq documentation that the usual relationships between error fields,like a schema name appearing wherever a table name appears, are notuniversal. This freedom has other applications; consider a FDWpropagating an error from an RDBMS having no schema support.Back-patch to 9.3, where core support for the error fields wasintroduced. This prevents the confusion of having a release where libpqexposes the fields and PL/pgSQL does not.Pavel Stehule, lexical revisions by Noah Misch.
1 parent69e4fd4 commit7cd9b13

File tree

10 files changed

+321
-49
lines changed

10 files changed

+321
-49
lines changed

‎doc/src/sgml/libpq.sgml

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2712,9 +2712,9 @@ char *PQresultErrorField(const PGresult *res, int fieldcode);
27122712
<term><symbol>PG_DIAG_TABLE_NAME</></term>
27132713
<listitem>
27142714
<para>
2715-
If the error was associated with a specific table, the name of
2716-
thetable. (When this field is present,the schema name field
2717-
provides the name of thetable's schema.)
2715+
If the error was associated with a specific table, the name of the
2716+
table. (Refer tothe schema name field for the name of the
2717+
table's schema.)
27182718
</para>
27192719
</listitem>
27202720
</varlistentry>
@@ -2723,9 +2723,9 @@ char *PQresultErrorField(const PGresult *res, int fieldcode);
27232723
<term><symbol>PG_DIAG_COLUMN_NAME</></term>
27242724
<listitem>
27252725
<para>
2726-
If the error was associated with a specific table column, the
2727-
nameof the column. (When this field is present, the schema
2728-
and table name fieldsidentify the table.)
2726+
If the error was associated with a specific table column, the name
2727+
of the column. (Refer to the schema and table name fields to
2728+
identify the table.)
27292729
</para>
27302730
</listitem>
27312731
</varlistentry>
@@ -2734,9 +2734,9 @@ char *PQresultErrorField(const PGresult *res, int fieldcode);
27342734
<term><symbol>PG_DIAG_DATATYPE_NAME</></term>
27352735
<listitem>
27362736
<para>
2737-
If the error was associated with a specific data type, the name
2738-
ofthe data type. (When this field is present, the schemaname
2739-
field provides the name ofthe data type's schema.)
2737+
If the error was associated with a specific data type, the name of
2738+
the data type. (Refer to the schema name field for thename of
2739+
the data type's schema.)
27402740
</para>
27412741
</listitem>
27422742
</varlistentry>
@@ -2745,11 +2745,11 @@ char *PQresultErrorField(const PGresult *res, int fieldcode);
27452745
<term><symbol>PG_DIAG_CONSTRAINT_NAME</></term>
27462746
<listitem>
27472747
<para>
2748-
If the error was associated with a specific constraint,
2749-
the nameof the constraint.The table or domain that the
2750-
constraint belongs to is reported using the fields listed
2751-
above. (For this purpose, indexes are treated as constraints,
2752-
even if they weren't created withconstraint syntax.)
2748+
If the error was associated with a specific constraint, the name
2749+
of the constraint.Refer to fields listed above for the
2750+
associated table or domain. (For this purpose, indexes are
2751+
treated as constraints, even if they weren't created with
2752+
constraint syntax.)
27532753
</para>
27542754
</listitem>
27552755
</varlistentry>
@@ -2787,9 +2787,14 @@ char *PQresultErrorField(const PGresult *res, int fieldcode);
27872787

27882788
<note>
27892789
<para>
2790-
The fields for schema name, table name, column name, data type
2791-
name, and constraint name are supplied only for a limited number
2792-
of error types; see <xref linkend="errcodes-appendix">.
2790+
The fields for schema name, table name, column name, data type name,
2791+
and constraint name are supplied only for a limited number of error
2792+
types; see <xref linkend="errcodes-appendix">. Do not assume that
2793+
the presence of any of these fields guarantees the presence of
2794+
another field. Core error sources observe the interrelationships
2795+
noted above, but user-defined functions may use these fields in other
2796+
ways. In the same vein, do not assume that these fields denote
2797+
contemporary objects in the current database.
27932798
</para>
27942799
</note>
27952800

‎doc/src/sgml/plpgsql.sgml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2664,11 +2664,36 @@ GET STACKED DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item<
26642664
<entry>text</entry>
26652665
<entry>the SQLSTATE error code of the exception</entry>
26662666
</row>
2667+
<row>
2668+
<entry><literal>COLUMN_NAME</literal></entry>
2669+
<entry>text</entry>
2670+
<entry>the name of column related to exception</entry>
2671+
</row>
2672+
<row>
2673+
<entry><literal>CONSTRAINT_NAME</literal></entry>
2674+
<entry>text</entry>
2675+
<entry>the name of constraint related to exception</entry>
2676+
</row>
2677+
<row>
2678+
<entry><literal>PG_DATATYPE_NAME</literal></entry>
2679+
<entry>text</entry>
2680+
<entry>the name of datatype related to exception</entry>
2681+
</row>
26672682
<row>
26682683
<entry><literal>MESSAGE_TEXT</literal></entry>
26692684
<entry>text</entry>
26702685
<entry>the text of the exception's primary message</entry>
26712686
</row>
2687+
<row>
2688+
<entry><literal>TABLE_NAME</literal></entry>
2689+
<entry>text</entry>
2690+
<entry>the name of table related to exception</entry>
2691+
</row>
2692+
<row>
2693+
<entry><literal>SCHEMA_NAME</literal></entry>
2694+
<entry>text</entry>
2695+
<entry>the name of schema related to exception</entry>
2696+
</row>
26722697
<row>
26732698
<entry><literal>PG_EXCEPTION_DETAIL</literal></entry>
26742699
<entry>text</entry>
@@ -3355,6 +3380,17 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id;
33553380
five-character SQLSTATE code.</para>
33563381
</listitem>
33573382
</varlistentry>
3383+
3384+
<varlistentry>
3385+
<term><literal>COLUMN</literal></term>
3386+
<term><literal>CONSTRAINT</literal></term>
3387+
<term><literal>DATATYPE</literal></term>
3388+
<term><literal>TABLE</literal></term>
3389+
<term><literal>SCHEMA</literal></term>
3390+
<listitem>
3391+
<para>Supplies the name of a related object.</para>
3392+
</listitem>
3393+
</varlistentry>
33583394
</variablelist>
33593395
</para>
33603396

‎doc/src/sgml/protocol.sgml

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4788,8 +4788,8 @@ message.
47884788
<listitem>
47894789
<para>
47904790
Table name: if the error was associated with a specific table, the
4791-
name of the table. (When this field is present,the schema name field
4792-
provides the name ofthe table's schema.)
4791+
name of the table. (Refer tothe schema name field for the name of
4792+
the table's schema.)
47934793
</para>
47944794
</listitem>
47954795
</varlistentry>
@@ -4801,8 +4801,8 @@ message.
48014801
<listitem>
48024802
<para>
48034803
Column name: if the error was associated with a specific table column,
4804-
the name of the column. (When this field is present,the schema and
4805-
table name fieldsidentify the table.)
4804+
the name of the column. (Refer tothe schema and table name fields to
4805+
identify the table.)
48064806
</para>
48074807
</listitem>
48084808
</varlistentry>
@@ -4814,8 +4814,8 @@ message.
48144814
<listitem>
48154815
<para>
48164816
Data type name: if the error was associated with a specific data type,
4817-
the name of the data type. (When this field is present, the schema
4818-
namefield provides the nameof the data type's schema.)
4817+
the name of the data type. (Refer to the schema name field for the
4818+
name of the data type's schema.)
48194819
</para>
48204820
</listitem>
48214821
</varlistentry>
@@ -4827,10 +4827,10 @@ message.
48274827
<listitem>
48284828
<para>
48294829
Constraint name: if the error was associated with a specific
4830-
constraint, the name of the constraint.The table or domain that the
4831-
constraint belongs to is reported using the fields listed above. (For
4832-
this purpose, indexes aretreated as constraints, even if they weren't
4833-
created with constraintsyntax.)
4830+
constraint, the name of the constraint.Refer to fields listed above
4831+
for the associated table or domain. (For this purpose, indexes are
4832+
treated as constraints, even if they weren't created with constraint
4833+
syntax.)
48344834
</para>
48354835
</listitem>
48364836
</varlistentry>
@@ -4876,7 +4876,12 @@ message.
48764876
<para>
48774877
The fields for schema name, table name, column name, data type name, and
48784878
constraint name are supplied only for a limited number of error types;
4879-
see <xref linkend="errcodes-appendix">.
4879+
see <xref linkend="errcodes-appendix">. Frontends should not assume that
4880+
the presence of any of these fields guarantees the presence of another
4881+
field. Core error sources observe the interrelationships noted above, but
4882+
user-defined functions may use these fields in other ways. In the same
4883+
vein, clients should not assume that these fields denote contemporary
4884+
objects in the current database.
48804885
</para>
48814886
</note>
48824887

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,11 +1569,36 @@ exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt)
15691569
unpack_sql_state(estate->cur_error->sqlerrcode));
15701570
break;
15711571

1572+
casePLPGSQL_GETDIAG_COLUMN_NAME:
1573+
exec_assign_c_string(estate,var,
1574+
estate->cur_error->column_name);
1575+
break;
1576+
1577+
casePLPGSQL_GETDIAG_CONSTRAINT_NAME:
1578+
exec_assign_c_string(estate,var,
1579+
estate->cur_error->constraint_name);
1580+
break;
1581+
1582+
casePLPGSQL_GETDIAG_DATATYPE_NAME:
1583+
exec_assign_c_string(estate,var,
1584+
estate->cur_error->datatype_name);
1585+
break;
1586+
15721587
casePLPGSQL_GETDIAG_MESSAGE_TEXT:
15731588
exec_assign_c_string(estate,var,
15741589
estate->cur_error->message);
15751590
break;
15761591

1592+
casePLPGSQL_GETDIAG_TABLE_NAME:
1593+
exec_assign_c_string(estate,var,
1594+
estate->cur_error->table_name);
1595+
break;
1596+
1597+
casePLPGSQL_GETDIAG_SCHEMA_NAME:
1598+
exec_assign_c_string(estate,var,
1599+
estate->cur_error->schema_name);
1600+
break;
1601+
15771602
default:
15781603
elog(ERROR,"unrecognized diagnostic item kind: %d",
15791604
diag_item->kind);
@@ -2799,6 +2824,16 @@ exec_init_tuple_store(PLpgSQL_execstate *estate)
27992824
estate->rettupdesc=rsi->expectedDesc;
28002825
}
28012826

2827+
#defineSET_RAISE_OPTION_TEXT(opt,name) \
2828+
do { \
2829+
if (opt) \
2830+
ereport(ERROR, \
2831+
(errcode(ERRCODE_SYNTAX_ERROR), \
2832+
errmsg("RAISE option already specified: %s", \
2833+
name))); \
2834+
opt = pstrdup(extval); \
2835+
} while (0)
2836+
28022837
/* ----------
28032838
* exec_stmt_raiseBuild a message and throw it with elog()
28042839
* ----------
@@ -2811,6 +2846,11 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
28112846
char*err_message=NULL;
28122847
char*err_detail=NULL;
28132848
char*err_hint=NULL;
2849+
char*err_column=NULL;
2850+
char*err_constraint=NULL;
2851+
char*err_datatype=NULL;
2852+
char*err_table=NULL;
2853+
char*err_schema=NULL;
28142854
ListCell*lc;
28152855

28162856
/* RAISE with no parameters: re-throw current exception */
@@ -2927,28 +2967,28 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
29272967
condname=pstrdup(extval);
29282968
break;
29292969
casePLPGSQL_RAISEOPTION_MESSAGE:
2930-
if (err_message)
2931-
ereport(ERROR,
2932-
(errcode(ERRCODE_SYNTAX_ERROR),
2933-
errmsg("RAISE option already specified: %s",
2934-
"MESSAGE")));
2935-
err_message=pstrdup(extval);
2970+
SET_RAISE_OPTION_TEXT(err_message,"MESSAGE");
29362971
break;
29372972
casePLPGSQL_RAISEOPTION_DETAIL:
2938-
if (err_detail)
2939-
ereport(ERROR,
2940-
(errcode(ERRCODE_SYNTAX_ERROR),
2941-
errmsg("RAISE option already specified: %s",
2942-
"DETAIL")));
2943-
err_detail=pstrdup(extval);
2973+
SET_RAISE_OPTION_TEXT(err_detail,"DETAIL");
29442974
break;
29452975
casePLPGSQL_RAISEOPTION_HINT:
2946-
if (err_hint)
2947-
ereport(ERROR,
2948-
(errcode(ERRCODE_SYNTAX_ERROR),
2949-
errmsg("RAISE option already specified: %s",
2950-
"HINT")));
2951-
err_hint=pstrdup(extval);
2976+
SET_RAISE_OPTION_TEXT(err_hint,"HINT");
2977+
break;
2978+
casePLPGSQL_RAISEOPTION_COLUMN:
2979+
SET_RAISE_OPTION_TEXT(err_column,"COLUMN");
2980+
break;
2981+
casePLPGSQL_RAISEOPTION_CONSTRAINT:
2982+
SET_RAISE_OPTION_TEXT(err_constraint,"CONSTRAINT");
2983+
break;
2984+
casePLPGSQL_RAISEOPTION_DATATYPE:
2985+
SET_RAISE_OPTION_TEXT(err_datatype,"DATATYPE");
2986+
break;
2987+
casePLPGSQL_RAISEOPTION_TABLE:
2988+
SET_RAISE_OPTION_TEXT(err_table,"TABLE");
2989+
break;
2990+
casePLPGSQL_RAISEOPTION_SCHEMA:
2991+
SET_RAISE_OPTION_TEXT(err_schema,"SCHEMA");
29522992
break;
29532993
default:
29542994
elog(ERROR,"unrecognized raise option: %d",opt->opt_type);
@@ -2982,7 +3022,17 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
29823022
(err_code ?errcode(err_code) :0,
29833023
errmsg_internal("%s",err_message),
29843024
(err_detail!=NULL) ?errdetail_internal("%s",err_detail) :0,
2985-
(err_hint!=NULL) ?errhint("%s",err_hint) :0));
3025+
(err_hint!=NULL) ?errhint("%s",err_hint) :0,
3026+
(err_column!=NULL) ?
3027+
err_generic_string(PG_DIAG_COLUMN_NAME,err_column) :0,
3028+
(err_constraint!=NULL) ?
3029+
err_generic_string(PG_DIAG_CONSTRAINT_NAME,err_constraint) :0,
3030+
(err_datatype!=NULL) ?
3031+
err_generic_string(PG_DIAG_DATATYPE_NAME,err_datatype) :0,
3032+
(err_table!=NULL) ?
3033+
err_generic_string(PG_DIAG_TABLE_NAME,err_table) :0,
3034+
(err_schema!=NULL) ?
3035+
err_generic_string(PG_DIAG_SCHEMA_NAME,err_schema) :0));
29863036

29873037
estate->err_text=NULL;/* un-suppress... */
29883038

@@ -2994,6 +3044,16 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
29943044
pfree(err_detail);
29953045
if (err_hint!=NULL)
29963046
pfree(err_hint);
3047+
if (err_column!=NULL)
3048+
pfree(err_column);
3049+
if (err_constraint!=NULL)
3050+
pfree(err_constraint);
3051+
if (err_datatype!=NULL)
3052+
pfree(err_datatype);
3053+
if (err_table!=NULL)
3054+
pfree(err_table);
3055+
if (err_schema!=NULL)
3056+
pfree(err_schema);
29973057

29983058
returnPLPGSQL_RC_OK;
29993059
}

‎src/pl/plpgsql/src/pl_funcs.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,18 @@ plpgsql_getdiag_kindname(int kind)
285285
return"PG_EXCEPTION_HINT";
286286
casePLPGSQL_GETDIAG_RETURNED_SQLSTATE:
287287
return"RETURNED_SQLSTATE";
288+
casePLPGSQL_GETDIAG_COLUMN_NAME:
289+
return"COLUMN_NAME";
290+
casePLPGSQL_GETDIAG_CONSTRAINT_NAME:
291+
return"CONSTRAINT_NAME";
292+
casePLPGSQL_GETDIAG_DATATYPE_NAME:
293+
return"PG_DATATYPE_NAME";
288294
casePLPGSQL_GETDIAG_MESSAGE_TEXT:
289295
return"MESSAGE_TEXT";
296+
casePLPGSQL_GETDIAG_TABLE_NAME:
297+
return"TABLE_NAME";
298+
casePLPGSQL_GETDIAG_SCHEMA_NAME:
299+
return"SCHEMA_NAME";
290300
}
291301

292302
return"unknown";
@@ -1317,6 +1327,21 @@ dump_raise(PLpgSQL_stmt_raise *stmt)
13171327
casePLPGSQL_RAISEOPTION_HINT:
13181328
printf(" HINT = ");
13191329
break;
1330+
casePLPGSQL_RAISEOPTION_COLUMN:
1331+
printf(" COLUMN = ");
1332+
break;
1333+
casePLPGSQL_RAISEOPTION_CONSTRAINT:
1334+
printf(" CONSTRAINT = ");
1335+
break;
1336+
casePLPGSQL_RAISEOPTION_DATATYPE:
1337+
printf(" DATATYPE = ");
1338+
break;
1339+
casePLPGSQL_RAISEOPTION_TABLE:
1340+
printf(" TABLE = ");
1341+
break;
1342+
casePLPGSQL_RAISEOPTION_SCHEMA:
1343+
printf(" SCHEMA = ");
1344+
break;
13201345
}
13211346
dump_expr(opt->expr);
13221347
printf("\n");

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp