Search in sources :

Example 1 with ParameterLiteral

use of org.datanucleus.store.rdbms.sql.expression.ParameterLiteral in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method processNoteqExpression.

/* (non-Javadoc)
     * @see org.datanucleus.query.evaluator.AbstractExpressionEvaluator#processNoteqExpression(org.datanucleus.query.expression.Expression)
     */
@Override
protected Object processNoteqExpression(Expression expr) {
    SQLExpression right = stack.pop();
    SQLExpression left = stack.pop();
    if (left instanceof ParameterLiteral && !(right instanceof ParameterLiteral)) {
        left = replaceParameterLiteral((ParameterLiteral) left, right.getJavaTypeMapping());
    } else if (right instanceof ParameterLiteral && !(left instanceof ParameterLiteral)) {
        right = replaceParameterLiteral((ParameterLiteral) right, left.getJavaTypeMapping());
    }
    if (left.isParameter() && right.isParameter()) {
        if (left.isParameter() && left instanceof SQLLiteral && ((SQLLiteral) left).getValue() != null) {
            useParameterExpressionAsLiteral((SQLLiteral) left);
        }
        if (right.isParameter() && right instanceof SQLLiteral && ((SQLLiteral) right).getValue() != null) {
            useParameterExpressionAsLiteral((SQLLiteral) right);
        }
    }
    ExpressionUtils.checkAndCorrectExpressionMappingsForBooleanComparison(left, right);
    if (left instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) left);
        left = stack.pop();
    }
    if (right instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) right);
        right = stack.pop();
    }
    BooleanExpression opExpr = left.ne(right);
    stack.push(opExpr);
    return opExpr;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) ParameterLiteral(org.datanucleus.store.rdbms.sql.expression.ParameterLiteral) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) SQLLiteral(org.datanucleus.store.rdbms.sql.expression.SQLLiteral) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression)

Example 2 with ParameterLiteral

use of org.datanucleus.store.rdbms.sql.expression.ParameterLiteral in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method processLtExpression.

/* (non-Javadoc)
     * @see org.datanucleus.query.evaluator.AbstractExpressionEvaluator#processLtExpression(org.datanucleus.query.expression.Expression)
     */
@Override
protected Object processLtExpression(Expression expr) {
    SQLExpression right = stack.pop();
    SQLExpression left = stack.pop();
    if (left instanceof ParameterLiteral && !(right instanceof ParameterLiteral)) {
        left = replaceParameterLiteral((ParameterLiteral) left, right.getJavaTypeMapping());
    } else if (right instanceof ParameterLiteral && !(left instanceof ParameterLiteral)) {
        right = replaceParameterLiteral((ParameterLiteral) right, left.getJavaTypeMapping());
    }
    ExpressionUtils.checkAndCorrectExpressionMappingsForBooleanComparison(left, right);
    if (left instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) left);
        left = stack.pop();
    }
    if (right instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) right);
        right = stack.pop();
    }
    BooleanExpression opExpr = left.lt(right);
    stack.push(opExpr);
    return opExpr;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) ParameterLiteral(org.datanucleus.store.rdbms.sql.expression.ParameterLiteral) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression)

Example 3 with ParameterLiteral

use of org.datanucleus.store.rdbms.sql.expression.ParameterLiteral in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method processParameterExpression.

/**
 * Method to process a parameter expression.
 * The optional argument controls whether we should create this as a parameter or as a literal (i.e the param value is known etc).
 * If the parameter doesn't have its value defined then returns ParameterLiteral otherwise we get an XXXLiteral of the (declared) type of the parameter
 * @param expr The ParameterExpression
 * @param asLiteral Whether to create a SQLLiteral rather than a parameter literal
 * @return The processed expression
 */
protected Object processParameterExpression(ParameterExpression expr, boolean asLiteral) {
    if (compileComponent == CompilationComponent.ORDERING || compileComponent == CompilationComponent.RESULT) {
        // All JDBC drivers I know don't allow parameters in the order-by, or update clause
        // Note that we also don't allow parameters in result clause since SQLStatement squashes all SELECT expression to a String so losing info about params
        asLiteral = true;
    } else if (compileComponent == CompilationComponent.UPDATE && processingCase && !storeMgr.getDatastoreAdapter().supportsOption(DatastoreAdapter.PARAMETER_IN_CASE_IN_UPDATE_CLAUSE)) {
        // This database doesn't support parameters within a CASE expression in the UPDATE clause, so process as a literal
        asLiteral = true;
    }
    if (expr.getPosition() >= 0) {
        if (paramNameByPosition == null) {
            paramNameByPosition = new HashMap<>();
        }
        paramNameByPosition.put(Integer.valueOf(expr.getPosition()), expr.getId());
    }
    // Find the parameter value if supplied
    Object paramValue = null;
    boolean paramValueSet = false;
    if (parameters != null && parameters.size() > 0) {
        // Check if the parameter has a value
        if (parameters.containsKey(expr.getId())) {
            // Named parameter
            paramValue = parameters.get(expr.getId());
            paramValueSet = true;
        } else if (parameterValueByName != null && parameterValueByName.containsKey(expr.getId())) {
            // Positional parameter, but already encountered
            paramValue = parameterValueByName.get(expr.getId());
            paramValueSet = true;
        } else {
            // Positional parameter, not yet encountered
            int position = positionalParamNumber;
            if (positionalParamNumber < 0) {
                position = 0;
            }
            if (parameters.containsKey(Integer.valueOf(position))) {
                paramValue = parameters.get(Integer.valueOf(position));
                paramValueSet = true;
                positionalParamNumber = position + 1;
                if (parameterValueByName == null) {
                    parameterValueByName = new HashMap<>();
                }
                parameterValueByName.put(expr.getId(), paramValue);
            }
        }
    }
    // Find the type to use for the parameter
    JavaTypeMapping m = paramMappingForName.get(expr.getId());
    if (m == null) {
        // Try to determine from provided parameter value or from symbol table (declared type)
        if (paramValue != null) {
            if (!storeMgr.getMetaDataManager().isClassPersistable(paramValue.getClass().getName()) && !paramValue.getClass().isArray() && !paramValue.getClass().isInterface() && !Collection.class.isAssignableFrom(paramValue.getClass()) && !Map.class.isAssignableFrom(paramValue.getClass()) && !storeMgr.getNucleusContext().getTypeManager().isSupportedSecondClassType(paramValue.getClass().getName())) {
                // Test for this being the "id" of a persistable object
                // Persistable/array/interface/collection/map/simple cannot be an object "id"
                String className = storeMgr.getClassNameForObjectID(paramValue, clr, ec);
                if (className != null) {
                    // Identity for persistable class
                    AbstractClassMetaData cmd = storeMgr.getMetaDataManager().getMetaDataForClass(className, clr);
                    if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                        Class cls = clr.classForName(className);
                        m = exprFactory.getMappingForType(cls, false);
                        m = new PersistableIdMapping((PersistableMapping) m);
                    }
                }
            }
            if (m == null) {
                // Use the type of the input parameter value
                try {
                    m = exprFactory.getMappingForType(paramValue.getClass(), false);
                    if (m instanceof TypeConverterMapping && expr.getSymbol().getValueType() != null && expr.getSymbol().getValueType() != m.getJavaType()) {
                        // This is because if we have a parameter of type "ZoneInfo" it needs to use TimeZone since we have the TypeConverter for that
                        try {
                            m = exprFactory.getMappingForType(expr.getSymbol().getValueType(), false);
                        } catch (NucleusUserException nue) {
                        }
                    }
                } catch (NucleusUserException nue) {
                    // Maybe it needs a TypeConverter so try with the (declared) symbol type of this parameter
                    m = exprFactory.getMappingForType(expr.getSymbol().getValueType(), false);
                }
            }
            if (expr.getSymbol() != null && expr.getSymbol().getValueType() != null) {
                if (!QueryUtils.queryParameterTypesAreCompatible(expr.getSymbol().getValueType(), paramValue.getClass())) {
                    throw new QueryCompilerSyntaxException(Localiser.msg("021118", expr.getId(), expr.getSymbol().getValueType().getName(), paramValue.getClass().getName()));
                }
                if (expr.getSymbol().getValueType() != paramValue.getClass()) {
                    // Mark as not precompilable since the supplied type implies a subclass of the declared type
                    setNotPrecompilable();
                }
            }
        } else if (expr.getSymbol() != null && expr.getSymbol().getValueType() != null) {
            Class valueType = expr.getSymbol().getValueType();
            if (!paramValueSet) {
                if (valueType.isInterface()) {
                    // Special case where we have an interface parameter (not set), and don't know the type, so we pick the first implementation just to get something that works
                    // This is recompiled when the parameter is provided so is just for use in "compile()"
                    String[] implNames = storeMgr.getMetaDataManager().getClassesImplementingInterface(valueType.getName(), clr);
                    if (implNames != null && implNames.length > 0) {
                        valueType = clr.classForName(implNames[0]);
                        setNotPrecompilable();
                    }
                }
            }
            // Use the declared type of the parameter (explicit params)
            m = exprFactory.getMappingForType(valueType, false);
        }
    }
    if (asLiteral && m != null && !m.representableAsStringLiteralInStatement()) {
        // Must keep this as a parameter since its String form is no good in statements
        asLiteral = false;
    }
    if (asLiteral) {
        // Parameter being represented as a literal (for whatever reason), so no longer precompilable
        if (isPrecompilable()) {
            NucleusLogger.QUERY.debug("Parameter " + expr + " is being resolved as a literal, so the query is no longer precompilable");
        }
        setNotPrecompilable();
    } else if (paramValue == null && expr.getSymbol() != null) {
        if (isPrecompilable()) {
            NucleusLogger.QUERY.debug("Parameter " + expr + " is set to null so this has to be resolved as a NullLiteral, and the query is no longer precompilable");
        }
        setNotPrecompilable();
    }
    // Create the SQLExpression for this parameter, either as value-literal or as parameter-literal
    SQLExpression sqlExpr = null;
    if (paramValueSet && paramValue == null && options.contains(OPTION_NULL_PARAM_USE_IS_NULL)) {
        // Value is set to null, but we enforce a NullLiteral for the case of null comparisons e.g we don't want "field = ?", but instead "field IS NULL"
        sqlExpr = exprFactory.newLiteral(stmt, null, null);
    } else if (asLiteral) {
        // Create a value-literal as requested
        sqlExpr = exprFactory.newLiteral(stmt, m, paramValue);
    } else {
        // Create a parameter-literal with it tied to the parameter name for later replacement in the statement
        sqlExpr = exprFactory.newLiteralParameter(stmt, m, paramValue, expr.getId());
        if (sqlExpr instanceof ParameterLiteral) {
            ((ParameterLiteral) sqlExpr).setName(expr.getId());
        }
        if (expressionForParameter == null) {
            expressionForParameter = new HashMap<>();
        }
        expressionForParameter.put(expr.getId(), sqlExpr);
        paramMappingForName.put(expr.getId(), m);
    }
    stack.push(sqlExpr);
    return sqlExpr;
}
Also used : ParameterLiteral(org.datanucleus.store.rdbms.sql.expression.ParameterLiteral) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) HashMap(java.util.HashMap) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) PersistableIdMapping(org.datanucleus.store.rdbms.mapping.java.PersistableIdMapping) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) TypeConverterMapping(org.datanucleus.store.rdbms.mapping.java.TypeConverterMapping) QueryCompilerSyntaxException(org.datanucleus.store.query.QueryCompilerSyntaxException) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) FetchPlanForClass(org.datanucleus.FetchPlanForClass) Map(java.util.Map) HashMap(java.util.HashMap)

Example 4 with ParameterLiteral

use of org.datanucleus.store.rdbms.sql.expression.ParameterLiteral in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method processLteqExpression.

/* (non-Javadoc)
     * @see org.datanucleus.query.evaluator.AbstractExpressionEvaluator#processLteqExpression(org.datanucleus.query.expression.Expression)
     */
@Override
protected Object processLteqExpression(Expression expr) {
    SQLExpression right = stack.pop();
    SQLExpression left = stack.pop();
    if (left instanceof ParameterLiteral && !(right instanceof ParameterLiteral)) {
        left = replaceParameterLiteral((ParameterLiteral) left, right.getJavaTypeMapping());
    } else if (right instanceof ParameterLiteral && !(left instanceof ParameterLiteral)) {
        right = replaceParameterLiteral((ParameterLiteral) right, left.getJavaTypeMapping());
    }
    ExpressionUtils.checkAndCorrectExpressionMappingsForBooleanComparison(left, right);
    if (left instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) left);
        left = stack.pop();
    }
    if (right instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) right);
        right = stack.pop();
    }
    BooleanExpression opExpr = left.le(right);
    stack.push(opExpr);
    return opExpr;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) ParameterLiteral(org.datanucleus.store.rdbms.sql.expression.ParameterLiteral) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression)

Example 5 with ParameterLiteral

use of org.datanucleus.store.rdbms.sql.expression.ParameterLiteral in project datanucleus-rdbms by datanucleus.

the class StringIndexOf5Method method getExpression.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
     */
public SQLExpression getExpression(SQLStatement stmt, SQLExpression expr, List<SQLExpression> args) {
    if (args == null || args.size() == 0 || args.size() > 2) {
        throw new NucleusException(Localiser.msg("060003", "indexOf", "StringExpression", 0, "StringExpression/CharacterExpression/ParameterLiteral"));
    }
    // {stringExpr}.indexOf(strExpr1 [,numExpr2])
    SQLExpression substrExpr = args.get(0);
    if (!(substrExpr instanceof StringExpression) && !(substrExpr instanceof CharacterExpression) && !(substrExpr instanceof ParameterLiteral)) {
        throw new NucleusException(Localiser.msg("060003", "indexOf", "StringExpression", 0, "StringExpression/CharacterExpression/ParameterLiteral"));
    }
    ArrayList funcArgs = new ArrayList();
    if (args.size() == 1) {
        // strExpr.indexOf(str1)
        funcArgs.add(expr);
        funcArgs.add(substrExpr);
        SQLExpression oneExpr = ExpressionUtils.getLiteralForOne(stmt);
        NumericExpression locateExpr = new NumericExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(int.class, true), "STRPOS", funcArgs);
        return new NumericExpression(locateExpr, Expression.OP_SUB, oneExpr);
    }
    // strExpr.indexOf(str1, pos)
    SQLExpression fromExpr = args.get(1);
    if (!(fromExpr instanceof NumericExpression)) {
        throw new NucleusException(Localiser.msg("060003", "indexOf", "StringExpression", 1, "NumericExpression"));
    }
    // Find the substring starting at this position
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    ArrayList substrArgs = new ArrayList(1);
    substrArgs.add(fromExpr);
    SQLExpression strExpr = exprFactory.invokeMethod(stmt, "java.lang.String", "substring", expr, substrArgs);
    funcArgs.add(strExpr);
    funcArgs.add(substrExpr);
    NumericExpression locateExpr = new NumericExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(int.class, true), "STRPOS", funcArgs);
    SQLExpression[] whenExprs = new SQLExpression[1];
    NumericExpression zeroExpr = new IntegerLiteral(stmt, exprFactory.getMappingForType(Integer.class, false), Integer.valueOf(0), null);
    whenExprs[0] = locateExpr.gt(zeroExpr);
    SQLExpression[] actionExprs = new SQLExpression[1];
    SQLExpression oneExpr = ExpressionUtils.getLiteralForOne(stmt);
    NumericExpression posExpr1 = new NumericExpression(locateExpr, Expression.OP_SUB, oneExpr);
    actionExprs[0] = new NumericExpression(posExpr1, Expression.OP_ADD, fromExpr);
    SQLExpression elseExpr = new IntegerLiteral(stmt, exprFactory.getMappingForType(Integer.class, false), Integer.valueOf(-1), null);
    return new CaseNumericExpression(whenExprs, actionExprs, elseExpr);
}
Also used : ParameterLiteral(org.datanucleus.store.rdbms.sql.expression.ParameterLiteral) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) StringExpression(org.datanucleus.store.rdbms.sql.expression.StringExpression) ArrayList(java.util.ArrayList) CaseNumericExpression(org.datanucleus.store.rdbms.sql.expression.CaseNumericExpression) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) CaseNumericExpression(org.datanucleus.store.rdbms.sql.expression.CaseNumericExpression) NucleusException(org.datanucleus.exceptions.NucleusException) CharacterExpression(org.datanucleus.store.rdbms.sql.expression.CharacterExpression) IntegerLiteral(org.datanucleus.store.rdbms.sql.expression.IntegerLiteral)

Aggregations

ParameterLiteral (org.datanucleus.store.rdbms.sql.expression.ParameterLiteral)27 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)23 NucleusException (org.datanucleus.exceptions.NucleusException)17 StringExpression (org.datanucleus.store.rdbms.sql.expression.StringExpression)16 ArrayList (java.util.ArrayList)15 CharacterExpression (org.datanucleus.store.rdbms.sql.expression.CharacterExpression)12 BooleanExpression (org.datanucleus.store.rdbms.sql.expression.BooleanExpression)11 NumericExpression (org.datanucleus.store.rdbms.sql.expression.NumericExpression)11 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)7 StringLiteral (org.datanucleus.store.rdbms.sql.expression.StringLiteral)7 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)6 UnboundExpression (org.datanucleus.store.rdbms.sql.expression.UnboundExpression)6 IntegerLiteral (org.datanucleus.store.rdbms.sql.expression.IntegerLiteral)5 SQLLiteral (org.datanucleus.store.rdbms.sql.expression.SQLLiteral)4 DatastoreAdapter (org.datanucleus.store.rdbms.adapter.DatastoreAdapter)2 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 FetchPlanForClass (org.datanucleus.FetchPlanForClass)1