15
15
#include "planner_tree_modification.h"
16
16
#include "utils.h"
17
17
18
+ #include "catalog/pg_type.h"
18
19
#include "foreign/fdwapi.h"
19
20
#include "foreign/foreign.h"
20
21
#include "nodes/nodeFuncs.h"
@@ -65,7 +66,7 @@ CustomExecMethods partition_filter_exec_methods;
65
66
66
67
67
68
static 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 );
69
70
static Index append_rte_to_estate (EState * estate , RangeTblEntry * rte );
70
71
static int append_rri_to_estate (EState * estate , ResultRelInfo * rri );
71
72
static void prepare_rri_fdw_for_insert (EState * estate ,
@@ -317,10 +318,11 @@ find_partitions_for_value(Datum value, Oid value_type,
317
318
318
319
319
320
Plan *
320
- make_partition_filter (Plan * subplan , Oid partitioned_table ,
321
+ make_partition_filter (Plan * subplan , Oid parent_relid ,
321
322
OnConflictAction conflict_action )
322
323
{
323
324
CustomScan * cscan = makeNode (CustomScan );
325
+ Relation parent_rel ;
324
326
325
327
cscan -> scan .plan .startup_cost = subplan -> startup_cost ;
326
328
cscan -> scan .plan .total_cost = subplan -> total_cost ;
@@ -330,14 +332,17 @@ make_partition_filter(Plan *subplan, Oid partitioned_table,
330
332
cscan -> methods = & partition_filter_plan_methods ;
331
333
cscan -> custom_plans = list_make1 (subplan );
332
334
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 );
334
339
335
340
/* No relation will be scanned */
336
341
cscan -> scan .scanrelid = 0 ;
337
342
cscan -> custom_scan_tlist = subplan -> targetlist ;
338
343
339
344
/* 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 );
341
346
342
347
return & cscan -> scan .plan ;
343
348
}
@@ -755,25 +760,50 @@ append_rri_to_estate(EState *estate, ResultRelInfo *rri)
755
760
* Build partition filter's target list pointing to subplan tuple's elements
756
761
*/
757
762
static List *
758
- pfilter_build_tlist (List * tlist )
763
+ pfilter_build_tlist (Relation parent_rel , List * tlist )
759
764
{
760
765
List * result_tlist = NIL ;
761
766
ListCell * lc ;
762
767
int i = 1 ;
763
768
764
769
foreach (lc , tlist )
765
770
{
766
- TargetEntry * tle = (TargetEntry * ) lfirst (lc );
771
+ TargetEntry * tle = (TargetEntry * ) lfirst (lc );
772
+ Expr * col_expr ;
773
+ Form_pg_attribute attr ;
767
774
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
+ }
774
804
775
805
result_tlist = lappend (result_tlist ,
776
- makeTargetEntry (( Expr * ) var ,
806
+ makeTargetEntry (col_expr ,
777
807
i ,
778
808
NULL ,
779
809
tle -> resjunk ));
0 commit comments