@@ -106,10 +106,12 @@ static void deparseTargetList(StringInfo buf,
106106PlannerInfo * root ,
107107Index rtindex ,
108108Relation rel ,
109- Bitmapset * attrs_used );
109+ Bitmapset * attrs_used ,
110+ List * * retrieved_attrs );
110111static void deparseReturningList (StringInfo buf ,PlannerInfo * root ,
111112Index rtindex ,Relation rel ,
112- List * returningList );
113+ List * returningList ,
114+ List * * retrieved_attrs );
113115static void deparseColumnRef (StringInfo buf ,int varno ,int varattno ,
114116PlannerInfo * root );
115117static void deparseRelation (StringInfo buf ,Relation rel );
@@ -652,12 +654,16 @@ is_builtin(Oid oid)
652654 * Construct a simple SELECT statement that retrieves desired columns
653655 * of the specified foreign table, and append it to "buf".The output
654656 * contains just "SELECT ... FROM tablename".
657+ *
658+ * We also create an integer List of the columns being retrieved, which is
659+ * returned to *retrieved_attrs.
655660 */
656661void
657662deparseSelectSql (StringInfo buf ,
658663PlannerInfo * root ,
659664RelOptInfo * baserel ,
660- Bitmapset * attrs_used )
665+ Bitmapset * attrs_used ,
666+ List * * retrieved_attrs )
661667{
662668RangeTblEntry * rte = planner_rt_fetch (baserel -> relid ,root );
663669Relation rel ;
@@ -672,7 +678,8 @@ deparseSelectSql(StringInfo buf,
672678 * Construct SELECT list
673679 */
674680appendStringInfoString (buf ,"SELECT " );
675- deparseTargetList (buf ,root ,baserel -> relid ,rel ,attrs_used );
681+ deparseTargetList (buf ,root ,baserel -> relid ,rel ,attrs_used ,
682+ retrieved_attrs );
676683
677684/*
678685 * Construct FROM clause
@@ -687,24 +694,24 @@ deparseSelectSql(StringInfo buf,
687694 * Emit a target list that retrieves the columns specified in attrs_used.
688695 * This is used for both SELECT and RETURNING targetlists.
689696 *
690- * We list attributes in order of the foreign table's columns, but replace
691- * any attributes that need not be fetched with NULL constants. (We can't
692- * just omit such attributes, or we'll lose track of which columns are
693- * which at runtime.) Note however that any dropped columns are ignored.
694- * Also, if ctid needs to be retrieved, it's added at the end.
697+ * The tlist text is appended to buf, and we also create an integer List
698+ * of the columns being retrieved, which is returned to *retrieved_attrs.
695699 */
696700static void
697701deparseTargetList (StringInfo buf ,
698702PlannerInfo * root ,
699703Index rtindex ,
700704Relation rel ,
701- Bitmapset * attrs_used )
705+ Bitmapset * attrs_used ,
706+ List * * retrieved_attrs )
702707{
703708TupleDesc tupdesc = RelationGetDescr (rel );
704709bool have_wholerow ;
705710bool first ;
706711int i ;
707712
713+ * retrieved_attrs = NIL ;
714+
708715/* If there's a whole-row reference, we'll need all the columns. */
709716have_wholerow = bms_is_member (0 - FirstLowInvalidHeapAttributeNumber ,
710717attrs_used );
@@ -718,16 +725,18 @@ deparseTargetList(StringInfo buf,
718725if (attr -> attisdropped )
719726continue ;
720727
721- if (!first )
722- appendStringInfoString (buf ,", " );
723- first = false;
724-
725728if (have_wholerow ||
726729bms_is_member (i - FirstLowInvalidHeapAttributeNumber ,
727730attrs_used ))
731+ {
732+ if (!first )
733+ appendStringInfoString (buf ,", " );
734+ first = false;
735+
728736deparseColumnRef (buf ,rtindex ,i ,root );
729- else
730- appendStringInfoString (buf ,"NULL" );
737+
738+ * retrieved_attrs = lappend_int (* retrieved_attrs ,i );
739+ }
731740}
732741
733742/*
@@ -742,6 +751,9 @@ deparseTargetList(StringInfo buf,
742751first = false;
743752
744753appendStringInfoString (buf ,"ctid" );
754+
755+ * retrieved_attrs = lappend_int (* retrieved_attrs ,
756+ SelfItemPointerAttributeNumber );
745757}
746758
747759/* Don't generate bad syntax if no undropped columns */
@@ -809,11 +821,16 @@ appendWhereClause(StringInfo buf,
809821
810822/*
811823 * deparse remote INSERT statement
824+ *
825+ * The statement text is appended to buf, and we also create an integer List
826+ * of the columns being retrieved by RETURNING (if any), which is returned
827+ * to *retrieved_attrs.
812828 */
813829void
814830deparseInsertSql (StringInfo buf ,PlannerInfo * root ,
815831Index rtindex ,Relation rel ,
816- List * targetAttrs ,List * returningList )
832+ List * targetAttrs ,List * returningList ,
833+ List * * retrieved_attrs )
817834{
818835AttrNumber pindex ;
819836bool first ;
@@ -858,16 +875,24 @@ deparseInsertSql(StringInfo buf, PlannerInfo *root,
858875appendStringInfoString (buf ," DEFAULT VALUES" );
859876
860877if (returningList )
861- deparseReturningList (buf ,root ,rtindex ,rel ,returningList );
878+ deparseReturningList (buf ,root ,rtindex ,rel ,returningList ,
879+ retrieved_attrs );
880+ else
881+ * retrieved_attrs = NIL ;
862882}
863883
864884/*
865885 * deparse remote UPDATE statement
886+ *
887+ * The statement text is appended to buf, and we also create an integer List
888+ * of the columns being retrieved by RETURNING (if any), which is returned
889+ * to *retrieved_attrs.
866890 */
867891void
868892deparseUpdateSql (StringInfo buf ,PlannerInfo * root ,
869893Index rtindex ,Relation rel ,
870- List * targetAttrs ,List * returningList )
894+ List * targetAttrs ,List * returningList ,
895+ List * * retrieved_attrs )
871896{
872897AttrNumber pindex ;
873898bool first ;
@@ -894,23 +919,34 @@ deparseUpdateSql(StringInfo buf, PlannerInfo *root,
894919appendStringInfoString (buf ," WHERE ctid = $1" );
895920
896921if (returningList )
897- deparseReturningList (buf ,root ,rtindex ,rel ,returningList );
922+ deparseReturningList (buf ,root ,rtindex ,rel ,returningList ,
923+ retrieved_attrs );
924+ else
925+ * retrieved_attrs = NIL ;
898926}
899927
900928/*
901929 * deparse remote DELETE statement
930+ *
931+ * The statement text is appended to buf, and we also create an integer List
932+ * of the columns being retrieved by RETURNING (if any), which is returned
933+ * to *retrieved_attrs.
902934 */
903935void
904936deparseDeleteSql (StringInfo buf ,PlannerInfo * root ,
905937Index rtindex ,Relation rel ,
906- List * returningList )
938+ List * returningList ,
939+ List * * retrieved_attrs )
907940{
908941appendStringInfoString (buf ,"DELETE FROM " );
909942deparseRelation (buf ,rel );
910943appendStringInfoString (buf ," WHERE ctid = $1" );
911944
912945if (returningList )
913- deparseReturningList (buf ,root ,rtindex ,rel ,returningList );
946+ deparseReturningList (buf ,root ,rtindex ,rel ,returningList ,
947+ retrieved_attrs );
948+ else
949+ * retrieved_attrs = NIL ;
914950}
915951
916952/*
@@ -919,7 +955,8 @@ deparseDeleteSql(StringInfo buf, PlannerInfo *root,
919955static void
920956deparseReturningList (StringInfo buf ,PlannerInfo * root ,
921957Index rtindex ,Relation rel ,
922- List * returningList )
958+ List * returningList ,
959+ List * * retrieved_attrs )
923960{
924961Bitmapset * attrs_used ;
925962
@@ -931,7 +968,8 @@ deparseReturningList(StringInfo buf, PlannerInfo *root,
931968& attrs_used );
932969
933970appendStringInfoString (buf ," RETURNING " );
934- deparseTargetList (buf ,root ,rtindex ,rel ,attrs_used );
971+ deparseTargetList (buf ,root ,rtindex ,rel ,attrs_used ,
972+ retrieved_attrs );
935973}
936974
937975/*
@@ -959,10 +997,11 @@ deparseAnalyzeSizeSql(StringInfo buf, Relation rel)
959997/*
960998 * Construct SELECT statement to acquire sample rows of given relation.
961999 *
962- * Note: command is appended to whatever might be in buf already.
1000+ * SELECT command is appended to buf, and list of columns retrieved
1001+ * is returned to *retrieved_attrs.
9631002 */
9641003void
965- deparseAnalyzeSql (StringInfo buf ,Relation rel )
1004+ deparseAnalyzeSql (StringInfo buf ,Relation rel , List * * retrieved_attrs )
9661005{
9671006Oid relid = RelationGetRelid (rel );
9681007TupleDesc tupdesc = RelationGetDescr (rel );
@@ -972,6 +1011,8 @@ deparseAnalyzeSql(StringInfo buf, Relation rel)
9721011ListCell * lc ;
9731012bool first = true;
9741013
1014+ * retrieved_attrs = NIL ;
1015+
9751016appendStringInfoString (buf ,"SELECT " );
9761017for (i = 0 ;i < tupdesc -> natts ;i ++ )
9771018{
@@ -999,6 +1040,8 @@ deparseAnalyzeSql(StringInfo buf, Relation rel)
9991040}
10001041
10011042appendStringInfoString (buf ,quote_identifier (colname ));
1043+
1044+ * retrieved_attrs = lappend_int (* retrieved_attrs ,i + 1 );
10021045}
10031046
10041047/* Don't generate bad syntax for zero-column relation. */