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

Commitbd2e68d

Browse files
committed
Avoid doing catalog lookups in postgres_fdw's conversion_error_callback.
As in50371df, this is a bad idea since the callback can't reallyknow what error is being thrown and thus whether or not it is safeto attempt catalog accesses. Rather than pushing said accesses intothe mainline code where they'd usually be a waste of cycles, we canlook at the query's rangetable instead.This change does mean that we'll be printing query aliases (if anywere used) rather than the table or column's true name. But thatdoesn't seem like a bad thing: it's certainly a more useful definitionin self-join cases, for instance. In any case, it seems unlikely thatany applications would be depending on this detail, so it seems safeto change.Patch by me. Original complaint by Andres Freund; Bharath Rupireddynoted the connection to conversion_error_callback.Discussion:https://postgr.es/m/20210106020229.ne5xnuu6wlondjpe@alap3.anarazel.de
1 parenteda3b45 commitbd2e68d

File tree

3 files changed

+49
-51
lines changed

3 files changed

+49
-51
lines changed

‎contrib/postgres_fdw/expected/postgres_fdw.out‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4035,15 +4035,17 @@ DROP FUNCTION f_test(int);
40354035
-- conversion error
40364036
-- ===================================================================
40374037
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int;
4038-
SELECT * FROM ft1 WHEREc1 = 1; -- ERROR
4038+
SELECT * FROM ft1ftx(x1,x2,x3,x4,x5,x6,x7,x8)WHEREx1 = 1; -- ERROR
40394039
ERROR: invalid input syntax for type integer: "foo"
4040-
CONTEXT: column "c8" of foreign table "ft1"
4041-
SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR
4040+
CONTEXT: column "x8" of foreign table "ftx"
4041+
SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
4042+
WHERE ftx.x1 = ft2.c1 AND ftx.x1 = 1; -- ERROR
40424043
ERROR: invalid input syntax for type integer: "foo"
4043-
CONTEXT: column "c8" of foreign table "ft1"
4044-
SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR
4044+
CONTEXT: column "x8" of foreign table "ftx"
4045+
SELECT ftx.x1, ft2.c2, ftx FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
4046+
WHERE ftx.x1 = ft2.c1 AND ftx.x1 = 1; -- ERROR
40454047
ERROR: invalid input syntax for type integer: "foo"
4046-
CONTEXT: whole-row reference to foreign table "ft1"
4048+
CONTEXT: whole-row reference to foreign table "ftx"
40474049
SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR
40484050
ERROR: invalid input syntax for type integer: "foo"
40494051
CONTEXT: processing expression at position 2 in select list

‎contrib/postgres_fdw/postgres_fdw.c‎

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -284,16 +284,8 @@ typedef struct
284284
*/
285285
typedefstructConversionLocation
286286
{
287-
Relationrel;/* foreign table's relcache entry. */
288287
AttrNumbercur_attno;/* attribute number being processed, or 0 */
289-
290-
/*
291-
* In case of foreign join push down, fdw_scan_tlist is used to identify
292-
* the Var node corresponding to the error location and
293-
* fsstate->ss.ps.state gives access to the RTEs of corresponding relation
294-
* to get the relation name and attribute name.
295-
*/
296-
ForeignScanState*fsstate;
288+
ForeignScanState*fsstate;/* plan node being processed */
297289
}ConversionLocation;
298290

299291
/* Callback argument for ec_member_matches_foreign */
@@ -6317,7 +6309,6 @@ make_tuple_from_result_row(PGresult *res,
63176309
/*
63186310
* Set up and install callback to report where conversion error occurs.
63196311
*/
6320-
errpos.rel=rel;
63216312
errpos.cur_attno=0;
63226313
errpos.fsstate=fsstate;
63236314
errcallback.callback=conversion_error_callback;
@@ -6420,70 +6411,73 @@ make_tuple_from_result_row(PGresult *res,
64206411
/*
64216412
* Callback function which is called when error occurs during column value
64226413
* conversion. Print names of column and relation.
6414+
*
6415+
* Note that this function mustn't do any catalog lookups, since we are in
6416+
* an already-failed transaction. Fortunately, we can get the needed info
6417+
* from the query's rangetable instead.
64236418
*/
64246419
staticvoid
64256420
conversion_error_callback(void*arg)
64266421
{
6422+
ConversionLocation*errpos= (ConversionLocation*)arg;
6423+
ForeignScanState*fsstate=errpos->fsstate;
6424+
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
6425+
intvarno=0;
6426+
AttrNumbercolno=0;
64276427
constchar*attname=NULL;
64286428
constchar*relname=NULL;
64296429
boolis_wholerow= false;
6430-
ConversionLocation*errpos= (ConversionLocation*)arg;
64316430

6432-
if (errpos->rel)
6431+
if (fsplan->scan.scanrelid>0)
64336432
{
64346433
/* error occurred in a scan against a foreign table */
6435-
TupleDesctupdesc=RelationGetDescr(errpos->rel);
6436-
Form_pg_attributeattr=TupleDescAttr(tupdesc,errpos->cur_attno-1);
6437-
6438-
if (errpos->cur_attno>0&&errpos->cur_attno <=tupdesc->natts)
6439-
attname=NameStr(attr->attname);
6440-
elseif (errpos->cur_attno==SelfItemPointerAttributeNumber)
6441-
attname="ctid";
6442-
6443-
relname=RelationGetRelationName(errpos->rel);
6434+
varno=fsplan->scan.scanrelid;
6435+
colno=errpos->cur_attno;
64446436
}
64456437
else
64466438
{
64476439
/* error occurred in a scan against a foreign join */
6448-
ForeignScanState*fsstate=errpos->fsstate;
6449-
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
6450-
EState*estate=fsstate->ss.ps.state;
64516440
TargetEntry*tle;
64526441

64536442
tle=list_nth_node(TargetEntry,fsplan->fdw_scan_tlist,
64546443
errpos->cur_attno-1);
64556444

64566445
/*
64576446
* Target list can have Vars and expressions. For Vars, we can get
6458-
*its relation, however for expressions we can't. Thus for
6447+
*some information, however for expressions we can't. Thus for
64596448
* expressions, just show generic context message.
64606449
*/
64616450
if (IsA(tle->expr,Var))
64626451
{
6463-
RangeTblEntry*rte;
64646452
Var*var= (Var*)tle->expr;
64656453

6466-
rte=exec_rt_fetch(var->varno,estate);
6467-
6468-
if (var->varattno==0)
6469-
is_wholerow= true;
6470-
else
6471-
attname=get_attname(rte->relid,var->varattno, false);
6472-
6473-
relname=get_rel_name(rte->relid);
6454+
varno=var->varno;
6455+
colno=var->varattno;
64746456
}
6475-
else
6476-
errcontext("processing expression at position %d in select list",
6477-
errpos->cur_attno);
64786457
}
64796458

6480-
if (relname)
6459+
if (varno>0)
64816460
{
6482-
if (is_wholerow)
6483-
errcontext("whole-row reference to foreign table \"%s\"",relname);
6484-
elseif (attname)
6485-
errcontext("column \"%s\" of foreign table \"%s\"",attname,relname);
6461+
EState*estate=fsstate->ss.ps.state;
6462+
RangeTblEntry*rte=exec_rt_fetch(varno,estate);
6463+
6464+
relname=rte->eref->aliasname;
6465+
6466+
if (colno==0)
6467+
is_wholerow= true;
6468+
elseif (colno>0&&colno <=list_length(rte->eref->colnames))
6469+
attname=strVal(list_nth(rte->eref->colnames,colno-1));
6470+
elseif (colno==SelfItemPointerAttributeNumber)
6471+
attname="ctid";
64866472
}
6473+
6474+
if (relname&&is_wholerow)
6475+
errcontext("whole-row reference to foreign table \"%s\"",relname);
6476+
elseif (relname&&attname)
6477+
errcontext("column \"%s\" of foreign table \"%s\"",attname,relname);
6478+
else
6479+
errcontext("processing expression at position %d in select list",
6480+
errpos->cur_attno);
64876481
}
64886482

64896483
/*

‎contrib/postgres_fdw/sql/postgres_fdw.sql‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,9 +1072,11 @@ DROP FUNCTION f_test(int);
10721072
-- conversion error
10731073
-- ===================================================================
10741074
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPEint;
1075-
SELECT*FROM ft1WHERE c1=1;-- ERROR
1076-
SELECTft1.c1,ft2.c2,ft1.c8FROM ft1, ft2WHEREft1.c1=ft2.c1ANDft1.c1=1;-- ERROR
1077-
SELECTft1.c1,ft2.c2, ft1FROM ft1, ft2WHEREft1.c1=ft2.c1ANDft1.c1=1;-- ERROR
1075+
SELECT*FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8)WHERE x1=1;-- ERROR
1076+
SELECTftx.x1,ft2.c2,ftx.x8FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
1077+
WHEREftx.x1=ft2.c1ANDftx.x1=1;-- ERROR
1078+
SELECTftx.x1,ft2.c2, ftxFROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
1079+
WHEREftx.x1=ft2.c1ANDftx.x1=1;-- ERROR
10781080
SELECTsum(c2), array_agg(c8)FROM ft1GROUP BY c8;-- ERROR
10791081
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
10801082

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp