@@ -79,14 +79,16 @@ static bool disable_inheritance_subselect_walker(Node *node, void *context);
7979/* Expression tree handlers */
8080static Datum increase_hashable_value (const PartRelationInfo * prel , Datum value );
8181static 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 );
8384static WrapperNode * handle_opexpr (const OpExpr * expr , WalkerContext * context );
8485static WrapperNode * handle_boolexpr (const BoolExpr * expr , WalkerContext * context );
8586static WrapperNode * handle_arrexpr (const ScalarArrayOpExpr * expr , WalkerContext * context );
8687static void change_varnos_in_restrinct_info (RestrictInfo * rinfo , change_varno_context * context );
8788static void change_varnos (Node * node , Oid old_varno , Oid new_varno );
8889static bool change_varno_walker (Node * node , change_varno_context * context );
8990static 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 */
9294static void set_plain_rel_size (PlannerInfo * root , RelOptInfo * rel ,
@@ -966,7 +968,7 @@ decrease_hashable_value(const PartRelationInfo *prel, Datum value)
966968 */
967969static void
968970handle_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 */
11921202static void
11931203handle_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 *
13061323handle_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