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

Commite3161b2

Browse files
committed
Add libpq support for recreating an error message with different verbosity.
Often, upon getting an unexpected error in psql, one's first wish is thatthe verbosity setting had been higher; for example, to be able to see theschema-name field or the server code location info. Up to now the only wayhas been to adjust the VERBOSITY variable and repeat the failing query.That's a pain, and it doesn't work if the error isn't reproducible.This commit adds support in libpq for regenerating the error message foran existing error PGresult at any desired verbosity level. This is almostjust a matter of refactoring the existing code into a subroutine, but thereis one bit of possibly-needed information that was not getting put intoPGresults: the text of the last query sent to the server. We must add thatstring to the contents of an error PGresult. But we only need to save itif it might be used, which with the existing error-formatting code onlyhappens if there is a PG_DIAG_STATEMENT_POSITION error field, which isprobably pretty rare for errors in production situations. So really theoverhead when the feature isn't used should be negligible.Alex Shulgin, reviewed by Daniel Vérité, some improvements by me
1 parent5a5b917 commite3161b2

File tree

6 files changed

+217
-77
lines changed

6 files changed

+217
-77
lines changed

‎doc/src/sgml/libpq.sgml

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2691,6 +2691,48 @@ char *PQresultErrorMessage(const PGresult *res);
26912691
</listitem>
26922692
</varlistentry>
26932693

2694+
<varlistentry id="libpq-pqresultverboseerrormessage">
2695+
<term>
2696+
<function>PQresultVerboseErrorMessage</function>
2697+
<indexterm>
2698+
<primary>PQresultVerboseErrorMessage</primary>
2699+
</indexterm>
2700+
</term>
2701+
2702+
<listitem>
2703+
<para>
2704+
Returns a reformatted version of the error message associated with
2705+
a <structname>PGresult</> object.
2706+
<synopsis>
2707+
char *PQresultVerboseErrorMessage(const PGresult *res,
2708+
PGVerbosity verbosity,
2709+
PGContextVisibility show_context);
2710+
</synopsis>
2711+
In some situations a client might wish to obtain a more detailed
2712+
version of a previously-reported error.
2713+
<function>PQresultVerboseErrorMessage</function> addresses this need
2714+
by computing the message that would have been produced
2715+
by <function>PQresultErrorMessage</function> if the specified
2716+
verbosity settings had been in effect for the connection when the
2717+
given <structname>PGresult</> was generated. If
2718+
the <structname>PGresult</> is not an error result,
2719+
<quote>PGresult is not an error result</> is reported instead.
2720+
The returned string includes a trailing newline.
2721+
</para>
2722+
2723+
<para>
2724+
Unlike most other functions for extracting data from
2725+
a <structname>PGresult</>, the result of this function is a freshly
2726+
allocated string. The caller must free it
2727+
using <function>PQfreemem()</> when the string is no longer needed.
2728+
</para>
2729+
2730+
<para>
2731+
A NULL return is possible if there is insufficient memory.
2732+
</para>
2733+
</listitem>
2734+
</varlistentry>
2735+
26942736
<varlistentry id="libpq-pqresulterrorfield">
26952737
<term><function>PQresultErrorField</function><indexterm><primary>PQresultErrorField</></></term>
26962738
<listitem>
@@ -5582,6 +5624,8 @@ PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
55825624
mode includes all available fields. Changing the verbosity does not
55835625
affect the messages available from already-existing
55845626
<structname>PGresult</> objects, only subsequently-created ones.
5627+
(But see <function>PQresultVerboseErrorMessage</function> if you
5628+
want to print a previous error with a different verbosity.)
55855629
</para>
55865630
</listitem>
55875631
</varlistentry>
@@ -5622,6 +5666,8 @@ PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibilit
56225666
affect the messages available from
56235667
already-existing <structname>PGresult</> objects, only
56245668
subsequently-created ones.
5669+
(But see <function>PQresultVerboseErrorMessage</function> if you
5670+
want to print a previous error with a different display mode.)
56255671
</para>
56265672
</listitem>
56275673
</varlistentry>
@@ -6089,8 +6135,9 @@ PQsetNoticeProcessor(PGconn *conn,
60896135
receiver function is called. It is passed the message in the form of
60906136
a <symbol>PGRES_NONFATAL_ERROR</symbol>
60916137
<structname>PGresult</structname>. (This allows the receiver to extract
6092-
individual fields using <function>PQresultErrorField</>, or the complete
6093-
preformatted message using <function>PQresultErrorMessage</>.) The same
6138+
individual fields using <function>PQresultErrorField</>, or obtain a
6139+
complete preformatted message using <function>PQresultErrorMessage</>
6140+
or <function>PQresultVerboseErrorMessage</>.) The same
60946141
void pointer passed to <function>PQsetNoticeReceiver</function> is also
60956142
passed. (This pointer can be used to access application-specific state
60966143
if needed.)

‎src/interfaces/libpq/exports.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,4 @@ PQsslStruct 167
170170
PQsslAttributeNames 168
171171
PQsslAttribute 169
172172
PQsetErrorContextVisibility 170
173+
PQresultVerboseErrorMessage 171

‎src/interfaces/libpq/fe-exec.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
159159
result->nEvents=0;
160160
result->errMsg=NULL;
161161
result->errFields=NULL;
162+
result->errQuery=NULL;
162163
result->null_field[0]='\0';
163164
result->curBlock=NULL;
164165
result->curOffset=0;
@@ -2598,6 +2599,44 @@ PQresultErrorMessage(const PGresult *res)
25982599
returnres->errMsg;
25992600
}
26002601

2602+
char*
2603+
PQresultVerboseErrorMessage(constPGresult*res,
2604+
PGVerbosityverbosity,
2605+
PGContextVisibilityshow_context)
2606+
{
2607+
PQExpBufferDataworkBuf;
2608+
2609+
/*
2610+
* Because the caller is expected to free the result string, we must
2611+
* strdup any constant result. We use plain strdup and document that
2612+
* callers should expect NULL if out-of-memory.
2613+
*/
2614+
if (!res||
2615+
(res->resultStatus!=PGRES_FATAL_ERROR&&
2616+
res->resultStatus!=PGRES_NONFATAL_ERROR))
2617+
returnstrdup(libpq_gettext("PGresult is not an error result\n"));
2618+
2619+
initPQExpBuffer(&workBuf);
2620+
2621+
/*
2622+
* Currently, we pass this off to fe-protocol3.c in all cases; it will
2623+
* behave reasonably sanely with an error reported by fe-protocol2.c as
2624+
* well. If necessary, we could record the protocol version in PGresults
2625+
* so as to be able to invoke a version-specific message formatter, but
2626+
* for now there's no need.
2627+
*/
2628+
pqBuildErrorMessage3(&workBuf,res,verbosity,show_context);
2629+
2630+
/* If insufficient memory to format the message, fail cleanly */
2631+
if (PQExpBufferDataBroken(workBuf))
2632+
{
2633+
termPQExpBuffer(&workBuf);
2634+
returnstrdup(libpq_gettext("out of memory\n"));
2635+
}
2636+
2637+
returnworkBuf.data;
2638+
}
2639+
26012640
char*
26022641
PQresultErrorField(constPGresult*res,intfieldcode)
26032642
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp