1515#include "planner_tree_modification.h"
1616#include "utils.h"
1717
18+ #include "catalog/pg_type.h"
1819#include "foreign/fdwapi.h"
1920#include "foreign/foreign.h"
2021#include "nodes/nodeFuncs.h"
@@ -65,7 +66,7 @@ CustomExecMethodspartition_filter_exec_methods;
6566
6667
6768static estate_mod_data * fetch_estate_mod_data (EState * estate );
68- static List * pfilter_build_tlist (List * tlist );
69+ static List * pfilter_build_tlist (Relation parent_rel , List * tlist );
6970static Index append_rte_to_estate (EState * estate ,RangeTblEntry * rte );
7071static int append_rri_to_estate (EState * estate ,ResultRelInfo * rri );
7172static void prepare_rri_fdw_for_insert (EState * estate ,
@@ -317,10 +318,11 @@ find_partitions_for_value(Datum value, Oid value_type,
317318
318319
319320Plan *
320- make_partition_filter (Plan * subplan ,Oid partitioned_table ,
321+ make_partition_filter (Plan * subplan ,Oid parent_relid ,
321322OnConflictAction conflict_action )
322323{
323324CustomScan * cscan = makeNode (CustomScan );
325+ Relation parent_rel ;
324326
325327cscan -> scan .plan .startup_cost = subplan -> startup_cost ;
326328cscan -> scan .plan .total_cost = subplan -> total_cost ;
@@ -330,14 +332,17 @@ make_partition_filter(Plan *subplan, Oid partitioned_table,
330332cscan -> methods = & partition_filter_plan_methods ;
331333cscan -> custom_plans = list_make1 (subplan );
332334
333- cscan -> scan .plan .targetlist = pfilter_build_tlist (subplan -> targetlist );
335+ parent_rel = RelationIdGetRelation (parent_relid );
336+ cscan -> scan .plan .targetlist = pfilter_build_tlist (parent_rel ,
337+ subplan -> targetlist );
338+ RelationClose (parent_rel );
334339
335340/* No relation will be scanned */
336341cscan -> scan .scanrelid = 0 ;
337342cscan -> custom_scan_tlist = subplan -> targetlist ;
338343
339344/* Pack partitioned table's Oid and conflict_action */
340- cscan -> custom_private = list_make2_int (partitioned_table ,conflict_action );
345+ cscan -> custom_private = list_make2_int (parent_relid ,conflict_action );
341346
342347return & cscan -> scan .plan ;
343348}
@@ -755,25 +760,50 @@ append_rri_to_estate(EState *estate, ResultRelInfo *rri)
755760 * Build partition filter's target list pointing to subplan tuple's elements
756761 */
757762static List *
758- pfilter_build_tlist (List * tlist )
763+ pfilter_build_tlist (Relation parent_rel , List * tlist )
759764{
760765List * result_tlist = NIL ;
761766ListCell * lc ;
762767int i = 1 ;
763768
764769foreach (lc ,tlist )
765770{
766- TargetEntry * tle = (TargetEntry * )lfirst (lc );
771+ TargetEntry * tle = (TargetEntry * )lfirst (lc );
772+ Expr * col_expr ;
773+ Form_pg_attribute attr ;
767774
768- Var * var = makeVar (INDEX_VAR ,/* point to subplan's elements */
769- i ,/* direct attribute mapping */
770- exprType ((Node * )tle -> expr ),
771- exprTypmod ((Node * )tle -> expr ),
772- exprCollation ((Node * )tle -> expr ),
773- 0 );
775+ /* Make sure that this attribute exists */
776+ if (i > RelationGetDescr (parent_rel )-> natts )
777+ elog (ERROR ,"error in function " CppAsString (pfilter_build_tlist ));
778+
779+ /* Fetch pg_attribute entry for this column */
780+ attr = RelationGetDescr (parent_rel )-> attrs [i - 1 ];
781+
782+ /* If this column is dropped, create a placeholder Const */
783+ if (attr -> attisdropped )
784+ {
785+ /* Insert NULL for dropped column */
786+ col_expr = (Expr * )makeConst (INT4OID ,
787+ -1 ,
788+ InvalidOid ,
789+ sizeof (int32 ),
790+ (Datum )0 ,
791+ true,
792+ true);
793+ }
794+ /* Otherwise we should create a Var referencing subplan's output */
795+ else
796+ {
797+ col_expr = (Expr * )makeVar (INDEX_VAR ,/* point to subplan's elements */
798+ i ,/* direct attribute mapping */
799+ exprType ((Node * )tle -> expr ),
800+ exprTypmod ((Node * )tle -> expr ),
801+ exprCollation ((Node * )tle -> expr ),
802+ 0 );
803+ }
774804
775805result_tlist = lappend (result_tlist ,
776- makeTargetEntry (( Expr * ) var ,
806+ makeTargetEntry (col_expr ,
777807i ,
778808NULL ,
779809tle -> resjunk ));