@@ -85,7 +85,7 @@ static bool validate_range_opexpr(const Expr *expr,
8585static bool read_opexpr_const (const OpExpr * opexpr ,
8686const PartRelationInfo * prel ,
8787const AttrNumber part_attno ,
88- Datum * val );
88+ Datum * value );
8989
9090static int oid_cmp (const void * p1 ,const void * p2 );
9191
@@ -877,53 +877,100 @@ static bool
877877read_opexpr_const (const OpExpr * opexpr ,
878878const PartRelationInfo * prel ,
879879const AttrNumber part_attno ,
880- Datum * val )
880+ Datum * value )
881881{
882882const Node * left ;
883883const Node * right ;
884884const Var * part_attr ;/* partitioned column */
885- const Const * constant ;
885+ const Const * boundary ;
886886bool cast_success ;
887887
888+ /* There should be exactly 2 args */
888889if (list_length (opexpr -> args )!= 2 )
889890return false;
890891
892+ /* Fetch args of expression */
891893left = linitial (opexpr -> args );
892894right = lsecond (opexpr -> args );
893895
894- /*VAR is a part of RelabelType node */
895- if ( IsA (left , RelabelType ) && IsA ( right , Const ))
896+ /*Examine LEFT argument */
897+ switch ( nodeTag (left ))
896898{
897- Var * var = (Var * ) ((RelabelType * )left )-> arg ;
899+ case T_RelabelType :
900+ {
901+ Var * var = (Var * ) ((RelabelType * )left )-> arg ;
898902
899- if (IsA (var ,Var ))
900- part_attr = var ;
901- else
903+ /* This node should contain Var */
904+ if (!IsA (var ,Var ))
905+ return false;
906+
907+ /* Update LEFT */
908+ left = (Node * )var ;
909+ }
910+ /* FALL THROUGH (no break) */
911+
912+ case T_Var :
913+ {
914+ part_attr = (Var * )left ;
915+
916+ /* VAR.attno == partitioned attribute number */
917+ if (part_attr -> varoattno != part_attno )
918+ return false;
919+ }
920+ break ;
921+
922+ default :
902923return false;
903924}
904- /* left arg is of type VAR */
905- else if (IsA (left ,Var )&& IsA (right ,Const ))
925+
926+ /* Examine RIGHT argument */
927+ switch (nodeTag (right ))
906928{
907- part_attr = ( Var * ) left ;
908- }
909- /* Something is wrong, retreat! */
910- else return false ;
929+ case T_FuncExpr :
930+ {
931+ FuncExpr * func_expr = ( FuncExpr * ) right ;
932+ Const * constant ;
911933
912- /* VAR.attno == partitioned attribute number */
913- if (part_attr -> varoattno != part_attno )
914- return false;
934+ /* This node should represent a type cast */
935+ if (func_expr -> funcformat != COERCE_EXPLICIT_CAST &&
936+ func_expr -> funcformat != COERCE_IMPLICIT_CAST )
937+ return false;
915938
916- /* CONST is NOT NULL */
917- if (((Const * )right )-> constisnull )
918- return false;
939+ /* This node should have exactly 1 argument */
940+ if (list_length (func_expr -> args )!= 1 )
941+ return false;
942+
943+ /* Extract single argument */
944+ constant = linitial (func_expr -> args );
945+
946+ /* Argument should be a Const */
947+ if (!IsA (constant ,Const ))
948+ return false;
949+
950+ /* Update RIGHT */
951+ right = (Node * )constant ;
952+ }
953+ /* FALL THROUGH (no break) */
919954
920- constant = (Const * )right ;
955+ case T_Const :
956+ {
957+ boundary = (Const * )right ;
958+
959+ /* CONST is NOT NULL */
960+ if (boundary -> constisnull )
961+ return false;
962+ }
963+ break ;
964+
965+ default :
966+ return false;
967+ }
921968
922969/* Cast Const to a proper type if needed */
923- * val = perform_type_cast (constant -> constvalue ,
924- getBaseType (constant -> consttype ),
925- getBaseType (prel -> atttype ),
926- & cast_success );
970+ * value = perform_type_cast (boundary -> constvalue ,
971+ getBaseType (boundary -> consttype ),
972+ getBaseType (prel -> atttype ),
973+ & cast_success );
927974
928975if (!cast_success )
929976{