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

Commitc0241b9

Browse files
committed
When an ERROR happens on a dblink remote connection, take
pains to pass the ERROR message components locally, includingusing the passed SQLSTATE. Also wrap the passed info in anappropriate CONTEXT message. Addresses complaint by HenryCombrinck. Joe Conway, with much good advice from Tom Lane.
1 parent0a8f6b7 commitc0241b9

File tree

2 files changed

+95
-94
lines changed

2 files changed

+95
-94
lines changed

‎contrib/dblink/dblink.c

Lines changed: 71 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Darko Prenosil <Darko.Prenosil@finteh.hr>
99
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
1010
*
11-
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.73 2008/04/04 17:02:56 momjian Exp $
11+
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.74 2008/07/03 03:56:57 joe Exp $
1212
* Copyright (c) 2001-2008, PostgreSQL Global Development Group
1313
* ALL RIGHTS RESERVED;
1414
*
@@ -94,6 +94,7 @@ static HeapTuple get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 p
9494
staticOidget_relid_from_relname(text*relname_text);
9595
staticchar*generate_relation_name(Oidrelid);
9696
staticvoiddblink_security_check(PGconn*conn,remoteConn*rconn);
97+
staticvoiddblink_res_error(constchar*conname,PGresult*res,constchar*dblink_context_msg,boolfail);
9798

9899
/* Global */
99100
staticremoteConn*pconn=NULL;
@@ -125,34 +126,20 @@ typedef struct remoteConnHashEnt
125126
} \
126127
} while (0)
127128

128-
#defineDBLINK_RES_INTERNALERROR(p2) \
129-
do { \
130-
msg = pstrdup(PQerrorMessage(conn)); \
131-
if (res) \
132-
PQclear(res); \
133-
elog(ERROR, "%s: %s", p2, msg); \
134-
} while (0)
135-
136-
#defineDBLINK_RES_ERROR(p2) \
129+
#definexpstrdup(var_c,var_) \
137130
do { \
138-
msg = pstrdup(PQerrorMessage(conn)); \
139-
if (res) \
140-
PQclear(res); \
141-
ereport(ERROR, \
142-
(errcode(ERRCODE_SYNTAX_ERROR), \
143-
errmsg("%s", p2), \
144-
errdetail("%s", msg))); \
131+
if (var_ != NULL) \
132+
var_c = pstrdup(var_); \
133+
else \
134+
var_c = NULL; \
145135
} while (0)
146136

147-
#defineDBLINK_RES_ERROR_AS_NOTICE(p2) \
137+
#defineDBLINK_RES_INTERNALERROR(p2) \
148138
do { \
149139
msg = pstrdup(PQerrorMessage(conn)); \
150140
if (res) \
151141
PQclear(res); \
152-
ereport(NOTICE, \
153-
(errcode(ERRCODE_SYNTAX_ERROR), \
154-
errmsg("%s", p2), \
155-
errdetail("%s", msg))); \
142+
elog(ERROR, "%s: %s", p2, msg); \
156143
} while (0)
157144

158145
#defineDBLINK_CONN_NOT_AVAIL \
@@ -396,13 +383,8 @@ dblink_open(PG_FUNCTION_ARGS)
396383
res=PQexec(conn,buf.data);
397384
if (!res||PQresultStatus(res)!=PGRES_COMMAND_OK)
398385
{
399-
if (fail)
400-
DBLINK_RES_ERROR("sql error");
401-
else
402-
{
403-
DBLINK_RES_ERROR_AS_NOTICE("sql error");
404-
PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
405-
}
386+
dblink_res_error(conname,res,"could not open cursor",fail);
387+
PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
406388
}
407389

408390
PQclear(res);
@@ -470,13 +452,8 @@ dblink_close(PG_FUNCTION_ARGS)
470452
res=PQexec(conn,buf.data);
471453
if (!res||PQresultStatus(res)!=PGRES_COMMAND_OK)
472454
{
473-
if (fail)
474-
DBLINK_RES_ERROR("sql error");
475-
else
476-
{
477-
DBLINK_RES_ERROR_AS_NOTICE("sql error");
478-
PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
479-
}
455+
dblink_res_error(conname,res,"could not close cursor",fail);
456+
PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
480457
}
481458

482459
PQclear(res);
@@ -513,7 +490,6 @@ dblink_fetch(PG_FUNCTION_ARGS)
513490
intcall_cntr;
514491
intmax_calls;
515492
AttInMetadata*attinmeta;
516-
char*msg;
517493
PGresult*res=NULL;
518494
MemoryContextoldcontext;
519495
char*conname=NULL;
@@ -590,13 +566,8 @@ dblink_fetch(PG_FUNCTION_ARGS)
590566
(PQresultStatus(res)!=PGRES_COMMAND_OK&&
591567
PQresultStatus(res)!=PGRES_TUPLES_OK))
592568
{
593-
if (fail)
594-
DBLINK_RES_ERROR("sql error");
595-
else
596-
{
597-
DBLINK_RES_ERROR_AS_NOTICE("sql error");
598-
SRF_RETURN_DONE(funcctx);
599-
}
569+
dblink_res_error(conname,res,"could not fetch from cursor",fail);
570+
SRF_RETURN_DONE(funcctx);
600571
}
601572
elseif (PQresultStatus(res)==PGRES_COMMAND_OK)
602573
{
@@ -846,15 +817,10 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
846817
(PQresultStatus(res)!=PGRES_COMMAND_OK&&
847818
PQresultStatus(res)!=PGRES_TUPLES_OK))
848819
{
849-
if (fail)
850-
DBLINK_RES_ERROR("sql error");
851-
else
852-
{
853-
DBLINK_RES_ERROR_AS_NOTICE("sql error");
854-
if (freeconn)
855-
PQfinish(conn);
856-
SRF_RETURN_DONE(funcctx);
857-
}
820+
dblink_res_error(conname,res,"could not execute query",fail);
821+
if (freeconn)
822+
PQfinish(conn);
823+
SRF_RETURN_DONE(funcctx);
858824
}
859825

860826
if (PQresultStatus(res)==PGRES_COMMAND_OK)
@@ -1180,10 +1146,7 @@ dblink_exec(PG_FUNCTION_ARGS)
11801146
(PQresultStatus(res)!=PGRES_COMMAND_OK&&
11811147
PQresultStatus(res)!=PGRES_TUPLES_OK))
11821148
{
1183-
if (fail)
1184-
DBLINK_RES_ERROR("sql error");
1185-
else
1186-
DBLINK_RES_ERROR_AS_NOTICE("sql error");
1149+
dblink_res_error(conname,res,"could not execute command",fail);
11871150

11881151
/* need a tuple descriptor representing one TEXT column */
11891152
tupdesc=CreateTemplateTupleDesc(1, false);
@@ -1195,7 +1158,6 @@ dblink_exec(PG_FUNCTION_ARGS)
11951158
* result tuple
11961159
*/
11971160
sql_cmd_status=cstring_to_text("ERROR");
1198-
11991161
}
12001162
elseif (PQresultStatus(res)==PGRES_COMMAND_OK)
12011163
{
@@ -2288,3 +2250,54 @@ dblink_security_check(PGconn *conn, remoteConn *rconn)
22882250
}
22892251
}
22902252
}
2253+
2254+
staticvoid
2255+
dblink_res_error(constchar*conname,PGresult*res,constchar*dblink_context_msg,boolfail)
2256+
{
2257+
intlevel;
2258+
char*pg_diag_sqlstate=PQresultErrorField(res,PG_DIAG_SQLSTATE);
2259+
char*pg_diag_message_primary=PQresultErrorField(res,PG_DIAG_MESSAGE_PRIMARY);
2260+
char*pg_diag_message_detail=PQresultErrorField(res,PG_DIAG_MESSAGE_DETAIL);
2261+
char*pg_diag_message_hint=PQresultErrorField(res,PG_DIAG_MESSAGE_HINT);
2262+
char*pg_diag_context=PQresultErrorField(res,PG_DIAG_CONTEXT);
2263+
intsqlstate;
2264+
char*message_primary;
2265+
char*message_detail;
2266+
char*message_hint;
2267+
char*message_context;
2268+
constchar*dblink_context_conname="unnamed";
2269+
2270+
if (fail)
2271+
level=ERROR;
2272+
else
2273+
level=NOTICE;
2274+
2275+
if (pg_diag_sqlstate)
2276+
sqlstate=MAKE_SQLSTATE(pg_diag_sqlstate[0],
2277+
pg_diag_sqlstate[1],
2278+
pg_diag_sqlstate[2],
2279+
pg_diag_sqlstate[3],
2280+
pg_diag_sqlstate[4]);
2281+
else
2282+
sqlstate=ERRCODE_CONNECTION_FAILURE;
2283+
2284+
xpstrdup(message_primary,pg_diag_message_primary);
2285+
xpstrdup(message_detail,pg_diag_message_detail);
2286+
xpstrdup(message_hint,pg_diag_message_hint);
2287+
xpstrdup(message_context,pg_diag_context);
2288+
2289+
if (res)
2290+
PQclear(res);
2291+
2292+
if (conname)
2293+
dblink_context_conname=conname;
2294+
2295+
ereport(level,
2296+
(errcode(sqlstate),
2297+
message_primary ?errmsg("%s",message_primary) :errmsg("unknown error"),
2298+
message_detail ?errdetail("%s",message_detail) :0,
2299+
message_hint ?errhint("%s",message_hint) :0,
2300+
message_context ?errcontext("%s",message_context) :0,
2301+
errcontext("Error occurred on dblink connection named \"%s\": %s.",
2302+
dblink_context_conname,dblink_context_msg)));
2303+
}

‎contrib/dblink/expected/dblink.out

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,8 @@ WHERE t.a > 7;
125125

126126
-- open a cursor with bad SQL and fail_on_error set to false
127127
SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foobar',false);
128-
NOTICE: sql error
129-
DETAIL: ERROR: relation "foobar" does not exist
130-
128+
NOTICE: relation "foobar" does not exist
129+
CONTEXT: Error occurred on dblink connection named "unnamed": could not open cursor.
131130
dblink_open
132131
-------------
133132
ERROR
@@ -194,9 +193,8 @@ FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
194193
-- intentionally botch a fetch
195194
SELECT *
196195
FROM dblink_fetch('rmt_foobar_cursor',4,false) AS t(a int, b text, c text[]);
197-
NOTICE: sql error
198-
DETAIL: ERROR: cursor "rmt_foobar_cursor" does not exist
199-
196+
NOTICE: cursor "rmt_foobar_cursor" does not exist
197+
CONTEXT: Error occurred on dblink connection named "unnamed": could not fetch from cursor.
200198
a | b | c
201199
---+---+---
202200
(0 rows)
@@ -210,9 +208,8 @@ SELECT dblink_exec('ABORT');
210208

211209
-- close the wrong cursor
212210
SELECT dblink_close('rmt_foobar_cursor',false);
213-
NOTICE: sql error
214-
DETAIL: ERROR: cursor "rmt_foobar_cursor" does not exist
215-
211+
NOTICE: cursor "rmt_foobar_cursor" does not exist
212+
CONTEXT: Error occurred on dblink connection named "unnamed": could not close cursor.
216213
dblink_close
217214
--------------
218215
ERROR
@@ -221,15 +218,13 @@ DETAIL: ERROR: cursor "rmt_foobar_cursor" does not exist
221218
-- should generate 'cursor "rmt_foo_cursor" not found' error
222219
SELECT *
223220
FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
224-
ERROR: sql error
225-
DETAIL: ERROR: cursor "rmt_foo_cursor" does not exist
226-
221+
ERROR: cursor "rmt_foo_cursor" does not exist
222+
CONTEXT: Error occurred on dblink connection named "unnamed": could not fetch from cursor.
227223
-- this time, 'cursor "rmt_foo_cursor" not found' as a notice
228224
SELECT *
229225
FROM dblink_fetch('rmt_foo_cursor',4,false) AS t(a int, b text, c text[]);
230-
NOTICE: sql error
231-
DETAIL: ERROR: cursor "rmt_foo_cursor" does not exist
232-
226+
NOTICE: cursor "rmt_foo_cursor" does not exist
227+
CONTEXT: Error occurred on dblink connection named "unnamed": could not fetch from cursor.
233228
a | b | c
234229
---+---+---
235230
(0 rows)
@@ -291,9 +286,8 @@ FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]);
291286
-- bad remote select
292287
SELECT *
293288
FROM dblink('SELECT * FROM foobar',false) AS t(a int, b text, c text[]);
294-
NOTICE: sql error
295-
DETAIL: ERROR: relation "foobar" does not exist
296-
289+
NOTICE: relation "foobar" does not exist
290+
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute query.
297291
a | b | c
298292
---+---+---
299293
(0 rows)
@@ -316,9 +310,8 @@ WHERE a = 11;
316310

317311
-- botch a change to some other data
318312
SELECT dblink_exec('UPDATE foobar SET f3[2] = ''b99'' WHERE f1 = 11',false);
319-
NOTICE: sql error
320-
DETAIL: ERROR: relation "foobar" does not exist
321-
313+
NOTICE: relation "foobar" does not exist
314+
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute command.
322315
dblink_exec
323316
-------------
324317
ERROR
@@ -378,9 +371,8 @@ WHERE t.a > 7;
378371
SELECT *
379372
FROM dblink('myconn','SELECT * FROM foobar',false) AS t(a int, b text, c text[])
380373
WHERE t.a > 7;
381-
NOTICE: sql error
382-
DETAIL: ERROR: relation "foobar" does not exist
383-
374+
NOTICE: relation "foobar" does not exist
375+
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute query.
384376
a | b | c
385377
---+---+---
386378
(0 rows)
@@ -416,9 +408,8 @@ SELECT dblink_disconnect('myconn2');
416408

417409
-- open a cursor incorrectly
418410
SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foobar',false);
419-
NOTICE: sql error
420-
DETAIL: ERROR: relation "foobar" does not exist
421-
411+
NOTICE: relation "foobar" does not exist
412+
CONTEXT: Error occurred on dblink connection named "myconn": could not open cursor.
422413
dblink_open
423414
-------------
424415
ERROR
@@ -503,9 +494,8 @@ SELECT dblink_close('myconn','rmt_foo_cursor');
503494

504495
-- this should fail because there is no open transaction
505496
SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
506-
ERROR: sql error
507-
DETAIL: ERROR: DECLARE CURSOR can only be used in transaction blocks
508-
497+
ERROR: DECLARE CURSOR can only be used in transaction blocks
498+
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute command.
509499
-- reset remote transaction state
510500
SELECT dblink_exec('myconn','ABORT');
511501
dblink_exec
@@ -554,9 +544,8 @@ FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
554544
-- fetch some data incorrectly
555545
SELECT *
556546
FROM dblink_fetch('myconn','rmt_foobar_cursor',4,false) AS t(a int, b text, c text[]);
557-
NOTICE: sql error
558-
DETAIL: ERROR: cursor "rmt_foobar_cursor" does not exist
559-
547+
NOTICE: cursor "rmt_foobar_cursor" does not exist
548+
CONTEXT: Error occurred on dblink connection named "myconn": could not fetch from cursor.
560549
a | b | c
561550
---+---+---
562551
(0 rows)
@@ -571,9 +560,8 @@ SELECT dblink_exec('myconn','ABORT');
571560
-- should generate 'cursor "rmt_foo_cursor" not found' error
572561
SELECT *
573562
FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
574-
ERROR: sql error
575-
DETAIL: ERROR: cursor "rmt_foo_cursor" does not exist
576-
563+
ERROR: cursor "rmt_foo_cursor" does not exist
564+
CONTEXT: Error occurred on dblink connection named "myconn": could not fetch from cursor.
577565
-- close the named persistent connection
578566
SELECT dblink_disconnect('myconn');
579567
dblink_disconnect

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp