@@ -2014,11 +2014,13 @@ addRangeTableEntryForENR(ParseState *pstate,
2014
2014
2015
2015
/*
2016
2016
* Build the list of effective column names using user-supplied aliases
2017
- * and/or actual column names. Also build the cannibalized fields.
2017
+ * and/or actual column names.
2018
2018
*/
2019
2019
tupdesc = ENRMetadataGetTupDesc (enrmd );
2020
2020
rte -> eref = makeAlias (refname , NIL );
2021
2021
buildRelationAliases (tupdesc , alias , rte -> eref );
2022
+
2023
+ /* Record additional data for ENR, including column type info */
2022
2024
rte -> enrname = enrmd -> name ;
2023
2025
rte -> enrtuples = enrmd -> enrtuples ;
2024
2026
rte -> coltypes = NIL ;
@@ -2028,16 +2030,24 @@ addRangeTableEntryForENR(ParseState *pstate,
2028
2030
{
2029
2031
Form_pg_attribute att = TupleDescAttr (tupdesc , attno - 1 );
2030
2032
2031
- if (att -> atttypid == InvalidOid &&
2032
- !(att -> attisdropped ))
2033
- elog (ERROR , "atttypid was invalid for column which has not been dropped from \"%s\"" ,
2034
- rv -> relname );
2035
- rte -> coltypes =
2036
- lappend_oid (rte -> coltypes , att -> atttypid );
2037
- rte -> coltypmods =
2038
- lappend_int (rte -> coltypmods , att -> atttypmod );
2039
- rte -> colcollations =
2040
- lappend_oid (rte -> colcollations , att -> attcollation );
2033
+ if (att -> attisdropped )
2034
+ {
2035
+ /* Record zeroes for a dropped column */
2036
+ rte -> coltypes = lappend_oid (rte -> coltypes , InvalidOid );
2037
+ rte -> coltypmods = lappend_int (rte -> coltypmods , 0 );
2038
+ rte -> colcollations = lappend_oid (rte -> colcollations , InvalidOid );
2039
+ }
2040
+ else
2041
+ {
2042
+ /* Let's just make sure we can tell this isn't dropped */
2043
+ if (att -> atttypid == InvalidOid )
2044
+ elog (ERROR , "atttypid is invalid for non-dropped column in \"%s\"" ,
2045
+ rv -> relname );
2046
+ rte -> coltypes = lappend_oid (rte -> coltypes , att -> atttypid );
2047
+ rte -> coltypmods = lappend_int (rte -> coltypmods , att -> atttypmod );
2048
+ rte -> colcollations = lappend_oid (rte -> colcollations ,
2049
+ att -> attcollation );
2050
+ }
2041
2051
}
2042
2052
2043
2053
/*
@@ -2416,7 +2426,7 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
2416
2426
case RTE_CTE :
2417
2427
case RTE_NAMEDTUPLESTORE :
2418
2428
{
2419
- /* Tablefunc, Values or CTE RTE */
2429
+ /* Tablefunc, Values, CTE, or ENR RTE */
2420
2430
ListCell * aliasp_item = list_head (rte -> eref -> colnames );
2421
2431
ListCell * lct ;
2422
2432
ListCell * lcm ;
@@ -2436,23 +2446,43 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
2436
2446
if (colnames )
2437
2447
{
2438
2448
/* Assume there is one alias per output column */
2439
- char * label = strVal (lfirst (aliasp_item ));
2449
+ if (OidIsValid (coltype ))
2450
+ {
2451
+ char * label = strVal (lfirst (aliasp_item ));
2452
+
2453
+ * colnames = lappend (* colnames ,
2454
+ makeString (pstrdup (label )));
2455
+ }
2456
+ else if (include_dropped )
2457
+ * colnames = lappend (* colnames ,
2458
+ makeString (pstrdup ("" )));
2440
2459
2441
- * colnames = lappend (* colnames ,
2442
- makeString (pstrdup (label )));
2443
2460
aliasp_item = lnext (aliasp_item );
2444
2461
}
2445
2462
2446
2463
if (colvars )
2447
2464
{
2448
- Var * varnode ;
2465
+ if (OidIsValid (coltype ))
2466
+ {
2467
+ Var * varnode ;
2449
2468
2450
- varnode = makeVar (rtindex , varattno ,
2451
- coltype , coltypmod , colcoll ,
2452
- sublevels_up );
2453
- varnode -> location = location ;
2469
+ varnode = makeVar (rtindex , varattno ,
2470
+ coltype , coltypmod , colcoll ,
2471
+ sublevels_up );
2472
+ varnode -> location = location ;
2454
2473
2455
- * colvars = lappend (* colvars , varnode );
2474
+ * colvars = lappend (* colvars , varnode );
2475
+ }
2476
+ else if (include_dropped )
2477
+ {
2478
+ /*
2479
+ * It doesn't really matter what type the Const
2480
+ * claims to be.
2481
+ */
2482
+ * colvars = lappend (* colvars ,
2483
+ makeNullConst (INT4OID , -1 ,
2484
+ InvalidOid ));
2485
+ }
2456
2486
}
2457
2487
}
2458
2488
}
@@ -2831,13 +2861,21 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
2831
2861
case RTE_NAMEDTUPLESTORE :
2832
2862
{
2833
2863
/*
2834
- * tablefunc, VALUES or CTE RTE --- get type info from lists
2835
- * in the RTE
2864
+ * tablefunc, VALUES, CTE, or ENR RTE --- get type info from
2865
+ * lists in the RTE
2836
2866
*/
2837
2867
Assert (attnum > 0 && attnum <= list_length (rte -> coltypes ));
2838
2868
* vartype = list_nth_oid (rte -> coltypes , attnum - 1 );
2839
2869
* vartypmod = list_nth_int (rte -> coltypmods , attnum - 1 );
2840
2870
* varcollid = list_nth_oid (rte -> colcollations , attnum - 1 );
2871
+
2872
+ /* For ENR, better check for dropped column */
2873
+ if (!OidIsValid (* vartype ))
2874
+ ereport (ERROR ,
2875
+ (errcode (ERRCODE_UNDEFINED_COLUMN ),
2876
+ errmsg ("column %d of relation \"%s\" does not exist" ,
2877
+ attnum ,
2878
+ rte -> eref -> aliasname )));
2841
2879
}
2842
2880
break ;
2843
2881
default :
@@ -2888,15 +2926,11 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
2888
2926
break ;
2889
2927
case RTE_NAMEDTUPLESTORE :
2890
2928
{
2891
- Assert (rte -> enrname );
2892
-
2893
- /*
2894
- * We checked when we loaded coltypes for the tuplestore that
2895
- * InvalidOid was only used for dropped columns, so it is safe
2896
- * to count on that here.
2897
- */
2898
- result =
2899
- ((list_nth_oid (rte -> coltypes , attnum - 1 ) == InvalidOid ));
2929
+ /* Check dropped-ness by testing for valid coltype */
2930
+ if (attnum <= 0 ||
2931
+ attnum > list_length (rte -> coltypes ))
2932
+ elog (ERROR , "invalid varattno %d" , attnum );
2933
+ result = !OidIsValid ((list_nth_oid (rte -> coltypes , attnum - 1 )));
2900
2934
}
2901
2935
break ;
2902
2936
case RTE_JOIN :
0 commit comments