Skip to content

Commit cd5e53b

Browse files
committed
fix for variables wrapped into RelabelType
1 parent 115dc68 commit cd5e53b

File tree

2 files changed

+107
-35
lines changed

2 files changed

+107
-35
lines changed

src/init.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,10 @@ load_check_constraints(Oid parent_oid, Snapshot snapshot)
362362
case PT_RANGE:
363363
if (!validate_range_constraint(expr, prel, &min, &max))
364364
{
365-
elog(WARNING, "Range constraint for relation %u MUST have exact format: "
365+
elog(WARNING, "Wrong CHECK constraint for relation '%s'. "
366+
"It MUST have exact format: "
366367
"VARIABLE >= CONST AND VARIABLE < CONST. Skipping...",
367-
(Oid) con->conrelid);
368+
get_rel_name(con->conrelid));
368369
continue;
369370
}
370371

@@ -387,9 +388,9 @@ load_check_constraints(Oid parent_oid, Snapshot snapshot)
387388
case PT_HASH:
388389
if (!validate_hash_constraint(expr, prel, &hash))
389390
{
390-
elog(WARNING, "Hash constraint for relation %u MUST have exact format: "
391-
"VARIABLE %% CONST = CONST. Skipping...",
392-
(Oid) con->conrelid);
391+
elog(WARNING, "Wrong CHECK constraint format for relation '%s'. "
392+
"Skipping...",
393+
get_rel_name(con->conrelid));
393394
continue;
394395
}
395396
children[hash] = con->conrelid;
@@ -546,11 +547,15 @@ validate_hash_constraint(Expr *expr, PartRelationInfo *prel, int *hash)
546547

547548
/* Check that function is the base hash function for the type */
548549
funcexpr = (FuncExpr *) first;
549-
if (funcexpr->funcid != prel->hash_proc || !IsA(linitial(funcexpr->args), Var))
550+
if (funcexpr->funcid != prel->hash_proc ||
551+
(!IsA(linitial(funcexpr->args), Var) && !IsA(linitial(funcexpr->args), RelabelType)))
550552
return false;
551553

552554
/* Check that argument is partitioning key attribute */
553-
var = (Var *) linitial(funcexpr->args);
555+
if (IsA(linitial(funcexpr->args), RelabelType))
556+
var = (Var *) ((RelabelType *) linitial(funcexpr->args))->arg;
557+
else
558+
var = (Var *) linitial(funcexpr->args);
554559
if (var->varattno != prel->attnum)
555560
return false;
556561

src/pg_pathman.c

Lines changed: 95 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,16 @@ static bool disable_inheritance_subselect_walker(Node *node, void *context);
7979
/* Expression tree handlers */
8080
static Datum increase_hashable_value(const PartRelationInfo *prel, Datum value);
8181
static Datum decrease_hashable_value(const PartRelationInfo *prel, Datum value);
82-
static void handle_binary_opexpr(WalkerContext *context, WrapperNode *result, const Var *v, const Const *c);
82+
static void handle_binary_opexpr(WalkerContext *context, WrapperNode *result, const Node *varnode, const Const *c);
83+
static void handle_binary_opexpr_param(const PartRelationInfo *prel, WrapperNode *result, const Node *varnode);
8384
static WrapperNode *handle_opexpr(const OpExpr *expr, WalkerContext *context);
8485
static WrapperNode *handle_boolexpr(const BoolExpr *expr, WalkerContext *context);
8586
static WrapperNode *handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context);
8687
static void change_varnos_in_restrinct_info(RestrictInfo *rinfo, change_varno_context *context);
8788
static void change_varnos(Node *node, Oid old_varno, Oid new_varno);
8889
static bool change_varno_walker(Node *node, change_varno_context *context);
8990
static RestrictInfo *rebuild_restrictinfo(Node *clause, RestrictInfo *old_rinfo);
91+
static bool pull_var_param(const WalkerContext *ctx, const OpExpr *expr, Node **var_ptr, Node **param_ptr);
9092

9193
/* copied from allpaths.h */
9294
static void set_plain_rel_size(PlannerInfo *root, RelOptInfo *rel,
@@ -966,7 +968,7 @@ decrease_hashable_value(const PartRelationInfo *prel, Datum value)
966968
*/
967969
static void
968970
handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
969-
const Var *v, const Const *c)
971+
const Node *varnode, const Const *c)
970972
{
971973
HashRelationKey key;
972974
RangeRelation *rangerel;
@@ -978,18 +980,25 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
978980
is_greater;
979981
FmgrInfo cmp_func;
980982
Oid cmp_proc_oid;
983+
Oid vartype;
981984
const OpExpr *expr = (const OpExpr *)result->orig;
982985
TypeCacheEntry *tce;
983986
const PartRelationInfo *prel = context->prel;
984987

988+
Assert(IsA(varnode, Var) || IsA(varnode, RelableType));
989+
990+
vartype = !IsA(varnode, RelabelType) ?
991+
((Var *) varnode)->vartype :
992+
((RelabelType *) varnode)->resulttype;
993+
985994
/* Determine operator type */
986-
tce = lookup_type_cache(v->vartype,
995+
tce = lookup_type_cache(vartype,
987996
TYPECACHE_BTREE_OPFAMILY | TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO);
988997

989998
strategy = get_op_opfamily_strategy(expr->opno, tce->btree_opf);
990999
cmp_proc_oid = get_opfamily_proc(tce->btree_opf,
1000+
vartype,
9911001
c->consttype,
992-
prel->atttype,
9931002
BTORDER_PROC);
9941003
fmgr_info(cmp_proc_oid, &cmp_func);
9951004

@@ -1032,6 +1041,7 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
10321041
result->rangeset = list_make1_irange(make_irange(key.hash, key.hash, true));
10331042
return;
10341043
}
1044+
break;
10351045
case PT_RANGE:
10361046
value = c->constvalue;
10371047
rangerel = get_pathman_range_relation(prel->key.relid, NULL);
@@ -1191,14 +1201,21 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
11911201
*/
11921202
static void
11931203
handle_binary_opexpr_param(const PartRelationInfo *prel,
1194-
WrapperNode *result, const Var *v)
1204+
WrapperNode *result, const Node *varnode)
11951205
{
11961206
const OpExpr *expr = (const OpExpr *)result->orig;
11971207
TypeCacheEntry *tce;
11981208
int strategy;
1209+
Oid vartype;
1210+
1211+
Assert(IsA(varnode, Var) || IsA(varnode, RelableType));
1212+
1213+
vartype = !IsA(varnode, RelabelType) ?
1214+
((Var *) varnode)->vartype :
1215+
((RelabelType *) varnode)->resulttype;
11991216

12001217
/* Determine operator type */
1201-
tce = lookup_type_cache(v->vartype, TYPECACHE_BTREE_OPFAMILY);
1218+
tce = lookup_type_cache(vartype, TYPECACHE_BTREE_OPFAMILY);
12021219
strategy = get_op_opfamily_strategy(expr->opno, tce->btree_opf);
12031220

12041221
result->rangeset = list_make1_irange(make_irange(0, prel->children_count - 1, true));
@@ -1306,38 +1323,24 @@ static WrapperNode *
13061323
handle_opexpr(const OpExpr *expr, WalkerContext *context)
13071324
{
13081325
WrapperNode *result = (WrapperNode *)palloc(sizeof(WrapperNode));
1309-
Node *firstarg = NULL,
1310-
*secondarg = NULL;
1326+
Node *var, *param;
13111327
const PartRelationInfo *prel = context->prel;
13121328

13131329
result->orig = (const Node *)expr;
13141330
result->args = NIL;
13151331

13161332
if (list_length(expr->args) == 2)
13171333
{
1318-
if (IsA(linitial(expr->args), Var)
1319-
&& ((Var *)linitial(expr->args))->varoattno == prel->attnum)
1320-
{
1321-
firstarg = (Node *) linitial(expr->args);
1322-
secondarg = (Node *) lsecond(expr->args);
1323-
}
1324-
else if (IsA(lsecond(expr->args), Var)
1325-
&& ((Var *)lsecond(expr->args))->varoattno == prel->attnum)
1326-
{
1327-
firstarg = (Node *) lsecond(expr->args);
1328-
secondarg = (Node *) linitial(expr->args);
1329-
}
1330-
1331-
if (firstarg && secondarg)
1334+
if (pull_var_param(context, expr, &var, &param))
13321335
{
1333-
if (IsConstValue(context, secondarg))
1336+
if (IsConstValue(context, param))
13341337
{
1335-
handle_binary_opexpr(context, result, (Var *)firstarg, ExtractConst(context, secondarg));
1338+
handle_binary_opexpr(context, result, var, ExtractConst(context, param));
13361339
return result;
13371340
}
1338-
else if (IsA(secondarg, Param) || IsA(secondarg, Var))
1341+
else if (IsA(param, Param) || IsA(param, Var))
13391342
{
1340-
handle_binary_opexpr_param(prel, result, (Var *)firstarg);
1343+
handle_binary_opexpr_param(prel, result, var);
13411344
return result;
13421345
}
13431346
}
@@ -1348,6 +1351,54 @@ handle_opexpr(const OpExpr *expr, WalkerContext *context)
13481351
return result;
13491352
}
13501353

1354+
/*
1355+
* Checks if expression is a KEY OP PARAM or PARAM OP KEY,
1356+
* where KEY is partition key (it could be Var or RelableType) and PARAM is
1357+
* whatever. Function returns variable (or RelableType) and param via var_ptr
1358+
* and param_ptr pointers. If partition key isn't in expression then function
1359+
* returns false.
1360+
*/
1361+
static bool
1362+
pull_var_param(const WalkerContext *ctx, const OpExpr *expr, Node **var_ptr, Node **param_ptr)
1363+
{
1364+
Node *left = linitial(expr->args),
1365+
*right = lsecond(expr->args);
1366+
Var *v = NULL;
1367+
1368+
/* Check the case when variable is on the left side */
1369+
if (IsA(left, Var) || IsA(left, RelabelType))
1370+
{
1371+
v = !IsA(left, RelabelType) ?
1372+
(Var *) left :
1373+
(Var *) ((RelabelType *) left)->arg;
1374+
1375+
if (v->varattno == ctx->prel->attnum)
1376+
{
1377+
*var_ptr = left;
1378+
*param_ptr = right;
1379+
return true;
1380+
}
1381+
}
1382+
1383+
/* ... variable is on the right side */
1384+
if (IsA(right, Var) || IsA(right, RelabelType))
1385+
{
1386+
v = !IsA(right, RelabelType) ?
1387+
(Var *) right :
1388+
(Var *) ((RelabelType *) right)->arg;
1389+
1390+
if (v->varattno == ctx->prel->attnum)
1391+
{
1392+
*var_ptr = right;
1393+
*param_ptr = left;
1394+
return true;
1395+
}
1396+
}
1397+
1398+
/* Variable isn't a partitionig key */
1399+
return false;
1400+
}
1401+
13511402
/*
13521403
* Boolean expression handler
13531404
*/
@@ -1414,6 +1465,7 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
14141465
{
14151466
WrapperNode *result = (WrapperNode *)palloc(sizeof(WrapperNode));
14161467
Node *varnode = (Node *) linitial(expr->args);
1468+
Var *var;
14171469
Node *arraynode = (Node *) lsecond(expr->args);
14181470
int hash;
14191471
const PartRelationInfo *prel = context->prel;
@@ -1422,8 +1474,18 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
14221474
result->args = NIL;
14231475
result->paramsel = 1.0;
14241476

1477+
Assert(varnode != NULL);
1478+
14251479
/* If variable is not the partition key then skip it */
1426-
if (!varnode || !IsA(varnode, Var) || ((Var *) varnode)->varattno != prel->attnum)
1480+
if (IsA(varnode, Var) || IsA(varnode, RelabelType))
1481+
{
1482+
var = !IsA(varnode, RelabelType) ?
1483+
(Var *) varnode :
1484+
(Var *) ((RelabelType *) varnode)->arg;
1485+
if (var->varattno != prel->attnum)
1486+
goto handle_arrexpr_return;
1487+
}
1488+
else
14271489
goto handle_arrexpr_return;
14281490

14291491
if (arraynode && IsA(arraynode, Const) &&
@@ -1437,6 +1499,8 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
14371499
Datum *elem_values;
14381500
bool *elem_nulls;
14391501
int i;
1502+
Datum value;
1503+
uint32 int_value;
14401504

14411505
/* Extract values from array */
14421506
arrayval = DatumGetArrayTypeP(((Const *) arraynode)->constvalue);
@@ -1452,7 +1516,10 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
14521516
/* Construct OIDs list */
14531517
for (i = 0; i < num_elems; i++)
14541518
{
1455-
hash = make_hash(elem_values[i], prel->children_count);
1519+
/* Invoke base hash function for value type */
1520+
value = OidFunctionCall1(prel->hash_proc, elem_values[i]);
1521+
int_value = DatumGetUInt32(value);
1522+
hash = make_hash(int_value, prel->children_count);
14561523
result->rangeset = irange_list_union(result->rangeset,
14571524
list_make1_irange(make_irange(hash, hash, true)));
14581525
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy