Search in sources :

Example 96 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.

the class JDOQLCompiler method compile.

/**
 * Method to compile the query, and return the compiled results.
 * @param parameters the parameter map of values keyed by param name
 * @param subqueryMap Map of subquery variables, keyed by the subquery name
 * @return The compiled query
 */
public QueryCompilation compile(Map parameters, Map subqueryMap) {
    parser = new JDOQLParser();
    parser.setExplicitParameters(this.parameters != null);
    if (options != null && options.containsKey(Query.EXTENSION_JDOQL_STRICT)) {
        parser.setStrict(Boolean.parseBoolean((String) options.get(Query.EXTENSION_JDOQL_STRICT)));
    }
    symtbl = new SymbolTable();
    symtbl.setSymbolResolver(this);
    if (parentCompiler != null) {
        symtbl.setParentSymbolTable(parentCompiler.symtbl);
    }
    if (subqueryMap != null && !subqueryMap.isEmpty()) {
        // Load subqueries into symbol table so the compilation knows about them
        Iterator<String> subqueryIter = subqueryMap.keySet().iterator();
        while (subqueryIter.hasNext()) {
            String subqueryName = subqueryIter.next();
            Symbol sym = new PropertySymbol(subqueryName);
            sym.setType(Symbol.VARIABLE);
            symtbl.addSymbol(sym);
        }
    }
    Expression[] exprFrom = compileFrom();
    compileCandidatesParametersVariables(parameters);
    Expression exprFilter = compileFilter();
    Expression[] exprOrdering = compileOrdering();
    Expression[] exprResult = compileResult();
    Expression[] exprGrouping = compileGrouping();
    Expression exprHaving = compileHaving();
    Expression[] exprUpdate = compileUpdate();
    // Impose checks from JDO spec
    if (exprGrouping != null) {
        // - an aggregate expression evaluated once per group.
        if (exprResult != null) {
            for (int i = 0; i < exprResult.length; i++) {
                if (!isExpressionGroupingOrAggregate(exprResult[i], exprGrouping)) {
                    throw new NucleusUserException(Localiser.msg("021086", exprResult[i]));
                }
            }
        }
        // - an aggregate expression evaluated once per group.
        if (exprOrdering != null) {
            for (int i = 0; i < exprOrdering.length; i++) {
                if (!isExpressionGroupingOrAggregate(exprOrdering[i], exprGrouping)) {
                    throw new NucleusUserException(Localiser.msg("021087", exprOrdering[i]));
                }
            }
        }
    }
    if (exprHaving != null) {
        // grouping expression.
        if (!containsOnlyGroupingOrAggregates(exprHaving, exprGrouping)) {
            throw new NucleusUserException(Localiser.msg("021088", exprHaving));
        }
    }
    if (exprResult != null) {
        for (int i = 0; i < exprResult.length; i++) {
            if (exprResult[i] instanceof InvokeExpression) {
                InvokeExpression invokeExpr = (InvokeExpression) exprResult[i];
                if (isMethodNameAggregate(invokeExpr.getOperation())) {
                    // Make sure these have 1 argument
                    List<Expression> args = invokeExpr.getArguments();
                    if (args == null || args.size() != 1) {
                        throw new NucleusUserException(Localiser.msg("021089", invokeExpr.getOperation()));
                    }
                }
            }
        }
    }
    QueryCompilation compilation = new QueryCompilation(candidateClass, candidateAlias, symtbl, exprResult, exprFrom, exprFilter, exprGrouping, exprHaving, exprOrdering, exprUpdate);
    compilation.setQueryLanguage(getLanguage());
    // Apply compilation optimisations
    if (options != null) {
        if (options.containsKey(PropertyNames.PROPERTY_QUERY_COMPILE_OPTIMISE_VAR_THIS)) {
            Boolean val = (Boolean) options.get(PropertyNames.PROPERTY_QUERY_COMPILE_OPTIMISE_VAR_THIS);
            if (val == Boolean.TRUE) {
                // Perform "var == this" optimisation TODO Enable this using a query extension
                CompilationOptimiser optimiser = new VarThisCompilationOptimiser(compilation, metaDataManager, clr);
                optimiser.optimise();
            }
        }
    // TODO Add handling of relation navigation implying "relation != null". See NavigationNullCompilationOptimiser for a start point
    // i.e if we have "this.field1.field2 = val" this is equivalent to "this.field1 != null && this.field1.field2 = val"
    }
    return compilation;
}
Also used : InvokeExpression(org.datanucleus.query.expression.InvokeExpression) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) JDOQLParser(org.datanucleus.query.compiler.JDOQLParser) DyadicExpression(org.datanucleus.query.expression.DyadicExpression) ParameterExpression(org.datanucleus.query.expression.ParameterExpression) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) VariableExpression(org.datanucleus.query.expression.VariableExpression) OrderExpression(org.datanucleus.query.expression.OrderExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression)

Example 97 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.

the class DyadicExpression method bind.

/**
 * Method to bind the expression to the symbol table as appropriate.
 * @param symtbl Symbol table
 * @return The symbol for this expression
 */
public Symbol bind(SymbolTable symtbl) {
    if (left != null) {
        try {
            left.bind(symtbl);
        } catch (PrimaryExpressionIsClassLiteralException peil) {
            // PrimaryExpression should be swapped for a class Literal
            left = peil.getLiteral();
            left.bind(symtbl);
        } catch (PrimaryExpressionIsClassStaticFieldException peil) {
            // PrimaryExpression should be swapped for a static field Literal
            Field fld = peil.getLiteralField();
            try {
                // Get the value of the static field
                Object value = fld.get(null);
                left = new Literal(value);
                left.bind(symtbl);
            } catch (Exception e) {
                throw new NucleusUserException("Error processing static field " + fld.getName(), e);
            }
        } catch (PrimaryExpressionIsVariableException pive) {
            // PrimaryExpression should be swapped for a VariableExpression
            left = pive.getVariableExpression();
            left.bind(symtbl);
        } catch (PrimaryExpressionIsInvokeException piie) {
            // PrimaryExpression should be swapped for a InvokeExpression
            left = piie.getInvokeExpression();
            left.bind(symtbl);
        }
    }
    if (right != null) {
        try {
            right.bind(symtbl);
        } catch (PrimaryExpressionIsClassLiteralException peil) {
            // PrimaryExpression should be swapped for a class Literal
            right = peil.getLiteral();
            right.bind(symtbl);
        } catch (PrimaryExpressionIsClassStaticFieldException peil) {
            // PrimaryExpression should be swapped for a static field Literal
            Field fld = peil.getLiteralField();
            try {
                // Get the value of the static field
                Object value = fld.get(null);
                right = new Literal(value);
                right.bind(symtbl);
            } catch (Exception e) {
                throw new NucleusUserException("Error processing static field " + fld.getName(), e);
            }
        } catch (PrimaryExpressionIsVariableException pive) {
            // PrimaryExpression should be swapped for a VariableExpression
            right = pive.getVariableExpression();
            right.bind(symtbl);
        } catch (PrimaryExpressionIsInvokeException piie) {
            // PrimaryExpression should be swapped for a InvokeExpression
            right = piie.getInvokeExpression();
            right.bind(symtbl);
        }
    }
    if (left != null && left instanceof VariableExpression) {
        Symbol leftSym = left.getSymbol();
        if (leftSym != null && leftSym.getValueType() == null) {
            // Set type of implicit variable
            if (right instanceof Literal && ((Literal) right).getLiteral() != null) {
                leftSym.setValueType(((Literal) right).getLiteral().getClass());
            }
        }
    }
    if (right != null) {
        Symbol rightSym = right.getSymbol();
        if (rightSym != null && rightSym.getValueType() == null) {
            // Set type of implicit variable
            if (left instanceof Literal && ((Literal) left).getLiteral() != null) {
                rightSym.setValueType(((Literal) left).getLiteral().getClass());
            }
        }
    }
    // Interpret types of parameters etc when used in comparison operator
    if (op == Expression.OP_EQ || op == Expression.OP_NOTEQ || op == Expression.OP_GT || op == Expression.OP_GTEQ || op == Expression.OP_LT || op == Expression.OP_LTEQ) {
        Class leftType = (left != null && left.getSymbol() != null) ? left.getSymbol().getValueType() : null;
        Class rightType = (right != null && right.getSymbol() != null) ? right.getSymbol().getValueType() : null;
        if (left instanceof ParameterExpression && leftType == null && rightType != null) {
            // parameter {op} primary
            left.getSymbol().setValueType(rightType);
        } else if (right instanceof ParameterExpression && rightType == null && leftType != null) {
            // primary {op} parameter
            right.getSymbol().setValueType(leftType);
        }
        leftType = (left != null && left.getSymbol() != null) ? left.getSymbol().getValueType() : null;
        rightType = (right != null && right.getSymbol() != null) ? right.getSymbol().getValueType() : null;
    }
    return null;
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Symbol(org.datanucleus.query.compiler.Symbol) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Field(java.lang.reflect.Field)

Example 98 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.

the class PrimaryExpression method bind.

/**
 * Method to bind the expression to the symbol table as appropriate.
 * @param symtbl Symbol Table
 * @return The symbol for this expression
 */
public Symbol bind(SymbolTable symtbl) {
    if (left != null) {
        left.bind(symtbl);
    }
    // TODO Cater for finding field of left expression
    if (left == null && symtbl.hasSymbol(getId())) {
        symbol = symtbl.getSymbol(getId());
        if (symbol.getType() == Symbol.VARIABLE) {
            // This is a variable, so needs converting
            throw new PrimaryExpressionIsVariableException(symbol.getQualifiedName());
        }
        return symbol;
    }
    if (left != null) {
        return null;
    }
    if (symbol == null) {
        // Try with our symbol table
        try {
            Class symbolType = symtbl.getSymbolResolver().getType(tuples);
            symbol = new PropertySymbol(getId(), symbolType);
        } catch (NucleusUserException nue) {
        // Thrown if a field in the primary expression doesn't exist.
        }
    }
    if (symbol == null && symtbl.getParentSymbolTable() != null) {
        // Try parent symbol table if present
        try {
            Class symbolType = symtbl.getParentSymbolTable().getSymbolResolver().getType(tuples);
            symbol = new PropertySymbol(getId(), symbolType);
        } catch (NucleusUserException nue) {
        // Thrown if a field in the primary expression doesn't exist.
        }
    }
    if (symbol == null) {
        // This may be due to an entry like "org.jpox.samples.MyClass" used for "instanceof"
        String className = getId();
        try {
            // Try to find this as a complete class name (e.g as used in "instanceof")
            Class cls = symtbl.getSymbolResolver().resolveClass(className);
            // Represents a valid class so throw exception to get the PrimaryExpression swapped
            throw new PrimaryExpressionIsClassLiteralException(cls);
        } catch (ClassNotResolvedException cnre) {
            // Try to find classname.staticField
            if (className.indexOf('.') < 0) {
                // {candidateCls}.primary so "primary" is staticField ?
                Class primaryCls = symtbl.getSymbolResolver().getPrimaryClass();
                if (primaryCls == null) {
                    throw new NucleusUserException("Class name " + className + " could not be resolved");
                }
                try {
                    Field fld = primaryCls.getDeclaredField(className);
                    if (!Modifier.isStatic(fld.getModifiers())) {
                        throw new NucleusUserException("Identifier " + className + " is unresolved (not a static field)");
                    }
                    throw new PrimaryExpressionIsClassStaticFieldException(fld);
                } catch (NoSuchFieldException nsfe) {
                    if (symtbl.getSymbolResolver().supportsImplicitVariables() && left == null) {
                        // Implicit variable assumed so swap this primary for it
                        throw new PrimaryExpressionIsVariableException(className);
                    }
                    throw new NucleusUserException("Class name " + className + " could not be resolved");
                }
            }
            try {
                String staticFieldName = className.substring(className.lastIndexOf('.') + 1);
                className = className.substring(0, className.lastIndexOf('.'));
                Class cls = symtbl.getSymbolResolver().resolveClass(className);
                try {
                    Field fld = cls.getDeclaredField(staticFieldName);
                    if (!Modifier.isStatic(fld.getModifiers())) {
                        throw new NucleusUserException("Identifier " + className + "." + staticFieldName + " is unresolved (not a static field)");
                    }
                    throw new PrimaryExpressionIsClassStaticFieldException(fld);
                } catch (NoSuchFieldException nsfe) {
                    throw new NucleusUserException("Identifier " + className + "." + staticFieldName + " is unresolved (not a static field)");
                }
            } catch (ClassNotResolvedException cnre2) {
                if (getId().indexOf(".") > 0) {
                    Iterator<String> tupleIter = tuples.iterator();
                    Class cls = null;
                    while (tupleIter.hasNext()) {
                        String tuple = tupleIter.next();
                        if (cls == null) {
                            Symbol sym = symtbl.getSymbol(tuple);
                            if (sym == null) {
                                sym = symtbl.getSymbol("this");
                                if (sym == null) {
                                    // TODO Need to get hold of candidate alias
                                    break;
                                }
                            }
                            cls = sym.getValueType();
                        } else {
                            // Look for member of the current class
                            if (cls.isArray() && tuple.equals("length") && !tupleIter.hasNext()) {
                                // Special case of Array.length
                                PrimaryExpression primExpr = new PrimaryExpression(left, tuples.subList(0, tuples.size() - 1));
                                InvokeExpression invokeExpr = new InvokeExpression(primExpr, "size", null);
                                throw new PrimaryExpressionIsInvokeException(invokeExpr);
                            }
                            cls = ClassUtils.getClassForMemberOfClass(cls, tuple);
                        }
                    }
                    if (cls != null) {
                    // TODO Add symbol
                    }
                }
            }
            if (symtbl.getSymbolResolver().supportsImplicitVariables() && left == null) {
                // Implicit variable, so put as "left" and remove from tuples
                String varName = tuples.remove(0);
                VariableExpression varExpr = new VariableExpression(varName);
                varExpr.bind(symtbl);
                left = varExpr;
            } else {
                // Just throw the original exception
                throw new NucleusUserException("Cannot find type of (part of) " + getId() + " since symbol has no type; implicit variable?");
            }
        }
    }
    return symbol;
}
Also used : PropertySymbol(org.datanucleus.query.compiler.PropertySymbol) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Symbol(org.datanucleus.query.compiler.Symbol) PropertySymbol(org.datanucleus.query.compiler.PropertySymbol) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException) Field(java.lang.reflect.Field)

Example 99 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.

the class AbstractResultClassMapper method getResultForResultSetRow.

/**
 * Method to take the result(s) of a row of the query and convert it into an object of the resultClass
 * type, using the rules from the JDO spec.
 * @param inputResult The result from the query
 * @param fieldNames Names of the fields (in the query, ordered)
 * @param fields The Field objects for the fields of the result class (ordered)
 * @return Object of the resultClass type for the input result
 */
Object getResultForResultSetRow(Object inputResult, String[] fieldNames, Field[] fields) {
    if (resultClass == Object[].class) {
        return inputResult;
    } else if (QueryUtils.resultClassIsSimple(resultClass.getName())) {
        // User wants a single field
        if (fieldNames.length == 1) {
            if (inputResult == null || resultClass.isAssignableFrom(inputResult.getClass())) {
                return inputResult;
            }
            String msg = Localiser.msg("021202", resultClass.getName(), inputResult.getClass().getName());
            NucleusLogger.QUERY.error(msg);
            throw new NucleusUserException(msg);
        } else if (fieldNames.length > 1) {
            String msg = Localiser.msg("021201", resultClass.getName());
            NucleusLogger.QUERY.error(msg);
            throw new NucleusUserException(msg);
        } else {
            // 0 columns in the query ?
            return null;
        }
    } else if (fieldNames.length == 1 && inputResult != null && resultClass.isAssignableFrom(inputResult.getClass())) {
        // Only 1 column, and the input result is of the type of the result class, so return it
        return inputResult;
    } else {
        Object[] fieldValues = null;
        if (inputResult instanceof Object[]) {
            fieldValues = (Object[]) inputResult;
        } else {
            fieldValues = new Object[1];
            fieldValues[0] = inputResult;
        }
        Object obj = QueryUtils.createResultObjectUsingArgumentedConstructor(resultClass, fieldValues, null);
        if (obj != null) {
            return obj;
        } else if (NucleusLogger.QUERY.isDebugEnabled()) {
            // Give debug message that no constructor was found with the right args
            Class[] ctr_arg_types = new Class[fieldNames.length];
            for (int i = 0; i < fieldNames.length; i++) {
                if (fieldValues[i] != null) {
                    ctr_arg_types[i] = fieldValues[i].getClass();
                } else {
                    ctr_arg_types[i] = null;
                }
            }
            NucleusLogger.QUERY.debug(Localiser.msg("021206", resultClass.getName(), StringUtils.objectArrayToString(ctr_arg_types)));
        }
        // B. No argumented constructor so create object and update fields using fields/put()/setXXX()
        return QueryUtils.createResultObjectUsingDefaultConstructorAndSetters(resultClass, fieldNames, fields, fieldValues);
    }
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException)

Example 100 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException 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)

Aggregations

NucleusUserException (org.datanucleus.exceptions.NucleusUserException)258 NucleusException (org.datanucleus.exceptions.NucleusException)65 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)51 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)46 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)46 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)41 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)36 ArrayList (java.util.ArrayList)34 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)30 ObjectProvider (org.datanucleus.state.ObjectProvider)30 ClassNotResolvedException (org.datanucleus.exceptions.ClassNotResolvedException)26 Expression (org.datanucleus.query.expression.Expression)24 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)23 SQLException (java.sql.SQLException)22 PersistableMapping (org.datanucleus.store.rdbms.mapping.java.PersistableMapping)21 NullLiteral (org.datanucleus.store.rdbms.sql.expression.NullLiteral)21 SQLLiteral (org.datanucleus.store.rdbms.sql.expression.SQLLiteral)21 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)20 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)20 BigInteger (java.math.BigInteger)19