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

Commitaee83f3

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 parent9ab94cc commitaee83f3

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
@@ -4079,6 +4079,9 @@ CONTEXT: whole-row reference to foreign table "ftx"
40794079
SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR
40804080
ERROR: invalid input syntax for type integer: "foo"
40814081
CONTEXT: processing expression at position 2 in select list
4082+
ANALYZE ft1; -- ERROR
4083+
ERROR: invalid input syntax for type integer: "foo"
4084+
CONTEXT: column "c8" of foreign table "ft1"
40824085
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
40834086
-- ===================================================================
40844087
-- subtransaction

‎contrib/postgres_fdw/postgres_fdw.c

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

292293
/* Callback argument for ec_member_matches_foreign */
@@ -6345,7 +6346,12 @@ add_foreign_final_paths(PlannerInfo *root, RelOptInfo *input_rel,
63456346
* rel is the local representation of the foreign table, attinmeta is
63466347
* conversion data for the rel's tupdesc, and retrieved_attrs is an
63476348
* integer list of the table column numbers present in the PGresult.
6349+
* fsstate is the ForeignScan plan node's execution state.
63486350
* temp_context is a working context that can be reset after each tuple.
6351+
*
6352+
* Note: either rel or fsstate, but not both, can be NULL. rel is NULL
6353+
* if we're processing a remote join, while fsstate is NULL in a non-query
6354+
* context such as ANALYZE, or if we're processing a non-scan query node.
63496355
*/
63506356
staticHeapTuple
63516357
make_tuple_from_result_row(PGresult*res,
@@ -6376,6 +6382,10 @@ make_tuple_from_result_row(PGresult *res,
63766382
*/
63776383
oldcontext=MemoryContextSwitchTo(temp_context);
63786384

6385+
/*
6386+
* Get the tuple descriptor for the row. Use the rel's tupdesc if rel is
6387+
* provided, otherwise look to the scan node's ScanTupleSlot.
6388+
*/
63796389
if (rel)
63806390
tupdesc=RelationGetDescr(rel);
63816391
else
@@ -6393,6 +6403,7 @@ make_tuple_from_result_row(PGresult *res,
63936403
* Set up and install callback to report where conversion error occurs.
63946404
*/
63956405
errpos.cur_attno=0;
6406+
errpos.rel=rel;
63966407
errpos.fsstate=fsstate;
63976408
errcallback.callback=conversion_error_callback;
63986409
errcallback.arg= (void*)&errpos;
@@ -6497,60 +6508,87 @@ make_tuple_from_result_row(PGresult *res,
64976508
*
64986509
* Note that this function mustn't do any catalog lookups, since we are in
64996510
* an already-failed transaction. Fortunately, we can get the needed info
6500-
* from the query's rangetable instead.
6511+
* from therelation or thequery's rangetable instead.
65016512
*/
65026513
staticvoid
65036514
conversion_error_callback(void*arg)
65046515
{
65056516
ConversionLocation*errpos= (ConversionLocation*)arg;
6517+
Relationrel=errpos->rel;
65066518
ForeignScanState*fsstate=errpos->fsstate;
6507-
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
6508-
intvarno=0;
6509-
AttrNumbercolno=0;
65106519
constchar*attname=NULL;
65116520
constchar*relname=NULL;
65126521
boolis_wholerow= false;
65136522

6514-
if (fsplan->scan.scanrelid>0)
6515-
{
6516-
/* error occurred in a scan against a foreign table */
6517-
varno=fsplan->scan.scanrelid;
6518-
colno=errpos->cur_attno;
6519-
}
6520-
else
6523+
/*
6524+
* If we're in a scan node, always use aliases from the rangetable, for
6525+
* consistency between the simple-relation and remote-join cases. Look at
6526+
* the relation's tupdesc only if we're not in a scan node.
6527+
*/
6528+
if (fsstate)
65216529
{
6522-
/* error occurred in a scan against a foreign join */
6523-
TargetEntry*tle;
6530+
/* ForeignScan case */
6531+
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
6532+
intvarno=0;
6533+
AttrNumbercolno=0;
65246534

6525-
tle=list_nth_node(TargetEntry,fsplan->fdw_scan_tlist,
6526-
errpos->cur_attno-1);
6535+
if (fsplan->scan.scanrelid>0)
6536+
{
6537+
/* error occurred in a scan against a foreign table */
6538+
varno=fsplan->scan.scanrelid;
6539+
colno=errpos->cur_attno;
6540+
}
6541+
else
6542+
{
6543+
/* error occurred in a scan against a foreign join */
6544+
TargetEntry*tle;
65276545

6528-
/*
6529-
* Target list can have Vars and expressions. For Vars, we can get
6530-
* some information, however for expressions we can't. Thus for
6531-
* expressions, just show generic context message.
6532-
*/
6533-
if (IsA(tle->expr,Var))
6546+
tle=list_nth_node(TargetEntry,fsplan->fdw_scan_tlist,
6547+
errpos->cur_attno-1);
6548+
6549+
/*
6550+
* Target list can have Vars and expressions. For Vars, we can
6551+
* get some information, however for expressions we can't. Thus
6552+
* for expressions, just show generic context message.
6553+
*/
6554+
if (IsA(tle->expr,Var))
6555+
{
6556+
Var*var= (Var*)tle->expr;
6557+
6558+
varno=var->varno;
6559+
colno=var->varattno;
6560+
}
6561+
}
6562+
6563+
if (varno>0)
65346564
{
6535-
Var*var= (Var*)tle->expr;
6565+
EState*estate=fsstate->ss.ps.state;
6566+
RangeTblEntry*rte=exec_rt_fetch(varno,estate);
65366567

6537-
varno=var->varno;
6538-
colno=var->varattno;
6568+
relname=rte->eref->aliasname;
6569+
6570+
if (colno==0)
6571+
is_wholerow= true;
6572+
elseif (colno>0&&colno <=list_length(rte->eref->colnames))
6573+
attname=strVal(list_nth(rte->eref->colnames,colno-1));
6574+
elseif (colno==SelfItemPointerAttributeNumber)
6575+
attname="ctid";
65396576
}
65406577
}
6541-
6542-
if (varno>0)
6578+
elseif (rel)
65436579
{
6544-
EState*estate=fsstate->ss.ps.state;
6545-
RangeTblEntry*rte=exec_rt_fetch(varno,estate);
6580+
/* Non-ForeignScan case (we should always have a rel here) */
6581+
TupleDesctupdesc=RelationGetDescr(rel);
65466582

6547-
relname=rte->eref->aliasname;
6583+
relname=RelationGetRelationName(rel);
6584+
if (errpos->cur_attno>0&&errpos->cur_attno <=tupdesc->natts)
6585+
{
6586+
Form_pg_attributeattr=TupleDescAttr(tupdesc,
6587+
errpos->cur_attno-1);
65486588

6549-
if (colno==0)
6550-
is_wholerow= true;
6551-
elseif (colno>0&&colno <=list_length(rte->eref->colnames))
6552-
attname=strVal(list_nth(rte->eref->colnames,colno-1));
6553-
elseif (colno==SelfItemPointerAttributeNumber)
6589+
attname=NameStr(attr->attname);
6590+
}
6591+
elseif (errpos->cur_attno==SelfItemPointerAttributeNumber)
65546592
attname="ctid";
65556593
}
65566594

‎contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,7 @@ SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
11031103
SELECTftx.x1,ft2.c2, ftxFROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
11041104
WHEREftx.x1=ft2.c1ANDftx.x1=1;-- ERROR
11051105
SELECTsum(c2), array_agg(c8)FROM ft1GROUP BY c8;-- ERROR
1106+
ANALYZE ft1;-- ERROR
11061107
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
11071108

11081109
-- ===================================================================

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp