@@ -79,14 +79,16 @@ static bool disable_inheritance_subselect_walker(Node *node, void *context);
79
79
/* Expression tree handlers */
80
80
static Datum increase_hashable_value (const PartRelationInfo * prel , Datum value );
81
81
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 );
83
84
static WrapperNode * handle_opexpr (const OpExpr * expr , WalkerContext * context );
84
85
static WrapperNode * handle_boolexpr (const BoolExpr * expr , WalkerContext * context );
85
86
static WrapperNode * handle_arrexpr (const ScalarArrayOpExpr * expr , WalkerContext * context );
86
87
static void change_varnos_in_restrinct_info (RestrictInfo * rinfo , change_varno_context * context );
87
88
static void change_varnos (Node * node , Oid old_varno , Oid new_varno );
88
89
static bool change_varno_walker (Node * node , change_varno_context * context );
89
90
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 );
90
92
91
93
/* copied from allpaths.h */
92
94
static void set_plain_rel_size (PlannerInfo * root , RelOptInfo * rel ,
@@ -966,7 +968,7 @@ decrease_hashable_value(const PartRelationInfo *prel, Datum value)
966
968
*/
967
969
static void
968
970
handle_binary_opexpr (WalkerContext * context , WrapperNode * result ,
969
- const Var * v , const Const * c )
971
+ const Node * varnode , const Const * c )
970
972
{
971
973
HashRelationKey key ;
972
974
RangeRelation * rangerel ;
@@ -978,18 +980,25 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
978
980
is_greater ;
979
981
FmgrInfo cmp_func ;
980
982
Oid cmp_proc_oid ;
983
+ Oid vartype ;
981
984
const OpExpr * expr = (const OpExpr * )result -> orig ;
982
985
TypeCacheEntry * tce ;
983
986
const PartRelationInfo * prel = context -> prel ;
984
987
988
+ Assert (IsA (varnode , Var ) || IsA (varnode , RelableType ));
989
+
990
+ vartype = !IsA (varnode , RelabelType ) ?
991
+ ((Var * ) varnode )-> vartype :
992
+ ((RelabelType * ) varnode )-> resulttype ;
993
+
985
994
/* Determine operator type */
986
- tce = lookup_type_cache (v -> vartype ,
995
+ tce = lookup_type_cache (vartype ,
987
996
TYPECACHE_BTREE_OPFAMILY | TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO );
988
997
989
998
strategy = get_op_opfamily_strategy (expr -> opno , tce -> btree_opf );
990
999
cmp_proc_oid = get_opfamily_proc (tce -> btree_opf ,
1000
+ vartype ,
991
1001
c -> consttype ,
992
- prel -> atttype ,
993
1002
BTORDER_PROC );
994
1003
fmgr_info (cmp_proc_oid , & cmp_func );
995
1004
@@ -1032,6 +1041,7 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
1032
1041
result -> rangeset = list_make1_irange (make_irange (key .hash , key .hash , true));
1033
1042
return ;
1034
1043
}
1044
+ break ;
1035
1045
case PT_RANGE :
1036
1046
value = c -> constvalue ;
1037
1047
rangerel = get_pathman_range_relation (prel -> key .relid , NULL );
@@ -1191,14 +1201,21 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
1191
1201
*/
1192
1202
static void
1193
1203
handle_binary_opexpr_param (const PartRelationInfo * prel ,
1194
- WrapperNode * result , const Var * v )
1204
+ WrapperNode * result , const Node * varnode )
1195
1205
{
1196
1206
const OpExpr * expr = (const OpExpr * )result -> orig ;
1197
1207
TypeCacheEntry * tce ;
1198
1208
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 ;
1199
1216
1200
1217
/* Determine operator type */
1201
- tce = lookup_type_cache (v -> vartype , TYPECACHE_BTREE_OPFAMILY );
1218
+ tce = lookup_type_cache (vartype , TYPECACHE_BTREE_OPFAMILY );
1202
1219
strategy = get_op_opfamily_strategy (expr -> opno , tce -> btree_opf );
1203
1220
1204
1221
result -> rangeset = list_make1_irange (make_irange (0 , prel -> children_count - 1 , true));
@@ -1306,38 +1323,24 @@ static WrapperNode *
1306
1323
handle_opexpr (const OpExpr * expr , WalkerContext * context )
1307
1324
{
1308
1325
WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
1309
- Node * firstarg = NULL ,
1310
- * secondarg = NULL ;
1326
+ Node * var , * param ;
1311
1327
const PartRelationInfo * prel = context -> prel ;
1312
1328
1313
1329
result -> orig = (const Node * )expr ;
1314
1330
result -> args = NIL ;
1315
1331
1316
1332
if (list_length (expr -> args ) == 2 )
1317
1333
{
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 ))
1332
1335
{
1333
- if (IsConstValue (context , secondarg ))
1336
+ if (IsConstValue (context , param ))
1334
1337
{
1335
- handle_binary_opexpr (context , result , ( Var * ) firstarg , ExtractConst (context , secondarg ));
1338
+ handle_binary_opexpr (context , result , var , ExtractConst (context , param ));
1336
1339
return result ;
1337
1340
}
1338
- else if (IsA (secondarg , Param ) || IsA (secondarg , Var ))
1341
+ else if (IsA (param , Param ) || IsA (param , Var ))
1339
1342
{
1340
- handle_binary_opexpr_param (prel , result , ( Var * ) firstarg );
1343
+ handle_binary_opexpr_param (prel , result , var );
1341
1344
return result ;
1342
1345
}
1343
1346
}
@@ -1348,6 +1351,54 @@ handle_opexpr(const OpExpr *expr, WalkerContext *context)
1348
1351
return result ;
1349
1352
}
1350
1353
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
+
1351
1402
/*
1352
1403
* Boolean expression handler
1353
1404
*/
@@ -1414,6 +1465,7 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
1414
1465
{
1415
1466
WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
1416
1467
Node * varnode = (Node * ) linitial (expr -> args );
1468
+ Var * var ;
1417
1469
Node * arraynode = (Node * ) lsecond (expr -> args );
1418
1470
int hash ;
1419
1471
const PartRelationInfo * prel = context -> prel ;
@@ -1422,8 +1474,18 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
1422
1474
result -> args = NIL ;
1423
1475
result -> paramsel = 1.0 ;
1424
1476
1477
+ Assert (varnode != NULL );
1478
+
1425
1479
/* 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
1427
1489
goto handle_arrexpr_return ;
1428
1490
1429
1491
if (arraynode && IsA (arraynode , Const ) &&
@@ -1437,6 +1499,8 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
1437
1499
Datum * elem_values ;
1438
1500
bool * elem_nulls ;
1439
1501
int i ;
1502
+ Datum value ;
1503
+ uint32 int_value ;
1440
1504
1441
1505
/* Extract values from array */
1442
1506
arrayval = DatumGetArrayTypeP (((Const * ) arraynode )-> constvalue );
@@ -1452,7 +1516,10 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
1452
1516
/* Construct OIDs list */
1453
1517
for (i = 0 ; i < num_elems ; i ++ )
1454
1518
{
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 );
1456
1523
result -> rangeset = irange_list_union (result -> rangeset ,
1457
1524
list_make1_irange (make_irange (hash , hash , true)));
1458
1525
}
0 commit comments