Search in sources :

Example 16 with DyadicExpression

use of org.datanucleus.query.expression.DyadicExpression in project datanucleus-core by datanucleus.

the class JPQLQueryHelper method getJPQLForExpression.

/**
 * Convenience method to return the JPQL single-string query text for the provided expression.
 * @param expr The expression
 * @return The JPQL single-string text that equates to this expression
 */
public static String getJPQLForExpression(Expression expr) {
    if (expr instanceof DyadicExpression) {
        DyadicExpression dyExpr = (DyadicExpression) expr;
        Expression left = dyExpr.getLeft();
        Expression right = dyExpr.getRight();
        StringBuilder str = new StringBuilder("(");
        if (left != null) {
            str.append(JPQLQueryHelper.getJPQLForExpression(left));
        }
        // Special cases
        if (right != null && right instanceof Literal && ((Literal) right).getLiteral() == null && (dyExpr.getOperator() == Expression.OP_EQ || dyExpr.getOperator() == Expression.OP_NOTEQ)) {
            str.append(dyExpr.getOperator() == Expression.OP_EQ ? " IS NULL" : " IS NOT NULL");
        } else {
            if (dyExpr.getOperator() == Expression.OP_AND) {
                str.append(" AND ");
            } else if (dyExpr.getOperator() == Expression.OP_OR) {
                str.append(" OR ");
            } else if (dyExpr.getOperator() == Expression.OP_ADD) {
                str.append(" + ");
            } else if (dyExpr.getOperator() == Expression.OP_SUB) {
                str.append(" - ");
            } else if (dyExpr.getOperator() == Expression.OP_MUL) {
                str.append(" * ");
            } else if (dyExpr.getOperator() == Expression.OP_DIV) {
                str.append(" / ");
            } else if (dyExpr.getOperator() == Expression.OP_EQ) {
                str.append(" = ");
            } else if (dyExpr.getOperator() == Expression.OP_GT) {
                str.append(" > ");
            } else if (dyExpr.getOperator() == Expression.OP_LT) {
                str.append(" < ");
            } else if (dyExpr.getOperator() == Expression.OP_GTEQ) {
                str.append(" >= ");
            } else if (dyExpr.getOperator() == Expression.OP_LTEQ) {
                str.append(" <= ");
            } else if (dyExpr.getOperator() == Expression.OP_NOTEQ) {
                str.append(" <> ");
            } else {
                // TODO Support other operators
                throw new UnsupportedOperationException("Dont currently support operator " + dyExpr.getOperator() + " in JPQL conversion");
            }
            if (right != null) {
                str.append(JPQLQueryHelper.getJPQLForExpression(right));
            }
        }
        str.append(")");
        return str.toString();
    } else if (expr instanceof PrimaryExpression) {
        PrimaryExpression primExpr = (PrimaryExpression) expr;
        return primExpr.getId();
    } else if (expr instanceof ParameterExpression) {
        ParameterExpression paramExpr = (ParameterExpression) expr;
        if (paramExpr.getId() != null) {
            return ":" + paramExpr.getId();
        }
        return "?" + paramExpr.getPosition();
    } else if (expr instanceof InvokeExpression) {
        InvokeExpression invExpr = (InvokeExpression) expr;
        Expression invoked = invExpr.getLeft();
        List<Expression> args = invExpr.getArguments();
        String method = invExpr.getOperation();
        if (method.equalsIgnoreCase("CURRENT_DATE")) {
            return "CURRENT_DATE";
        } else if (method.equalsIgnoreCase("CURRENT_TIME")) {
            return "CURRENT_TIME";
        } else if (method.equalsIgnoreCase("CURRENT_TIMESTAMP")) {
            return "CURRENT_TIMESTAMP";
        } else if (method.equalsIgnoreCase("length")) {
            StringBuilder str = new StringBuilder("LENGTH(");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            if (args != null && !args.isEmpty()) {
                Expression firstExpr = args.get(0);
                str.append(",").append(JPQLQueryHelper.getJPQLForExpression(firstExpr));
                if (args.size() == 2) {
                    Expression secondExpr = args.get(1);
                    str.append(",").append(JPQLQueryHelper.getJPQLForExpression(secondExpr));
                }
            }
            str.append(")");
            return str.toString();
        } else if (method.equals("toLowerCase")) {
            return "LOWER(" + JPQLQueryHelper.getJPQLForExpression(invoked) + ")";
        } else if (method.equals("toUpperCase")) {
            return "UPPER(" + JPQLQueryHelper.getJPQLForExpression(invoked) + ")";
        } else if (method.equalsIgnoreCase("isEmpty")) {
            StringBuilder str = new StringBuilder();
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            str.append(" IS EMPTY");
            return str.toString();
        } else if (method.equalsIgnoreCase("indexOf")) {
            StringBuilder str = new StringBuilder("LOCATE(");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            if (args != null && !args.isEmpty()) {
                Expression firstExpr = args.get(0);
                str.append(",").append(JPQLQueryHelper.getJPQLForExpression(firstExpr));
                if (args.size() > 1) {
                    Expression secondExpr = args.get(1);
                    str.append(",").append(JPQLQueryHelper.getJPQLForExpression(secondExpr));
                }
            }
            str.append(")");
            return str.toString();
        } else if (method.equalsIgnoreCase("substring")) {
            StringBuilder str = new StringBuilder("SUBSTRING(");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            if (args != null && !args.isEmpty()) {
                Expression firstExpr = args.get(0);
                str.append(",").append(JPQLQueryHelper.getJPQLForExpression(firstExpr));
                if (args.size() > 1) {
                    Expression secondExpr = args.get(1);
                    str.append(",").append(JPQLQueryHelper.getJPQLForExpression(secondExpr));
                }
            }
            str.append(")");
            return str.toString();
        } else if (method.equalsIgnoreCase("trim")) {
            StringBuilder str = new StringBuilder("TRIM(BOTH ");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            if (args != null && !args.isEmpty()) {
                Expression trimChrExpr = args.get(0);
                str.append(JPQLQueryHelper.getJPQLForExpression(trimChrExpr));
            }
            str.append(" FROM ");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            str.append(")");
            return str.toString();
        } else if (method.equalsIgnoreCase("trimLeft")) {
            StringBuilder str = new StringBuilder("TRIM(LEADING ");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            if (args != null && !args.isEmpty()) {
                Expression trimChrExpr = args.get(0);
                str.append(JPQLQueryHelper.getJPQLForExpression(trimChrExpr));
            }
            str.append(" FROM ");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            str.append(")");
            return str.toString();
        } else if (method.equalsIgnoreCase("trimRight")) {
            StringBuilder str = new StringBuilder("TRIM(TRAILING ");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            if (args != null && !args.isEmpty()) {
                Expression trimChrExpr = args.get(0);
                str.append(JPQLQueryHelper.getJPQLForExpression(trimChrExpr));
            }
            str.append(" FROM ");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            str.append(")");
            return str.toString();
        } else if (method.equalsIgnoreCase("matches")) {
            if (args == null || args.isEmpty()) {
                throw new NucleusUserException("Cannot use 'matches' without an argument");
            }
            StringBuilder str = new StringBuilder();
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            str.append(" LIKE ");
            Expression firstExpr = args.get(0);
            str.append(JPQLQueryHelper.getJPQLForExpression(firstExpr));
            if (args != null && args.size() > 1) {
                Expression secondExpr = args.get(1);
                str.append(" ESCAPE ").append(JPQLQueryHelper.getJPQLForExpression(secondExpr));
            }
            return str.toString();
        } else if (method.equalsIgnoreCase("contains")) {
            StringBuilder str = new StringBuilder();
            if (args == null || args.isEmpty()) {
                throw new NucleusUserException("Cannot use 'contains' without an argument");
            }
            Expression firstExpr = args.get(0);
            str.append(JPQLQueryHelper.getJPQLForExpression(firstExpr));
            str.append(" MEMBER OF ");
            str.append(JPQLQueryHelper.getJPQLForExpression(invoked));
            return str.toString();
        } else if (method.equalsIgnoreCase("COUNT")) {
            if (args == null || args.isEmpty()) {
                throw new NucleusUserException("Cannot use 'COUNT' without an argument");
            }
            Expression argExpr = args.get(0);
            if (argExpr instanceof DyadicExpression && ((DyadicExpression) argExpr).getOperator() == Expression.OP_DISTINCT) {
                DyadicExpression dyExpr = (DyadicExpression) argExpr;
                return "COUNT(DISTINCT " + JPQLQueryHelper.getJPQLForExpression(dyExpr.getLeft()) + ")";
            }
            return "COUNT(" + JPQLQueryHelper.getJPQLForExpression(argExpr) + ")";
        } else if (method.equalsIgnoreCase("COALESCE")) {
            StringBuilder str = new StringBuilder("COALESCE(");
            if (args != null && !args.isEmpty()) {
                for (int i = 0; i < args.size(); i++) {
                    Expression argExpr = args.get(i);
                    str.append(JPQLQueryHelper.getJPQLForExpression(argExpr));
                    if (i < args.size() - 1) {
                        str.append(",");
                    }
                }
            }
            str.append(")");
            return str.toString();
        } else if (method.equalsIgnoreCase("NULLIF")) {
            StringBuilder str = new StringBuilder("NULLIF(");
            if (args != null && !args.isEmpty()) {
                for (int i = 0; i < args.size(); i++) {
                    Expression argExpr = args.get(i);
                    str.append(JPQLQueryHelper.getJPQLForExpression(argExpr));
                    if (i < args.size() - 1) {
                        str.append(",");
                    }
                }
            }
            str.append(")");
            return str.toString();
        } else if (method.equalsIgnoreCase("ABS")) {
            String argExprStr = (args != null && !args.isEmpty()) ? JPQLQueryHelper.getJPQLForExpression(args.get(0)) : "";
            return "ABS(" + argExprStr + ")";
        } else if (method.equalsIgnoreCase("AVG")) {
            String argExprStr = (args != null && !args.isEmpty()) ? JPQLQueryHelper.getJPQLForExpression(args.get(0)) : "";
            return "AVG(" + argExprStr + ")";
        } else if (method.equalsIgnoreCase("MAX")) {
            String argExprStr = (args != null && !args.isEmpty()) ? JPQLQueryHelper.getJPQLForExpression(args.get(0)) : "";
            return "MAX(" + argExprStr + ")";
        } else if (method.equalsIgnoreCase("MIN")) {
            String argExprStr = (args != null && !args.isEmpty()) ? JPQLQueryHelper.getJPQLForExpression(args.get(0)) : "";
            return "MIN(" + argExprStr + ")";
        } else if (method.equalsIgnoreCase("SQRT")) {
            String argExprStr = (args != null && !args.isEmpty()) ? JPQLQueryHelper.getJPQLForExpression(args.get(0)) : "";
            return "SQRT(" + argExprStr + ")";
        } else if (method.equalsIgnoreCase("SUM")) {
            String argExprStr = (args != null && !args.isEmpty()) ? JPQLQueryHelper.getJPQLForExpression(args.get(0)) : "";
            return "SUM(" + argExprStr + ")";
        }
        // TODO Support this
        throw new UnsupportedOperationException("Dont currently support InvokeExpression (" + invExpr + ") conversion into JPQL");
    } else if (expr instanceof Literal) {
        Literal litExpr = (Literal) expr;
        Object value = litExpr.getLiteral();
        if (value instanceof String || value instanceof Character) {
            return "'" + value.toString() + "'";
        } else if (value instanceof Boolean) {
            return (Boolean) value ? "TRUE" : "FALSE";
        } else {
            return litExpr.getLiteral().toString();
        }
    } else if (expr instanceof VariableExpression) {
        VariableExpression varExpr = (VariableExpression) expr;
        return varExpr.getId();
    } else {
        throw new UnsupportedOperationException("Dont currently support " + expr.getClass().getName() + " in JPQLQueryHelper");
    }
}
Also used : InvokeExpression(org.datanucleus.query.expression.InvokeExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) VariableExpression(org.datanucleus.query.expression.VariableExpression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) ParameterExpression(org.datanucleus.query.expression.ParameterExpression) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) VariableExpression(org.datanucleus.query.expression.VariableExpression) Literal(org.datanucleus.query.expression.Literal) ParameterExpression(org.datanucleus.query.expression.ParameterExpression) List(java.util.List)

Example 17 with DyadicExpression

use of org.datanucleus.query.expression.DyadicExpression in project datanucleus-core by datanucleus.

the class VarThisCompilationOptimiser method replaceVariableWithCandidateInExpression.

/**
 * Method that replaces any occurrence of the specified variable in the provided expression with the
 * candidate primary expression. Recurses to sub-expressions.
 * @param varName Variable name
 * @param expr The expression to update
 * @return Updated expression
 */
private Expression replaceVariableWithCandidateInExpression(String varName, Expression expr) {
    if (expr == null) {
        return null;
    }
    if (expr instanceof VariableExpression && ((VariableExpression) expr).getId().equals(varName)) {
        List<String> tuples = new ArrayList<String>();
        tuples.add(compilation.getCandidateAlias());
        Expression replExpr = new PrimaryExpression(tuples);
        replExpr.bind(compilation.getSymbolTable());
        return replExpr;
    } else if (expr instanceof DyadicExpression) {
        DyadicExpression dyExpr = (DyadicExpression) expr;
        if (dyExpr.getLeft() != null) {
            dyExpr.setLeft(replaceVariableWithCandidateInExpression(varName, dyExpr.getLeft()));
        }
        if (dyExpr.getRight() != null) {
            dyExpr.setRight(replaceVariableWithCandidateInExpression(varName, dyExpr.getRight()));
        }
    } else if (expr instanceof PrimaryExpression) {
        if (expr.getLeft() != null) {
            if (expr.getLeft() instanceof VariableExpression && ((VariableExpression) expr.getLeft()).getId().equals(varName)) {
                // Needs to be relative to candidate so just remove the "left"
                expr.setLeft(null);
            } else {
                expr.setLeft(replaceVariableWithCandidateInExpression(varName, expr.getLeft()));
            }
        }
    } else if (expr instanceof InvokeExpression) {
        InvokeExpression invokeExpr = (InvokeExpression) expr;
        if (invokeExpr.getLeft() != null) {
            invokeExpr.setLeft(replaceVariableWithCandidateInExpression(varName, invokeExpr.getLeft()));
        }
    // List<Expression> args = invokeExpr.getArguments(); // TODO Process Invoke args
    }
    // TODO More combinations
    return expr;
}
Also used : InvokeExpression(org.datanucleus.query.expression.InvokeExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) VariableExpression(org.datanucleus.query.expression.VariableExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) ArrayList(java.util.ArrayList) VariableExpression(org.datanucleus.query.expression.VariableExpression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression)

Example 18 with DyadicExpression

use of org.datanucleus.query.expression.DyadicExpression in project datanucleus-api-jdo by datanucleus.

the class ComparableExpressionImpl method lt.

/* (non-Javadoc)
     * @see org.datanucleus.query.typesafe.Expression#lt(java.lang.Object)
     */
public BooleanExpression lt(T t) {
    Expression leftQueryExpr = queryExpr;
    Expression rightQueryExpr = new Literal(t);
    org.datanucleus.query.expression.Expression queryExpr = new DyadicExpression(leftQueryExpr, org.datanucleus.query.expression.Expression.OP_LT, rightQueryExpr);
    return new BooleanExpressionImpl(queryExpr);
}
Also used : DyadicExpression(org.datanucleus.query.expression.DyadicExpression) NumericExpression(javax.jdo.query.NumericExpression) ComparableExpression(javax.jdo.query.ComparableExpression) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) OrderExpression(javax.jdo.query.OrderExpression) PersistableExpression(javax.jdo.query.PersistableExpression) BooleanExpression(javax.jdo.query.BooleanExpression) Literal(org.datanucleus.query.expression.Literal) Expression(org.datanucleus.query.expression.Expression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression)

Example 19 with DyadicExpression

use of org.datanucleus.query.expression.DyadicExpression in project datanucleus-api-jdo by datanucleus.

the class ComparableExpressionImpl method gt.

/* (non-Javadoc)
     * @see org.datanucleus.query.typesafe.Expression#gt(org.datanucleus.query.typesafe.ComparableExpression)
     */
public BooleanExpression gt(ComparableExpression expr) {
    Expression leftQueryExpr = queryExpr;
    Expression rightQueryExpr = ((ExpressionImpl) expr).getQueryExpression();
    org.datanucleus.query.expression.Expression queryExpr = new DyadicExpression(leftQueryExpr, org.datanucleus.query.expression.Expression.OP_GT, rightQueryExpr);
    return new BooleanExpressionImpl(queryExpr);
}
Also used : DyadicExpression(org.datanucleus.query.expression.DyadicExpression) NumericExpression(javax.jdo.query.NumericExpression) ComparableExpression(javax.jdo.query.ComparableExpression) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) OrderExpression(javax.jdo.query.OrderExpression) PersistableExpression(javax.jdo.query.PersistableExpression) BooleanExpression(javax.jdo.query.BooleanExpression) Expression(org.datanucleus.query.expression.Expression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression)

Example 20 with DyadicExpression

use of org.datanucleus.query.expression.DyadicExpression in project datanucleus-api-jdo by datanucleus.

the class ComparableExpressionImpl method gt.

/* (non-Javadoc)
     * @see org.datanucleus.query.typesafe.Expression#gt(java.lang.Object)
     */
public BooleanExpression gt(T t) {
    Expression leftQueryExpr = queryExpr;
    Expression rightQueryExpr = new Literal(t);
    org.datanucleus.query.expression.Expression queryExpr = new DyadicExpression(leftQueryExpr, org.datanucleus.query.expression.Expression.OP_GT, rightQueryExpr);
    return new BooleanExpressionImpl(queryExpr);
}
Also used : DyadicExpression(org.datanucleus.query.expression.DyadicExpression) NumericExpression(javax.jdo.query.NumericExpression) ComparableExpression(javax.jdo.query.ComparableExpression) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) OrderExpression(javax.jdo.query.OrderExpression) PersistableExpression(javax.jdo.query.PersistableExpression) BooleanExpression(javax.jdo.query.BooleanExpression) Literal(org.datanucleus.query.expression.Literal) Expression(org.datanucleus.query.expression.Expression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression)

Aggregations

DyadicExpression (org.datanucleus.query.expression.DyadicExpression)51 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)43 Expression (org.datanucleus.query.expression.Expression)42 PrimaryExpression (org.datanucleus.query.expression.PrimaryExpression)36 ParameterExpression (org.datanucleus.query.expression.ParameterExpression)34 Literal (org.datanucleus.query.expression.Literal)32 VariableExpression (org.datanucleus.query.expression.VariableExpression)30 NucleusException (org.datanucleus.exceptions.NucleusException)21 QueryCompilation (org.datanucleus.query.compiler.QueryCompilation)20 JavaQueryCompiler (org.datanucleus.query.compiler.JavaQueryCompiler)18 OrderExpression (org.datanucleus.query.expression.OrderExpression)13 BooleanExpression (javax.jdo.query.BooleanExpression)12 PersistableExpression (javax.jdo.query.PersistableExpression)12 JDOQLCompiler (org.datanucleus.query.compiler.JDOQLCompiler)12 Product (org.datanucleus.samples.store.Product)12 HashMap (java.util.HashMap)11 NumericExpression (javax.jdo.query.NumericExpression)9 ComparableExpression (javax.jdo.query.ComparableExpression)8 OrderExpression (javax.jdo.query.OrderExpression)8 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)7