Skip to content

Commit f78330f

Browse files
committed
Fix basic selects for range partitions
1 parent 62fdfd6 commit f78330f

File tree

3 files changed

+34
-84
lines changed

3 files changed

+34
-84
lines changed

src/hooks.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "miscadmin.h"
3030
#include "optimizer/cost.h"
3131
#include "optimizer/restrictinfo.h"
32+
#include "rewrite/rewriteManip.h"
3233
#include "utils/typcache.h"
3334
#include "utils/lsyscache.h"
3435

@@ -258,28 +259,22 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
258259
* Get pathkeys for ascending and descending sort by partitioned column.
259260
*/
260261
List *pathkeys;
261-
Var *var;
262-
Oid vartypeid,
263-
varcollid;
264-
int32 type_mod;
265262
TypeCacheEntry *tce;
263+
Node *expr;
266264

267-
/* Make Var from patition column */
268-
/* FIX: this */
269-
get_rte_attribute_type(rte, 0,
270-
&vartypeid, &type_mod, &varcollid);
271-
var = makeVar(rti, 0, vartypeid, type_mod, varcollid, 0);
272-
var->location = -1;
265+
expr = copyObject(prel->expr);
266+
if (rti != 1)
267+
ChangeVarNodes(expr, 1, rti, 0);
273268

274269
/* Determine operator type */
275-
tce = lookup_type_cache(var->vartype, TYPECACHE_LT_OPR | TYPECACHE_GT_OPR);
270+
tce = lookup_type_cache(prel->atttype, TYPECACHE_LT_OPR | TYPECACHE_GT_OPR);
276271

277272
/* Make pathkeys */
278-
pathkeys = build_expression_pathkey(root, (Expr *) var, NULL,
273+
pathkeys = build_expression_pathkey(root, (Expr *) expr, NULL,
279274
tce->lt_opr, NULL, false);
280275
if (pathkeys)
281276
pathkeyAsc = (PathKey *) linitial(pathkeys);
282-
pathkeys = build_expression_pathkey(root, (Expr *) var, NULL,
277+
pathkeys = build_expression_pathkey(root, (Expr *) expr, NULL,
283278
tce->gt_opr, NULL, false);
284279
if (pathkeys)
285280
pathkeyDesc = (PathKey *) linitial(pathkeys);

src/partition_filter.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "foreign/fdwapi.h"
2222
#include "foreign/foreign.h"
2323
#include "nodes/nodeFuncs.h"
24+
#include "rewrite/rewriteManip.h"
2425
#include "utils/guc.h"
2526
#include "utils/memutils.h"
2627
#include "utils/lsyscache.h"
@@ -609,7 +610,10 @@ partition_filter_exec(CustomScanState *node)
609610
Datum value;
610611
ExprDoneCond itemIsDone;
611612
ExprState *expr_state;
612-
struct expr_walker_context expr_walker_context;
613+
ListCell *lc;
614+
Index varno = 1;
615+
TupleTableSlot *tmp_slot;
616+
Node *expr;
613617

614618
/* Fetch PartRelationInfo for this partitioned relation */
615619
prel = get_pathman_relation_info(state->partitioned_table);
@@ -623,26 +627,34 @@ partition_filter_exec(CustomScanState *node)
623627
return slot;
624628
}
625629

626-
old_cxt = MemoryContextSwitchTo(estate->es_query_cxt);
627-
628-
/* Prepare walker context */
629-
expr_walker_context.prel = prel;
630-
expr_walker_context.slot = slot;
631-
expr_walker_context.tup = ExecCopySlotTuple(slot);
630+
/* Find proper varno for Vars in expression */
631+
foreach(lc, estate->es_range_table)
632+
{
633+
RangeTblEntry *entry = (RangeTblEntry *) lfirst(lc);
634+
if (entry->relid == prel->key)
635+
break;
632636

633-
/* Fetch values from slot for expression */
634-
adapt_values(prel->expr, (void *) &expr_walker_context);
637+
varno++;
638+
}
635639

636-
/* Prepare state for execution */
637-
expr_state = ExecInitExpr((Expr *)prel->expr, NULL);
640+
/* Change varno according to range table */
641+
expr = copyObject(prel->expr);
642+
if (varno != 1)
643+
ChangeVarNodes(expr, 1, varno, 0);
638644

645+
/* Prepare state for expression execution */
646+
old_cxt = MemoryContextSwitchTo(estate->es_query_cxt);
647+
expr_state = ExecInitExpr((Expr *) expr, NULL);
639648
MemoryContextSwitchTo(old_cxt);
640649

641650
/* Switch to per-tuple context */
642651
old_cxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
643652

644653
/* Execute expression */
654+
tmp_slot = econtext->ecxt_scantuple;
655+
econtext->ecxt_scantuple = slot;
645656
value = ExecEvalExpr(expr_state, econtext, &isnull, &itemIsDone);
657+
econtext->ecxt_scantuple = tmp_slot;
646658

647659
if (isnull)
648660
elog(ERROR, ERR_PART_ATTR_NULL);

src/relation_info.c

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,6 @@ static bool delayed_shutdown = false; /* pathman was dropped */
6868
list = NIL; \
6969
} while (0)
7070

71-
struct expr_mutator_context
72-
{
73-
Oid relid; /* partitioned table */
74-
List *rtable; /* range table list from expression query */
75-
};
76-
7771
static bool try_perform_parent_refresh(Oid parent);
7872
static Oid try_syscache_parent_search(Oid partition, PartParentSearch *status);
7973
static Oid get_parent_of_partition_internal(Oid partition,
@@ -92,8 +86,6 @@ static void fill_pbin_with_bounds(PartBoundInfo *pbin,
9286

9387
static int cmp_range_entries(const void *p1, const void *p2, void *arg);
9488

95-
static Node *expression_mutator(Node *node, struct expr_mutator_context *context);
96-
9789

9890
void
9991
init_relation_info_static_data(void)
@@ -133,7 +125,6 @@ refresh_pathman_relation_info(Oid relid,
133125
char *expr;
134126
HeapTuple tp;
135127
MemoryContext oldcontext;
136-
Node *tmp_node;
137128

138129
AssertTemporaryContext();
139130

@@ -191,16 +182,12 @@ refresh_pathman_relation_info(Oid relid,
191182
prel->atttype = DatumGetObjectId(values[Anum_pathman_config_atttype - 1]);
192183
expr = TextDatumGetCString(values[Anum_pathman_config_expression_p - 1]);
193184

194-
/* Restore planned expression */
195-
tmp_node = (Node *) stringToNode(expr);
196-
fix_opfuncids(tmp_node);
197-
pfree(expr);
198-
199-
/* expression and attname should be saved in cache context */
185+
/* Expression and attname should be saved in cache context */
200186
oldcontext = MemoryContextSwitchTo(PathmanRelationCacheContext);
201187

202-
prel->expr = expression_mutator(tmp_node, NULL);
203188
prel->attname = TextDatumGetCString(values[Anum_pathman_config_expression - 1]);
189+
prel->expr = (Node *) stringToNode(expr);
190+
fix_opfuncids(prel->expr);
204191

205192
MemoryContextSwitchTo(oldcontext);
206193

@@ -1195,47 +1182,3 @@ shout_if_prel_is_invalid(const Oid parent_oid,
11951182
expected_str);
11961183
}
11971184
}
1198-
1199-
1200-
/*
1201-
* To prevent calculation of Vars in expression, we wrap them with
1202-
* CustomConst, and later before execution we fill it with actual value
1203-
*/
1204-
static Node *
1205-
expression_mutator(Node *node, struct expr_mutator_context *context)
1206-
{
1207-
const TypeCacheEntry *typcache;
1208-
1209-
/* TODO: add RelabelType */
1210-
/* TODO: check Vars, they should only be related with base relation */
1211-
if (IsA(node, Var))
1212-
{
1213-
//Var *variable = (Var *) node;
1214-
Node *new_node = newNode(sizeof(CustomConst), T_Const);
1215-
Const *new_const = (Const *)new_node;
1216-
1217-
/*
1218-
RangeTblEntry *entry = rt_fetch(variable->varno, context->rtable);
1219-
if (entry->relid != context->relid)
1220-
elog(ERROR, "Columns in the expression should "
1221-
"be only from partitioned relation");
1222-
*/
1223-
1224-
/* we only need varattno from original Var, for now */
1225-
((CustomConst *)new_node)->varattno = ((Var *)node)->varattno;
1226-
1227-
new_const->consttype = ((Var *)node)->vartype;
1228-
new_const->consttypmod = ((Var *)node)->vartypmod;
1229-
new_const->constcollid = ((Var *)node)->varcollid;
1230-
new_const->constvalue = (Datum) 0;
1231-
new_const->constisnull = true;
1232-
new_const->location = -2;
1233-
1234-
typcache = lookup_type_cache(new_const->consttype, 0);
1235-
new_const->constbyval = typcache->typbyval;
1236-
new_const->constlen = typcache->typlen;
1237-
1238-
return new_node;
1239-
}
1240-
return expression_tree_mutator(node, expression_mutator, (void *) context);
1241-
}

0 commit comments

Comments
 (0)