/* ----------------------------------------------------------------
 *              ExecEvalBetweenExpr
 *
 *              Evaluate a BetweenExpr node.  Result is
 *              a boolean.  If any of the three expression
 *              parameters are NULL, result is NULL.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalBetweenExpr(BetweenExpr *btest,
                                 ExprContext *econtext,
                                 bool *isNull,
                                 ExprDoneCond *isDone)
{
        Datum           expr_result;
        Datum           lexpr_result;
        Datum           rexpr_result;

        /* Evaluate subexpressons and test for NULL parameters */
        expr_result = ExecEvalExpr(btest->expr, econtext, isNull, isDone);
        if (*isNull) {
                *isNull = true;
                return (Datum) 0;
        }
        lexpr_result = ExecEvalExpr(btest->lexpr, econtext, isNull, isDone);
        if (*isNull) {
                *isNull = true;
                return (Datum) 0;
        }
        rexpr_result = ExecEvalExpr(btest->rexpr, econtext, isNull, isDone);
        if (*isNull) {
                *isNull = true;
                return (Datum) 0;
        }

        /* Make sure return value is what we think it is */
        *isNull = false;

        /* Now, depending on the symmetry, evaluate the
           BETWEEN expression */

        switch (btest->symmetry)
        {
                case SYMMETRIC:
                        if ((expr_result >= lexpr_result &&
                                expr_result <= rexpr_result) ||
                                (expr_result >= rexpr_result &&
                                expr_result <= lexpr_result))
                        {
                                return BoolGetDatum(true);
                        }
                        else
                                return BoolGetDatum(false);
                case ASYMMETRIC:
                        if (expr_result >= lexpr_result &&
                                expr_result <= rexpr_result)
                        {
                                return BoolGetDatum(true);
                        }
                        else
                                return BoolGetDatum(false);
                default:
                        elog(ERROR, "ExecEvalBetweenExpr: unexpected symmetry %d",
                                 (int) btest->symmetry);
                        return (Datum) 0;       /* keep compiler quiet */
        }
}
