@@ -253,16 +253,8 @@ typedef struct PgFdwAnalyzeState
253
253
*/
254
254
typedef struct ConversionLocation
255
255
{
256
- Relation rel ; /* foreign table's relcache entry. */
257
256
AttrNumber cur_attno ; /* attribute number being processed, or 0 */
258
-
259
- /*
260
- * In case of foreign join push down, fdw_scan_tlist is used to identify
261
- * the Var node corresponding to the error location and
262
- * fsstate->ss.ps.state gives access to the RTEs of corresponding relation
263
- * to get the relation name and attribute name.
264
- */
265
- ForeignScanState * fsstate ;
257
+ ForeignScanState * fsstate ; /* plan node being processed */
266
258
} ConversionLocation ;
267
259
268
260
/* Callback argument for ec_member_matches_foreign */
@@ -5695,7 +5687,6 @@ make_tuple_from_result_row(PGresult *res,
5695
5687
/*
5696
5688
* Set up and install callback to report where conversion error occurs.
5697
5689
*/
5698
- errpos .rel = rel ;
5699
5690
errpos .cur_attno = 0 ;
5700
5691
errpos .fsstate = fsstate ;
5701
5692
errcallback .callback = conversion_error_callback ;
@@ -5815,72 +5806,75 @@ make_tuple_from_result_row(PGresult *res,
5815
5806
/*
5816
5807
* Callback function which is called when error occurs during column value
5817
5808
* conversion. Print names of column and relation.
5809
+ *
5810
+ * Note that this function mustn't do any catalog lookups, since we are in
5811
+ * an already-failed transaction. Fortunately, we can get the needed info
5812
+ * from the query's rangetable instead.
5818
5813
*/
5819
5814
static void
5820
5815
conversion_error_callback (void * arg )
5821
5816
{
5817
+ ConversionLocation * errpos = (ConversionLocation * ) arg ;
5818
+ ForeignScanState * fsstate = errpos -> fsstate ;
5819
+ ForeignScan * fsplan = castNode (ForeignScan , fsstate -> ss .ps .plan );
5820
+ int varno = 0 ;
5821
+ AttrNumber colno = 0 ;
5822
5822
const char * attname = NULL ;
5823
5823
const char * relname = NULL ;
5824
5824
bool is_wholerow = false;
5825
- ConversionLocation * errpos = (ConversionLocation * ) arg ;
5826
5825
5827
- if (errpos -> rel )
5826
+ if (fsplan -> scan . scanrelid > 0 )
5828
5827
{
5829
5828
/* error occurred in a scan against a foreign table */
5830
- TupleDesc tupdesc = RelationGetDescr (errpos -> rel );
5831
- Form_pg_attribute attr = TupleDescAttr (tupdesc , errpos -> cur_attno - 1 );
5832
-
5833
- if (errpos -> cur_attno > 0 && errpos -> cur_attno <= tupdesc -> natts )
5834
- attname = NameStr (attr -> attname );
5835
- else if (errpos -> cur_attno == SelfItemPointerAttributeNumber )
5836
- attname = "ctid" ;
5837
- else if (errpos -> cur_attno == ObjectIdAttributeNumber )
5838
- attname = "oid" ;
5839
-
5840
- relname = RelationGetRelationName (errpos -> rel );
5829
+ varno = fsplan -> scan .scanrelid ;
5830
+ colno = errpos -> cur_attno ;
5841
5831
}
5842
5832
else
5843
5833
{
5844
5834
/* error occurred in a scan against a foreign join */
5845
- ForeignScanState * fsstate = errpos -> fsstate ;
5846
- ForeignScan * fsplan = castNode (ForeignScan , fsstate -> ss .ps .plan );
5847
- EState * estate = fsstate -> ss .ps .state ;
5848
5835
TargetEntry * tle ;
5849
5836
5850
5837
tle = list_nth_node (TargetEntry , fsplan -> fdw_scan_tlist ,
5851
5838
errpos -> cur_attno - 1 );
5852
5839
5853
5840
/*
5854
5841
* Target list can have Vars and expressions. For Vars, we can get
5855
- * its relation , however for expressions we can't. Thus for
5842
+ * some information , however for expressions we can't. Thus for
5856
5843
* expressions, just show generic context message.
5857
5844
*/
5858
5845
if (IsA (tle -> expr , Var ))
5859
5846
{
5860
- RangeTblEntry * rte ;
5861
5847
Var * var = (Var * ) tle -> expr ;
5862
5848
5863
- rte = rt_fetch (var -> varno , estate -> es_range_table );
5864
-
5865
- if (var -> varattno == 0 )
5866
- is_wholerow = true;
5867
- else
5868
- attname = get_attname (rte -> relid , var -> varattno , false);
5869
-
5870
- relname = get_rel_name (rte -> relid );
5849
+ varno = var -> varno ;
5850
+ colno = var -> varattno ;
5871
5851
}
5872
- else
5873
- errcontext ("processing expression at position %d in select list" ,
5874
- errpos -> cur_attno );
5875
5852
}
5876
5853
5877
- if (relname )
5854
+ if (varno > 0 )
5878
5855
{
5879
- if (is_wholerow )
5880
- errcontext ("whole-row reference to foreign table \"%s\"" , relname );
5881
- else if (attname )
5882
- errcontext ("column \"%s\" of foreign table \"%s\"" , attname , relname );
5856
+ EState * estate = fsstate -> ss .ps .state ;
5857
+ RangeTblEntry * rte = rt_fetch (varno , estate -> es_range_table );
5858
+
5859
+ relname = rte -> eref -> aliasname ;
5860
+
5861
+ if (colno == 0 )
5862
+ is_wholerow = true;
5863
+ else if (colno > 0 && colno <= list_length (rte -> eref -> colnames ))
5864
+ attname = strVal (list_nth (rte -> eref -> colnames , colno - 1 ));
5865
+ else if (colno == SelfItemPointerAttributeNumber )
5866
+ attname = "ctid" ;
5867
+ else if (colno == ObjectIdAttributeNumber )
5868
+ attname = "oid" ;
5883
5869
}
5870
+
5871
+ if (relname && is_wholerow )
5872
+ errcontext ("whole-row reference to foreign table \"%s\"" , relname );
5873
+ else if (relname && attname )
5874
+ errcontext ("column \"%s\" of foreign table \"%s\"" , attname , relname );
5875
+ else
5876
+ errcontext ("processing expression at position %d in select list" ,
5877
+ errpos -> cur_attno );
5884
5878
}
5885
5879
5886
5880
/*
0 commit comments