@@ -302,16 +302,8 @@ typedef struct
302
302
*/
303
303
typedef struct ConversionLocation
304
304
{
305
- Relation rel ; /* foreign table's relcache entry. */
306
305
AttrNumber cur_attno ; /* attribute number being processed, or 0 */
307
-
308
- /*
309
- * In case of foreign join push down, fdw_scan_tlist is used to identify
310
- * the Var node corresponding to the error location and
311
- * fsstate->ss.ps.state gives access to the RTEs of corresponding relation
312
- * to get the relation name and attribute name.
313
- */
314
- ForeignScanState * fsstate ;
306
+ ForeignScanState * fsstate ; /* plan node being processed */
315
307
} ConversionLocation ;
316
308
317
309
/* Callback argument for ec_member_matches_foreign */
@@ -7082,7 +7074,6 @@ make_tuple_from_result_row(PGresult *res,
7082
7074
/*
7083
7075
* Set up and install callback to report where conversion error occurs.
7084
7076
*/
7085
- errpos .rel = rel ;
7086
7077
errpos .cur_attno = 0 ;
7087
7078
errpos .fsstate = fsstate ;
7088
7079
errcallback .callback = conversion_error_callback ;
@@ -7185,70 +7176,73 @@ make_tuple_from_result_row(PGresult *res,
7185
7176
/*
7186
7177
* Callback function which is called when error occurs during column value
7187
7178
* conversion. Print names of column and relation.
7179
+ *
7180
+ * Note that this function mustn't do any catalog lookups, since we are in
7181
+ * an already-failed transaction. Fortunately, we can get the needed info
7182
+ * from the query's rangetable instead.
7188
7183
*/
7189
7184
static void
7190
7185
conversion_error_callback (void * arg )
7191
7186
{
7187
+ ConversionLocation * errpos = (ConversionLocation * ) arg ;
7188
+ ForeignScanState * fsstate = errpos -> fsstate ;
7189
+ ForeignScan * fsplan = castNode (ForeignScan , fsstate -> ss .ps .plan );
7190
+ int varno = 0 ;
7191
+ AttrNumber colno = 0 ;
7192
7192
const char * attname = NULL ;
7193
7193
const char * relname = NULL ;
7194
7194
bool is_wholerow = false;
7195
- ConversionLocation * errpos = (ConversionLocation * ) arg ;
7196
7195
7197
- if (errpos -> rel )
7196
+ if (fsplan -> scan . scanrelid > 0 )
7198
7197
{
7199
7198
/* error occurred in a scan against a foreign table */
7200
- TupleDesc tupdesc = RelationGetDescr (errpos -> rel );
7201
- Form_pg_attribute attr = TupleDescAttr (tupdesc , errpos -> cur_attno - 1 );
7202
-
7203
- if (errpos -> cur_attno > 0 && errpos -> cur_attno <= tupdesc -> natts )
7204
- attname = NameStr (attr -> attname );
7205
- else if (errpos -> cur_attno == SelfItemPointerAttributeNumber )
7206
- attname = "ctid" ;
7207
-
7208
- relname = RelationGetRelationName (errpos -> rel );
7199
+ varno = fsplan -> scan .scanrelid ;
7200
+ colno = errpos -> cur_attno ;
7209
7201
}
7210
7202
else
7211
7203
{
7212
7204
/* error occurred in a scan against a foreign join */
7213
- ForeignScanState * fsstate = errpos -> fsstate ;
7214
- ForeignScan * fsplan = castNode (ForeignScan , fsstate -> ss .ps .plan );
7215
- EState * estate = fsstate -> ss .ps .state ;
7216
7205
TargetEntry * tle ;
7217
7206
7218
7207
tle = list_nth_node (TargetEntry , fsplan -> fdw_scan_tlist ,
7219
7208
errpos -> cur_attno - 1 );
7220
7209
7221
7210
/*
7222
7211
* Target list can have Vars and expressions. For Vars, we can get
7223
- * its relation , however for expressions we can't. Thus for
7212
+ * some information , however for expressions we can't. Thus for
7224
7213
* expressions, just show generic context message.
7225
7214
*/
7226
7215
if (IsA (tle -> expr , Var ))
7227
7216
{
7228
- RangeTblEntry * rte ;
7229
7217
Var * var = (Var * ) tle -> expr ;
7230
7218
7231
- rte = exec_rt_fetch (var -> varno , estate );
7232
-
7233
- if (var -> varattno == 0 )
7234
- is_wholerow = true;
7235
- else
7236
- attname = get_attname (rte -> relid , var -> varattno , false);
7237
-
7238
- relname = get_rel_name (rte -> relid );
7219
+ varno = var -> varno ;
7220
+ colno = var -> varattno ;
7239
7221
}
7240
- else
7241
- errcontext ("processing expression at position %d in select list" ,
7242
- errpos -> cur_attno );
7243
7222
}
7244
7223
7245
- if (relname )
7224
+ if (varno > 0 )
7246
7225
{
7247
- if (is_wholerow )
7248
- errcontext ("whole-row reference to foreign table \"%s\"" , relname );
7249
- else if (attname )
7250
- errcontext ("column \"%s\" of foreign table \"%s\"" , attname , relname );
7226
+ EState * estate = fsstate -> ss .ps .state ;
7227
+ RangeTblEntry * rte = exec_rt_fetch (varno , estate );
7228
+
7229
+ relname = rte -> eref -> aliasname ;
7230
+
7231
+ if (colno == 0 )
7232
+ is_wholerow = true;
7233
+ else if (colno > 0 && colno <= list_length (rte -> eref -> colnames ))
7234
+ attname = strVal (list_nth (rte -> eref -> colnames , colno - 1 ));
7235
+ else if (colno == SelfItemPointerAttributeNumber )
7236
+ attname = "ctid" ;
7251
7237
}
7238
+
7239
+ if (relname && is_wholerow )
7240
+ errcontext ("whole-row reference to foreign table \"%s\"" , relname );
7241
+ else if (relname && attname )
7242
+ errcontext ("column \"%s\" of foreign table \"%s\"" , attname , relname );
7243
+ else
7244
+ errcontext ("processing expression at position %d in select list" ,
7245
+ errpos -> cur_attno );
7252
7246
}
7253
7247
7254
7248
/*
0 commit comments