@@ -244,16 +244,8 @@ typedef struct PgFdwAnalyzeState
244
244
*/
245
245
typedef struct ConversionLocation
246
246
{
247
- Relation rel ; /* foreign table's relcache entry. */
248
247
AttrNumber cur_attno ; /* attribute number being processed, or 0 */
249
-
250
- /*
251
- * In case of foreign join push down, fdw_scan_tlist is used to identify
252
- * the Var node corresponding to the error location and
253
- * fsstate->ss.ps.state gives access to the RTEs of corresponding relation
254
- * to get the relation name and attribute name.
255
- */
256
- ForeignScanState * fsstate ;
248
+ ForeignScanState * fsstate ; /* plan node being processed */
257
249
} ConversionLocation ;
258
250
259
251
/* Callback argument for ec_member_matches_foreign */
@@ -5026,7 +5018,6 @@ make_tuple_from_result_row(PGresult *res,
5026
5018
/*
5027
5019
* Set up and install callback to report where conversion error occurs.
5028
5020
*/
5029
- errpos .rel = rel ;
5030
5021
errpos .cur_attno = 0 ;
5031
5022
errpos .fsstate = fsstate ;
5032
5023
errcallback .callback = conversion_error_callback ;
@@ -5146,71 +5137,75 @@ make_tuple_from_result_row(PGresult *res,
5146
5137
/*
5147
5138
* Callback function which is called when error occurs during column value
5148
5139
* conversion. Print names of column and relation.
5140
+ *
5141
+ * Note that this function mustn't do any catalog lookups, since we are in
5142
+ * an already-failed transaction. Fortunately, we can get the needed info
5143
+ * from the query's rangetable instead.
5149
5144
*/
5150
5145
static void
5151
5146
conversion_error_callback (void * arg )
5152
5147
{
5148
+ ConversionLocation * errpos = (ConversionLocation * ) arg ;
5149
+ ForeignScanState * fsstate = errpos -> fsstate ;
5150
+ ForeignScan * fsplan = castNode (ForeignScan , fsstate -> ss .ps .plan );
5151
+ int varno = 0 ;
5152
+ AttrNumber colno = 0 ;
5153
5153
const char * attname = NULL ;
5154
5154
const char * relname = NULL ;
5155
5155
bool is_wholerow = false;
5156
- ConversionLocation * errpos = (ConversionLocation * ) arg ;
5157
5156
5158
- if (errpos -> rel )
5157
+ if (fsplan -> scan . scanrelid > 0 )
5159
5158
{
5160
5159
/* error occurred in a scan against a foreign table */
5161
- TupleDesc tupdesc = RelationGetDescr (errpos -> rel );
5162
-
5163
- if (errpos -> cur_attno > 0 && errpos -> cur_attno <= tupdesc -> natts )
5164
- attname = NameStr (tupdesc -> attrs [errpos -> cur_attno - 1 ]-> attname );
5165
- else if (errpos -> cur_attno == SelfItemPointerAttributeNumber )
5166
- attname = "ctid" ;
5167
- else if (errpos -> cur_attno == ObjectIdAttributeNumber )
5168
- attname = "oid" ;
5169
-
5170
- relname = RelationGetRelationName (errpos -> rel );
5160
+ varno = fsplan -> scan .scanrelid ;
5161
+ colno = errpos -> cur_attno ;
5171
5162
}
5172
5163
else
5173
5164
{
5174
5165
/* error occurred in a scan against a foreign join */
5175
- ForeignScanState * fsstate = errpos -> fsstate ;
5176
- ForeignScan * fsplan = castNode (ForeignScan , fsstate -> ss .ps .plan );
5177
- EState * estate = fsstate -> ss .ps .state ;
5178
5166
TargetEntry * tle ;
5179
5167
5180
5168
tle = list_nth_node (TargetEntry , fsplan -> fdw_scan_tlist ,
5181
5169
errpos -> cur_attno - 1 );
5182
5170
5183
5171
/*
5184
5172
* Target list can have Vars and expressions. For Vars, we can get
5185
- * it's relation , however for expressions we can't. Thus for
5173
+ * some information , however for expressions we can't. Thus for
5186
5174
* expressions, just show generic context message.
5187
5175
*/
5188
5176
if (IsA (tle -> expr , Var ))
5189
5177
{
5190
- RangeTblEntry * rte ;
5191
5178
Var * var = (Var * ) tle -> expr ;
5192
5179
5193
- rte = rt_fetch (var -> varno , estate -> es_range_table );
5194
-
5195
- if (var -> varattno == 0 )
5196
- is_wholerow = true;
5197
- else
5198
- attname = get_relid_attribute_name (rte -> relid , var -> varattno );
5199
-
5200
- relname = get_rel_name (rte -> relid );
5180
+ varno = var -> varno ;
5181
+ colno = var -> varattno ;
5201
5182
}
5202
- else
5203
- errcontext ("processing expression at position %d in select list" ,
5204
- errpos -> cur_attno );
5205
5183
}
5206
5184
5207
- if (relname )
5185
+ if (varno > 0 )
5208
5186
{
5209
- if (is_wholerow )
5210
- errcontext ("whole-row reference to foreign table \"%s\"" , relname );
5211
- else if (attname )
5212
- errcontext ("column \"%s\" of foreign table \"%s\"" , attname , relname );
5187
+ EState * estate = fsstate -> ss .ps .state ;
5188
+ RangeTblEntry * rte = rt_fetch (varno , estate -> es_range_table );
5189
+
5190
+ relname = rte -> eref -> aliasname ;
5191
+
5192
+ if (colno == 0 )
5193
+ is_wholerow = true;
5194
+ else if (colno > 0 && colno <= list_length (rte -> eref -> colnames ))
5195
+ attname = strVal (list_nth (rte -> eref -> colnames , colno - 1 ));
5196
10000
code>
+ else if (colno == SelfItemPointerAttributeNumber )
5197
+ attname = "ctid" ;
5198
+ else if (colno == ObjectIdAttributeNumber )
5199
+ attname = "oid" ;
5213
5200
}
5201
+
5202
+ if (relname && is_wholerow )
5203
+ errcontext ("whole-row reference to foreign table \"%s\"" , relname );
5204
+ else if (relname && attname )
5205
+ errcontext ("column \"%s\" of foreign table \"%s\"" , attname , relname );
5206
+ else
5207
+ errcontext ("processing expression at position %d in select list" ,
5208
+ errpos -> cur_attno );
5214
5209
}
5215
5210
5216
5211
/*
0 commit comments