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

Commit3071bbf

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 parentdb692b0 commit3071bbf

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
@@ -4200,6 +4200,9 @@ CONTEXT: whole-row reference to foreign table "ftx"
42004200
SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR
42014201
ERROR: invalid input syntax for type integer: "foo"
42024202
CONTEXT: processing expression at position 2 in select list
4203+
ANALYZE ft1; -- ERROR
4204+
ERROR: invalid input syntax for type integer: "foo"
4205+
CONTEXT: column "c8" of foreign table "ft1"
42034206
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
42044207
-- ===================================================================
42054208
-- subtransaction

‎contrib/postgres_fdw/postgres_fdw.c

Lines changed: 73 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ typedef struct
303303
typedefstructConversionLocation
304304
{
305305
AttrNumbercur_attno;/* attribute number being processed, or 0 */
306-
ForeignScanState*fsstate;/* plan node being processed */
306+
Relationrel;/* foreign table being processed, or NULL */
307+
ForeignScanState*fsstate;/* plan node being processed, or NULL */
307308
}ConversionLocation;
308309

309310
/* Callback argument for ec_member_matches_foreign */
@@ -7113,7 +7114,12 @@ complete_pending_request(AsyncRequest *areq)
71137114
* rel is the local representation of the foreign table, attinmeta is
71147115
* conversion data for the rel's tupdesc, and retrieved_attrs is an
71157116
* integer list of the table column numbers present in the PGresult.
7117+
* fsstate is the ForeignScan plan node's execution state.
71167118
* temp_context is a working context that can be reset after each tuple.
7119+
*
7120+
* Note: either rel or fsstate, but not both, can be NULL. rel is NULL
7121+
* if we're processing a remote join, while fsstate is NULL in a non-query
7122+
* context such as ANALYZE, or if we're processing a non-scan query node.
71177123
*/
71187124
staticHeapTuple
71197125
make_tuple_from_result_row(PGresult*res,
@@ -7144,6 +7150,10 @@ make_tuple_from_result_row(PGresult *res,
71447150
*/
71457151
oldcontext=MemoryContextSwitchTo(temp_context);
71467152

7153+
/*
7154+
* Get the tuple descriptor for the row. Use the rel's tupdesc if rel is
7155+
* provided, otherwise look to the scan node's ScanTupleSlot.
7156+
*/
71477157
if (rel)
71487158
tupdesc=RelationGetDescr(rel);
71497159
else
@@ -7161,6 +7171,7 @@ make_tuple_from_result_row(PGresult *res,
71617171
* Set up and install callback to report where conversion error occurs.
71627172
*/
71637173
errpos.cur_attno=0;
7174+
errpos.rel=rel;
71647175
errpos.fsstate=fsstate;
71657176
errcallback.callback=conversion_error_callback;
71667177
errcallback.arg= (void*)&errpos;
@@ -7265,60 +7276,87 @@ make_tuple_from_result_row(PGresult *res,
72657276
*
72667277
* Note that this function mustn't do any catalog lookups, since we are in
72677278
* an already-failed transaction. Fortunately, we can get the needed info
7268-
* from the query's rangetable instead.
7279+
* from therelation or thequery's rangetable instead.
72697280
*/
72707281
staticvoid
72717282
conversion_error_callback(void*arg)
72727283
{
72737284
ConversionLocation*errpos= (ConversionLocation*)arg;
7285+
Relationrel=errpos->rel;
72747286
ForeignScanState*fsstate=errpos->fsstate;
7275-
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
7276-
intvarno=0;
7277-
AttrNumbercolno=0;
72787287
constchar*attname=NULL;
72797288
constchar*relname=NULL;
72807289
boolis_wholerow= false;
72817290

7282-
if (fsplan->scan.scanrelid>0)
7283-
{
7284-
/* error occurred in a scan against a foreign table */
7285-
varno=fsplan->scan.scanrelid;
7286-
colno=errpos->cur_attno;
7287-
}
7288-
else
7291+
/*
7292+
* If we're in a scan node, always use aliases from the rangetable, for
7293+
* consistency between the simple-relation and remote-join cases. Look at
7294+
* the relation's tupdesc only if we're not in a scan node.
7295+
*/
7296+
if (fsstate)
72897297
{
7290-
/* error occurred in a scan against a foreign join */
7291-
TargetEntry*tle;
7298+
/* ForeignScan case */
7299+
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
7300+
intvarno=0;
7301+
AttrNumbercolno=0;
72927302

7293-
tle=list_nth_node(TargetEntry,fsplan->fdw_scan_tlist,
7294-
errpos->cur_attno-1);
7303+
if (fsplan->scan.scanrelid>0)
7304+
{
7305+
/* error occurred in a scan against a foreign table */
7306+
varno=fsplan->scan.scanrelid;
7307+
colno=errpos->cur_attno;
7308+
}
7309+
else
7310+
{
7311+
/* error occurred in a scan against a foreign join */
7312+
TargetEntry*tle;
72957313

7296-
/*
7297-
* Target list can have Vars and expressions. For Vars, we can get
7298-
* some information, however for expressions we can't. Thus for
7299-
* expressions, just show generic context message.
7300-
*/
7301-
if (IsA(tle->expr,Var))
7314+
tle=list_nth_node(TargetEntry,fsplan->fdw_scan_tlist,
7315+
errpos->cur_attno-1);
7316+
7317+
/*
7318+
* Target list can have Vars and expressions. For Vars, we can
7319+
* get some information, however for expressions we can't. Thus
7320+
* for expressions, just show generic context message.
7321+
*/
7322+
if (IsA(tle->expr,Var))
7323+
{
7324+
Var*var= (Var*)tle->expr;
7325+
7326+
varno=var->varno;
7327+
colno=var->varattno;
7328+
}
7329+
}
7330+
7331+
if (varno>0)
73027332
{
7303-
Var*var= (Var*)tle->expr;
7333+
EState*estate=fsstate->ss.ps.state;
7334+
RangeTblEntry*rte=exec_rt_fetch(varno,estate);
73047335

7305-
varno=var->varno;
7306-
colno=var->varattno;
7336+
relname=rte->eref->aliasname;
7337+
7338+
if (colno==0)
7339+
is_wholerow= true;
7340+
elseif (colno>0&&colno <=list_length(rte->eref->colnames))
7341+
attname=strVal(list_nth(rte->eref->colnames,colno-1));
7342+
elseif (colno==SelfItemPointerAttributeNumber)
7343+
attname="ctid";
73077344
}
73087345
}
7309-
7310-
if (varno>0)
7346+
elseif (rel)
73117347
{
7312-
EState*estate=fsstate->ss.ps.state;
7313-
RangeTblEntry*rte=exec_rt_fetch(varno,estate);
7348+
/* Non-ForeignScan case (we should always have a rel here) */
7349+
TupleDesctupdesc=RelationGetDescr(rel);
73147350

7315-
relname=rte->eref->aliasname;
7351+
relname=RelationGetRelationName(rel);
7352+
if (errpos->cur_attno>0&&errpos->cur_attno <=tupdesc->natts)
7353+
{
7354+
Form_pg_attributeattr=TupleDescAttr(tupdesc,
7355+
errpos->cur_attno-1);
73167356

7317-
if (colno==0)
7318-
is_wholerow= true;
7319-
elseif (colno>0&&colno <=list_length(rte->eref->colnames))
7320-
attname=strVal(list_nth(rte->eref->colnames,colno-1));
7321-
elseif (colno==SelfItemPointerAttributeNumber)
7357+
attname=NameStr(attr->attname);
7358+
}
7359+
elseif (errpos->cur_attno==SelfItemPointerAttributeNumber)
73227360
attname="ctid";
73237361
}
73247362

‎contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,7 @@ SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
11641164
SELECTftx.x1,ft2.c2, ftxFROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
11651165
WHEREftx.x1=ft2.c1ANDftx.x1=1;-- ERROR
11661166
SELECTsum(c2), array_agg(c8)FROM ft1GROUP BY c8;-- ERROR
1167+
ANALYZE ft1;-- ERROR
11671168
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
11681169

11691170
-- ===================================================================

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp