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

Commit2288973

Browse files
committed
Fix null-pointer crash in postgres_fdw's conversion_error_callback.
Commitc7b7311 adjusted conversion_error_callback to always useinformation from the query's rangetable, to avoid doing catalog lookupsin an already-failed transaction. However, as a result of the utterlyinadequate documentation for make_tuple_from_result_row, I failed torealize that fsstate could be NULL in some contexts. That led to acrash if we got a conversion error in such a context. Fix by fallingback to the previous coding when fsstate is NULL. Improve thecommentary, too.Per report from Andrey Borodin. Back-patch to 9.6, like the previouspatch.Discussion:https://postgr.es/m/08916396-55E4-4D68-AB3A-BD6066F9E5C0@yandex-team.ru
1 parent6762180 commit2288973

File tree

3 files changed

+77
-35
lines changed

3 files changed

+77
-35
lines changed

‎contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4049,6 +4049,9 @@ CONTEXT: whole-row reference to foreign table "ftx"
40494049
SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR
40504050
ERROR: invalid input syntax for type integer: "foo"
40514051
CONTEXT: processing expression at position 2 in select list
4052+
ANALYZE ft1; -- ERROR
4053+
ERROR: invalid input syntax for type integer: "foo"
4054+
CONTEXT: column "c8" of foreign table "ft1"
40524055
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
40534056
-- ===================================================================
40544057
-- subtransaction

‎contrib/postgres_fdw/postgres_fdw.c

Lines changed: 73 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ typedef struct
285285
typedefstructConversionLocation
286286
{
287287
AttrNumbercur_attno;/* attribute number being processed, or 0 */
288-
ForeignScanState*fsstate;/* plan node being processed */
288+
Relationrel;/* foreign table being processed, or NULL */
289+
ForeignScanState*fsstate;/* plan node being processed, or NULL */
289290
}ConversionLocation;
290291

291292
/* Callback argument for ec_member_matches_foreign */
@@ -6293,7 +6294,12 @@ add_foreign_final_paths(PlannerInfo *root, RelOptInfo *input_rel,
62936294
* rel is the local representation of the foreign table, attinmeta is
62946295
* conversion data for the rel's tupdesc, and retrieved_attrs is an
62956296
* integer list of the table column numbers present in the PGresult.
6297+
* fsstate is the ForeignScan plan node's execution state.
62966298
* temp_context is a working context that can be reset after each tuple.
6299+
*
6300+
* Note: either rel or fsstate, but not both, can be NULL. rel is NULL
6301+
* if we're processing a remote join, while fsstate is NULL in a non-query
6302+
* context such as ANALYZE, or if we're processing a non-scan query node.
62976303
*/
62986304
staticHeapTuple
62996305
make_tuple_from_result_row(PGresult*res,
@@ -6324,6 +6330,10 @@ make_tuple_from_result_row(PGresult *res,
63246330
*/
63256331
oldcontext=MemoryContextSwitchTo(temp_context);
63266332

6333+
/*
6334+
* Get the tuple descriptor for the row. Use the rel's tupdesc if rel is
6335+
* provided, otherwise look to the scan node's ScanTupleSlot.
6336+
*/
63276337
if (rel)
63286338
tupdesc=RelationGetDescr(rel);
63296339
else
@@ -6341,6 +6351,7 @@ make_tuple_from_result_row(PGresult *res,
63416351
* Set up and install callback to report where conversion error occurs.
63426352
*/
63436353
errpos.cur_attno=0;
6354+
errpos.rel=rel;
63446355
errpos.fsstate=fsstate;
63456356
errcallback.callback=conversion_error_callback;
63466357
errcallback.arg= (void*)&errpos;
@@ -6445,60 +6456,87 @@ make_tuple_from_result_row(PGresult *res,
64456456
*
64466457
* Note that this function mustn't do any catalog lookups, since we are in
64476458
* an already-failed transaction. Fortunately, we can get the needed info
6448-
* from the query's rangetable instead.
6459+
* from therelation or thequery's rangetable instead.
64496460
*/
64506461
staticvoid
64516462
conversion_error_callback(void*arg)
64526463
{
64536464
ConversionLocation*errpos= (ConversionLocation*)arg;
6465+
Relationrel=errpos->rel;
64546466
ForeignScanState*fsstate=errpos->fsstate;
6455-
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
6456-
intvarno=0;
6457-
AttrNumbercolno=0;
64586467
constchar*attname=NULL;
64596468
constchar*relname=NULL;
64606469
boolis_wholerow= false;
64616470

6462-
if (fsplan->scan.scanrelid>0)
6463-
{
6464-
/* error occurred in a scan against a foreign table */
6465-
varno=fsplan->scan.scanrelid;
6466-
colno=errpos->cur_attno;
6467-
}
6468-
else
6471+
/*
6472+
* If we're in a scan node, always use aliases from the rangetable, for
6473+
* consistency between the simple-relation and remote-join cases. Look at
6474+
* the relation's tupdesc only if we're not in a scan node.
6475+
*/
6476+
if (fsstate)
64696477
{
6470-
/* error occurred in a scan against a foreign join */
6471-
TargetEntry*tle;
6478+
/* ForeignScan case */
6479+
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
6480+
intvarno=0;
6481+
AttrNumbercolno=0;
64726482

6473-
tle=list_nth_node(TargetEntry,fsplan->fdw_scan_tlist,
6474-
errpos->cur_attno-1);
6483+
if (fsplan->scan.scanrelid>0)
6484+
{
6485+
/* error occurred in a scan against a foreign table */
6486+
varno=fsplan->scan.scanrelid;
6487+
colno=errpos->cur_attno;
6488+
}
6489+
else
6490+
{
6491+
/* error occurred in a scan against a foreign join */
6492+
TargetEntry*tle;
64756493

6476-
/*
6477-
* Target list can have Vars and expressions. For Vars, we can get
6478-
* some information, however for expressions we can't. Thus for
6479-
* expressions, just show generic context message.
6480-
*/
6481-
if (IsA(tle->expr,Var))
6494+
tle=list_nth_node(TargetEntry,fsplan->fdw_scan_tlist,
6495+
errpos->cur_attno-1);
6496+
6497+
/*
6498+
* Target list can have Vars and expressions. For Vars, we can
6499+
* get some information, however for expressions we can't. Thus
6500+
* for expressions, just show generic context message.
6501+
*/
6502+
if (IsA(tle->expr,Var))
6503+
{
6504+
Var*var= (Var*)tle->expr;
6505+
6506+
varno=var->varno;
6507+
colno=var->varattno;
6508+
}
6509+
}
6510+
6511+
if (varno>0)
64826512
{
6483-
Var*var= (Var*)tle->expr;
6513+
EState*estate=fsstate->ss.ps.state;
6514+
RangeTblEntry*rte=exec_rt_fetch(varno,estate);
64846515

6485-
varno=var->varno;
6486-
colno=var->varattno;
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";
64876524
}
64886525
}
6489-
6490-
if (varno>0)
6526+
elseif (rel)
64916527
{
6492-
EState*estate=fsstate->ss.ps.state;
6493-
RangeTblEntry*rte=exec_rt_fetch(varno,estate);
6528+
/* Non-ForeignScan case (we should always have a rel here) */
6529+
TupleDesctupdesc=RelationGetDescr(rel);
64946530

6495-
relname=rte->eref->aliasname;
6531+
relname=RelationGetRelationName(rel);
6532+
if (errpos->cur_attno>0&&errpos->cur_attno <=tupdesc->natts)
6533+
{
6534+
Form_pg_attributeattr=TupleDescAttr(tupdesc,
6535+
errpos->cur_attno-1);
64966536

6497-
if (colno==0)
6498-
is_wholerow= true;
6499-
elseif (colno>0&&colno <=list_length(rte->eref->colnames))
6500-
attname=strVal(list_nth(rte->eref->colnames,colno-1));
6501-
elseif (colno==SelfItemPointerAttributeNumber)
6537+
attname=NameStr(attr->attname);
6538+
}
6539+
elseif (errpos->cur_attno==SelfItemPointerAttributeNumber)
65026540
attname="ctid";
65036541
}
65046542

‎contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,7 @@ SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
10781078
SELECTftx.x1,ft2.c2, ftxFROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
10791079
WHEREftx.x1=ft2.c1ANDftx.x1=1;-- ERROR
10801080
SELECTsum(c2), array_agg(c8)FROM ft1GROUP BY c8;-- ERROR
1081+
ANALYZE ft1;-- ERROR
10811082
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
10821083

10831084
-- ===================================================================

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp