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

Commitbee1861

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 parentfa44348 commitbee1861

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
@@ -4065,15 +4065,17 @@ DROP FUNCTION f_test(int);
40654065
-- conversion error
40664066
-- ===================================================================
40674067
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int;
4068-
SELECT * FROM ft1 WHEREc1 = 1; -- ERROR
4068+
SELECT * FROM ft1ftx(x1,x2,x3,x4,x5,x6,x7,x8)WHEREx1 = 1; -- ERROR
40694069
ERROR: invalid input syntax for type integer: "foo"
4070-
CONTEXT: column "c8" of foreign table "ft1"
4071-
SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR
4070+
CONTEXT: column "x8" of foreign table "ftx"
4071+
SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
4072+
WHERE ftx.x1 = ft2.c1 AND ftx.x1 = 1; -- ERROR
40724073
ERROR: invalid input syntax for type integer: "foo"
4073-
CONTEXT: column "c8" of foreign table "ft1"
4074-
SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR
4074+
CONTEXT: column "x8" of foreign table "ftx"
4075+
SELECT ftx.x1, ft2.c2, ftx FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
4076+
WHERE ftx.x1 = ft2.c1 AND ftx.x1 = 1; -- ERROR
40754077
ERROR: invalid input syntax for type integer: "foo"
4076-
CONTEXT: whole-row reference to foreign table "ft1"
4078+
CONTEXT: whole-row reference to foreign table "ftx"
40774079
SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR
40784080
ERROR: invalid input syntax for type integer: "foo"
40794081
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
@@ -285,16 +285,8 @@ typedef struct
285285
*/
286286
typedefstructConversionLocation
287287
{
288-
Relationrel;/* foreign table's relcache entry. */
289288
AttrNumbercur_attno;/* attribute number being processed, or 0 */
290-
291-
/*
292-
* In case of foreign join push down, fdw_scan_tlist is used to identify
293-
* the Var node corresponding to the error location and
294-
* fsstate->ss.ps.state gives access to the RTEs of corresponding relation
295-
* to get the relation name and attribute name.
296-
*/
297-
ForeignScanState*fsstate;
289+
ForeignScanState*fsstate;/* plan node being processed */
298290
}ConversionLocation;
299291

300292
/* Callback argument for ec_member_matches_foreign */
@@ -6369,7 +6361,6 @@ make_tuple_from_result_row(PGresult *res,
63696361
/*
63706362
* Set up and install callback to report where conversion error occurs.
63716363
*/
6372-
errpos.rel=rel;
63736364
errpos.cur_attno=0;
63746365
errpos.fsstate=fsstate;
63756366
errcallback.callback=conversion_error_callback;
@@ -6472,70 +6463,73 @@ make_tuple_from_result_row(PGresult *res,
64726463
/*
64736464
* Callback function which is called when error occurs during column value
64746465
* conversion. Print names of column and relation.
6466+
*
6467+
* Note that this function mustn't do any catalog lookups, since we are in
6468+
* an already-failed transaction. Fortunately, we can get the needed info
6469+
* from the query's rangetable instead.
64756470
*/
64766471
staticvoid
64776472
conversion_error_callback(void*arg)
64786473
{
6474+
ConversionLocation*errpos= (ConversionLocation*)arg;
6475+
ForeignScanState*fsstate=errpos->fsstate;
6476+
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
6477+
intvarno=0;
6478+
AttrNumbercolno=0;
64796479
constchar*attname=NULL;
64806480
constchar*relname=NULL;
64816481
boolis_wholerow= false;
6482-
ConversionLocation*errpos= (ConversionLocation*)arg;
64836482

6484-
if (errpos->rel)
6483+
if (fsplan->scan.scanrelid>0)
64856484
{
64866485
/* error occurred in a scan against a foreign table */
6487-
TupleDesctupdesc=RelationGetDescr(errpos->rel);
6488-
Form_pg_attributeattr=TupleDescAttr(tupdesc,errpos->cur_attno-1);
6489-
6490-
if (errpos->cur_attno>0&&errpos->cur_attno <=tupdesc->natts)
6491-
attname=NameStr(attr->attname);
6492-
elseif (errpos->cur_attno==SelfItemPointerAttributeNumber)
6493-
attname="ctid";
6494-
6495-
relname=RelationGetRelationName(errpos->rel);
6486+
varno=fsplan->scan.scanrelid;
6487+
colno=errpos->cur_attno;
64966488
}
64976489
else
64986490
{
64996491
/* error occurred in a scan against a foreign join */
6500-
ForeignScanState*fsstate=errpos->fsstate;
6501-
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
6502-
EState*estate=fsstate->ss.ps.state;
65036492
TargetEntry*tle;
65046493

65056494
tle=list_nth_node(TargetEntry,fsplan->fdw_scan_tlist,
65066495
errpos->cur_attno-1);
65076496

65086497
/*
65096498
* Target list can have Vars and expressions. For Vars, we can get
6510-
*its relation, however for expressions we can't. Thus for
6499+
*some information, however for expressions we can't. Thus for
65116500
* expressions, just show generic context message.
65126501
*/
65136502
if (IsA(tle->expr,Var))
65146503
{
6515-
RangeTblEntry*rte;
65166504
Var*var= (Var*)tle->expr;
65176505

6518-
rte=exec_rt_fetch(var->varno,estate);
6519-
6520-
if (var->varattno==0)
6521-
is_wholerow= true;
6522-
else
6523-
attname=get_attname(rte->relid,var->varattno, false);
6524-
6525-
relname=get_rel_name(rte->relid);
6506+
varno=var->varno;
6507+
colno=var->varattno;
65266508
}
6527-
else
6528-
errcontext("processing expression at position %d in select list",
6529-
errpos->cur_attno);
65306509
}
65316510

6532-
if (relname)
6511+
if (varno>0)
65336512
{
6534-
if (is_wholerow)
6535-
errcontext("whole-row reference to foreign table \"%s\"",relname);
6536-
elseif (attname)
6537-
errcontext("column \"%s\" of foreign table \"%s\"",attname,relname);
6513+
EState*estate=fsstate->ss.ps.state;
6514+
RangeTblEntry*rte=exec_rt_fetch(varno,estate);
6515+
6516+
relname=rte->eref->aliasname;
6517+
6518+
if (colno==0)
6519+
is_wholerow= true;
6520+
elseif (colno>0&&colno <=list_length(rte->eref->colnames))
6521+
attname=strVal(list_nth(rte->eref->colnames,colno-1));
6522+
elseif (colno==SelfItemPointerAttributeNumber)
6523+
attname="ctid";
65386524
}
6525+
6526+
if (relname&&is_wholerow)
6527+
errcontext("whole-row reference to foreign table \"%s\"",relname);
6528+
elseif (relname&&attname)
6529+
errcontext("column \"%s\" of foreign table \"%s\"",attname,relname);
6530+
else
6531+
errcontext("processing expression at position %d in select list",
6532+
errpos->cur_attno);
65396533
}
65406534

65416535
/*

‎contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,9 +1097,11 @@ DROP FUNCTION f_test(int);
10971097
-- conversion error
10981098
-- ===================================================================
10991099
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPEint;
1100-
SELECT*FROM ft1WHERE c1=1;-- ERROR
1101-
SELECTft1.c1,ft2.c2,ft1.c8FROM ft1, ft2WHEREft1.c1=ft2.c1ANDft1.c1=1;-- ERROR
1102-
SELECTft1.c1,ft2.c2, ft1FROM ft1, ft2WHEREft1.c1=ft2.c1ANDft1.c1=1;-- ERROR
1100+
SELECT*FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8)WHERE x1=1;-- ERROR
1101+
SELECTftx.x1,ft2.c2,ftx.x8FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
1102+
WHEREftx.x1=ft2.c1ANDftx.x1=1;-- ERROR
1103+
SELECTftx.x1,ft2.c2, ftxFROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
1104+
WHEREftx.x1=ft2.c1ANDftx.x1=1;-- ERROR
11031105
SELECTsum(c2), array_agg(c8)FROM ft1GROUP BY c8;-- ERROR
11041106
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
11051107

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp