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;
}
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;
}
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;
}
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;
}
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);
}
Aggregations