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

Commit12ff678

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 parent8e26b86 commit12ff678

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
@@ -4110,6 +4110,9 @@ CONTEXT: whole-row reference to foreign table "ftx"
41104110
SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR
41114111
ERROR: invalid input syntax for type integer: "foo"
41124112
CONTEXT: processing expression at position 2 in select list
4113+
ANALYZE ft1; -- ERROR
4114+
ERROR: invalid input syntax for type integer: "foo"
4115+
CONTEXT: column "c8" of foreign table "ft1"
41134116
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
41144117
-- ===================================================================
41154118
-- 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 */
@@ -7117,7 +7118,12 @@ complete_pending_request(AsyncRequest *areq)
71177118
* rel is the local representation of the foreign table, attinmeta is
71187119
* conversion data for the rel's tupdesc, and retrieved_attrs is an
71197120
* integer list of the table column numbers present in the PGresult.
7121+
* fsstate is the ForeignScan plan node's execution state.
71207122
* temp_context is a working context that can be reset after each tuple.
7123+
*
7124+
* Note: either rel or fsstate, but not both, can be NULL. rel is NULL
7125+
* if we're processing a remote join, while fsstate is NULL in a non-query
7126+
* context such as ANALYZE, or if we're processing a non-scan query node.
71217127
*/
71227128
staticHeapTuple
71237129
make_tuple_from_result_row(PGresult*res,
@@ -7148,6 +7154,10 @@ make_tuple_from_result_row(PGresult *res,
71487154
*/
71497155
oldcontext=MemoryContextSwitchTo(temp_context);
71507156

7157+
/*
7158+
* Get the tuple descriptor for the row. Use the rel's tupdesc if rel is
7159+
* provided, otherwise look to the scan node's ScanTupleSlot.
7160+
*/
71517161
if (rel)
71527162
tupdesc=RelationGetDescr(rel);
71537163
else
@@ -7165,6 +7175,7 @@ make_tuple_from_result_row(PGresult *res,
71657175
* Set up and install callback to report where conversion error occurs.
71667176
*/
71677177
errpos.cur_attno=0;
7178+
errpos.rel=rel;
71687179
errpos.fsstate=fsstate;
71697180
errcallback.callback=conversion_error_callback;
71707181
errcallback.arg= (void*)&errpos;
@@ -7269,60 +7280,87 @@ make_tuple_from_result_row(PGresult *res,
72697280
*
72707281
* Note that this function mustn't do any catalog lookups, since we are in
72717282
* an already-failed transaction. Fortunately, we can get the needed info
7272-
* from the query's rangetable instead.
7283+
* from therelation or thequery's rangetable instead.
72737284
*/
72747285
staticvoid
72757286
conversion_error_callback(void*arg)
72767287
{
72777288
ConversionLocation*errpos= (ConversionLocation*)arg;
7289+
Relationrel=errpos->rel;
72787290
ForeignScanState*fsstate=errpos->fsstate;
7279-
ForeignScan*fsplan=castNode(ForeignScan,fsstate->ss.ps.plan);
7280-
intvarno=0;
7281-
AttrNumbercolno=0;
72827291
constchar*attname=NULL;
72837292
constchar*relname=NULL;
72847293
boolis_wholerow= false;
72857294

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

7297-
tle=list_nth_node(TargetEntry,fsplan->fdw_scan_tlist,
7298-
errpos->cur_attno-1);
7307+
if (fsplan->scan.scanrelid>0)
7308+
{
7309+
/* error occurred in a scan against a foreign table */
7310+
varno=fsplan->scan.scanrelid;
7311+
colno=errpos->cur_attno;
7312+
}
7313+
else
7314+
{
7315+
/* error occurred in a scan against a foreign join */
7316+
TargetEntry*tle;
72997317

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

7309-
varno=var->varno;
7310-
colno=var->varattno;
7340+
relname=rte->eref->aliasname;
7341+
7342+
if (colno==0)
7343+
is_wholerow= true;
7344+
elseif (colno>0&&colno <=list_length(rte->eref->colnames))
7345+
attname=strVal(list_nth(rte->eref->colnames,colno-1));
7346+
elseif (colno==SelfItemPointerAttributeNumber)
7347+
attname="ctid";
73117348
}
73127349
}
7313-
7314-
if (varno>0)
7350+
elseif (rel)
73157351
{
7316-
EState*estate=fsstate->ss.ps.state;
7317-
RangeTblEntry*rte=exec_rt_fetch(varno,estate);
7352+
/* Non-ForeignScan case (we should always have a rel here) */
7353+
TupleDesctupdesc=RelationGetDescr(rel);
73187354

7319-
relname=rte->eref->aliasname;
7355+
relname=RelationGetRelationName(rel);
7356+
if (errpos->cur_attno>0&&errpos->cur_attno <=tupdesc->natts)
7357+
{
7358+
Form_pg_attributeattr=TupleDescAttr(tupdesc,
7359+
errpos->cur_attno-1);
73207360

7321-
if (colno==0)
7322-
is_wholerow= true;
7323-
elseif (colno>0&&colno <=list_length(rte->eref->colnames))
7324-
attname=strVal(list_nth(rte->eref->colnames,colno-1));
7325-
elseif (colno==SelfItemPointerAttributeNumber)
7361+
attname=NameStr(attr->attname);
7362+
}
7363+
elseif (errpos->cur_attno==SelfItemPointerAttributeNumber)
73267364
attname="ctid";
73277365
}
73287366

‎contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
11351135
SELECTftx.x1,ft2.c2, ftxFROM ft1 ftx(x1,x2,x3,x4,x5,x6,x7,x8), ft2
11361136
WHEREftx.x1=ft2.c1ANDftx.x1=1;-- ERROR
11371137
SELECTsum(c2), array_agg(c8)FROM ft1GROUP BY c8;-- ERROR
1138+
ANALYZE ft1;-- ERROR
11381139
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
11391140

11401141
-- ===================================================================

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp