use of org.datanucleus.store.rdbms.sql.expression.NumericExpression in project datanucleus-rdbms by datanucleus.
the class CollectionContainsMethod 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() > 1) {
throw new NucleusException(Localiser.msg("060016", "contains", "CollectionExpression", 1));
}
CollectionExpression collExpr = (CollectionExpression) expr;
AbstractMemberMetaData mmd = collExpr.getJavaTypeMapping().getMemberMetaData();
SQLExpression elemExpr = args.get(0);
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
if (elemExpr.isParameter()) {
// Element is a parameter so make sure its type is set
if (mmd != null && mmd.getCollection() != null) {
Class elementCls = stmt.getQueryGenerator().getClassLoaderResolver().classForName(mmd.getCollection().getElementType());
stmt.getQueryGenerator().bindParameter(elemExpr.getParameterName(), elementCls);
}
}
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
if (collExpr instanceof CollectionLiteral) {
// Literal collection
CollectionLiteral lit = (CollectionLiteral) collExpr;
Collection coll = (Collection) lit.getValue();
JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
if (coll == null || coll.isEmpty()) {
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
}
if (collExpr.isParameter()) {
stmt.getQueryGenerator().useParameterExpressionAsLiteral((CollectionLiteral) collExpr);
}
boolean useInExpression = false;
List<SQLExpression> collElementExprs = lit.getElementExpressions();
if (collElementExprs != null && !collElementExprs.isEmpty()) {
// Make sure the the collection element(s) are compatible with the elemExpr
boolean incompatible = true;
Class elemtype = clr.classForName(elemExpr.getJavaTypeMapping().getType());
Iterator<SQLExpression> collElementExprIter = collElementExprs.iterator();
while (collElementExprIter.hasNext()) {
SQLExpression collElementExpr = collElementExprIter.next();
Class collElemType = clr.classForName(collElementExpr.getJavaTypeMapping().getType());
if (elementTypeCompatible(elemtype, collElemType)) {
incompatible = false;
break;
}
}
if (incompatible) {
// The provided element type isn't assignable to any of the input collection elements!
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
}
// Check if we should compare using an "IN (...)" expression
SQLExpression collElementExpr = collElementExprs.get(0);
if (collElementExpr instanceof StringExpression || collElementExpr instanceof NumericExpression || collElementExpr instanceof TemporalExpression || collElementExpr instanceof CharacterExpression || collElementExpr instanceof EnumExpression) {
useInExpression = true;
}
}
if (useInExpression) {
// Return "elem IN (val1, val2, ...)"
SQLExpression[] exprs = (collElementExprs != null ? collElementExprs.toArray(new SQLExpression[collElementExprs.size()]) : null);
return new InExpression(elemExpr, exprs);
}
// Return "elem == val1 || elem == val2 || elem == val3 ..."
BooleanExpression bExpr = null;
if (collElementExprs != null) {
for (int i = 0; i < collElementExprs.size(); i++) {
if (bExpr == null) {
bExpr = (collElementExprs.get(i)).eq(elemExpr);
} else {
bExpr = bExpr.ior((collElementExprs.get(i)).eq(elemExpr));
}
}
}
if (bExpr != null) {
bExpr.encloseInParentheses();
}
return bExpr;
}
if (mmd == null) {
throw new NucleusUserException("Cannot perform Collection.contains when the field metadata is not provided");
}
if (mmd.isSerialized()) {
throw new NucleusUserException("Cannot perform Collection.contains when the collection is being serialised");
}
ApiAdapter api = stmt.getRDBMSManager().getApiAdapter();
Class elementType = clr.classForName(mmd.getCollection().getElementType());
if (!api.isPersistable(elementType) && mmd.getJoinMetaData() == null) {
throw new NucleusUserException("Cannot perform Collection.contains when the collection<Non-Persistable> is not in a join table");
}
if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.FILTER) {
boolean useSubquery = getNeedsSubquery(stmt, collExpr, elemExpr);
JoinType joinType = JoinType.INNER_JOIN;
if (elemExpr instanceof UnboundExpression) {
// See if the user has defined what should be used
String varName = ((UnboundExpression) elemExpr).getVariableName();
String extensionName = "datanucleus.query.jdoql." + varName + ".join";
String extensionValue = (String) stmt.getQueryGenerator().getValueForExtension(extensionName);
if (extensionValue != null) {
if (extensionValue.equalsIgnoreCase("SUBQUERY")) {
useSubquery = true;
} else if (extensionValue.equalsIgnoreCase("INNERJOIN")) {
useSubquery = false;
} else if (extensionValue.equalsIgnoreCase("LEFTOUTERJOIN")) {
joinType = JoinType.LEFT_OUTER_JOIN;
}
}
}
if (useSubquery) {
return containsAsSubquery(stmt, collExpr, elemExpr);
}
return containsAsJoin(stmt, collExpr, elemExpr, joinType);
}
return containsAsSubquery(stmt, collExpr, elemExpr);
}
use of org.datanucleus.store.rdbms.sql.expression.NumericExpression in project datanucleus-rdbms by datanucleus.
the class JDOHelperGetVersionMethod 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 ignore, List<SQLExpression> args) {
if (args == null || args.size() == 0) {
throw new NucleusUserException("Cannot invoke JDOHelper.getVersion without an argument");
}
SQLExpression expr = args.get(0);
if (expr == null) {
throw new NucleusUserException("Cannot invoke JDOHelper.getVersion on null expression");
}
if (expr instanceof SQLLiteral) {
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ApiAdapter api = storeMgr.getApiAdapter();
Object obj = ((SQLLiteral) expr).getValue();
if (obj == null || !api.isPersistable(obj)) {
return new NullLiteral(stmt, null, null, null);
}
Object ver = stmt.getRDBMSManager().getApiAdapter().getVersionForObject(obj);
JavaTypeMapping m = stmt.getSQLExpressionFactory().getMappingForType(ver.getClass(), true);
return new ObjectLiteral(stmt, m, ver, null);
} else if (ObjectExpression.class.isAssignableFrom(expr.getClass())) {
if (((ObjectExpression) expr).getJavaTypeMapping() instanceof PersistableMapping) {
JavaTypeMapping mapping = ((ObjectExpression) expr).getJavaTypeMapping();
DatastoreClass table = (DatastoreClass) expr.getSQLTable().getTable();
if (// Version of candidate
table.getIdMapping() == mapping) {
mapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, true);
if (mapping == null) {
throw new NucleusUserException("Cannot use JDOHelper.getVersion on object that has no version information");
}
if (table.getVersionMetaData().getStrategy() == VersionStrategy.VERSION_NUMBER) {
return new NumericExpression(stmt, expr.getSQLTable(), mapping);
}
return new TemporalExpression(stmt, expr.getSQLTable(), mapping);
}
throw new NucleusUserException("Dont currently support JDOHelper.getVersion(ObjectExpression) for expr=" + expr + " on table=" + expr.getSQLTable());
// TODO Implement this
}
return expr;
}
throw new IllegalExpressionOperationException("JDOHelper.getVersion", expr);
}
use of org.datanucleus.store.rdbms.sql.expression.NumericExpression in project datanucleus-rdbms by datanucleus.
the class MapContainsValueMethod 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() > 1) {
throw new NucleusException(Localiser.msg("060016", "containsValue", "MapExpression", 1));
}
MapExpression mapExpr = (MapExpression) expr;
SQLExpression valExpr = args.get(0);
if (valExpr.isParameter()) {
// Value is a parameter so make sure its type is set
AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
if (mmd != null && mmd.getMap() != null) {
Class valCls = stmt.getQueryGenerator().getClassLoaderResolver().classForName(mmd.getMap().getValueType());
stmt.getQueryGenerator().bindParameter(valExpr.getParameterName(), valCls);
}
}
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
if (mapExpr instanceof MapLiteral) {
MapLiteral lit = (MapLiteral) mapExpr;
Map map = (Map) lit.getValue();
JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
if (map == null || map.size() == 0) {
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
}
boolean useInExpression = false;
List<SQLExpression> mapValExprs = lit.getValueLiteral().getValueExpressions();
if (mapValExprs != null && !mapValExprs.isEmpty()) {
// Make sure the the map key(s) are compatible with the keyExpr
boolean incompatible = true;
Class elemtype = clr.classForName(valExpr.getJavaTypeMapping().getType());
Iterator<SQLExpression> mapKeyExprIter = mapValExprs.iterator();
while (mapKeyExprIter.hasNext()) {
SQLExpression mapKeyExpr = mapKeyExprIter.next();
Class mapKeyType = clr.classForName(mapKeyExpr.getJavaTypeMapping().getType());
if (valueTypeCompatible(elemtype, mapKeyType)) {
incompatible = false;
break;
}
}
if (incompatible) {
// The provided element type isn't assignable to any of the input collection elements!
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
}
// Check if we should compare using an "IN (...)" expression
SQLExpression mapKeyExpr = mapValExprs.get(0);
if (mapKeyExpr instanceof StringExpression || mapKeyExpr instanceof NumericExpression || mapKeyExpr instanceof TemporalExpression || mapKeyExpr instanceof CharacterExpression || mapKeyExpr instanceof EnumExpression) {
useInExpression = true;
}
}
if (useInExpression) {
// Return "key IN (val1, val2, ...)"
SQLExpression[] exprs = (mapValExprs != null ? mapValExprs.toArray(new SQLExpression[mapValExprs.size()]) : null);
return new InExpression(valExpr, exprs);
}
// TODO If valExpr is a parameter and mapExpr is derived from a parameter ?
MapValueLiteral mapValueLiteral = lit.getValueLiteral();
BooleanExpression bExpr = null;
List<SQLExpression> elementExprs = mapValueLiteral.getValueExpressions();
for (int i = 0; i < elementExprs.size(); i++) {
if (bExpr == null) {
bExpr = (elementExprs.get(i)).eq(valExpr);
} else {
bExpr = bExpr.ior((elementExprs.get(i)).eq(valExpr));
}
}
if (bExpr != null) {
bExpr.encloseInParentheses();
}
return bExpr;
}
if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.FILTER) {
boolean useSubquery = getNeedsSubquery(stmt);
JoinType joinType = JoinType.INNER_JOIN;
if (valExpr instanceof UnboundExpression) {
// See if the user has defined what should be used
String varName = ((UnboundExpression) valExpr).getVariableName();
String extensionName = "datanucleus.query.jdoql." + varName + ".join";
String extensionValue = (String) stmt.getQueryGenerator().getValueForExtension(extensionName);
if (extensionValue != null) {
if (extensionValue.equalsIgnoreCase("SUBQUERY")) {
useSubquery = true;
} else if (extensionValue.equalsIgnoreCase("INNERJOIN")) {
useSubquery = false;
} else if (extensionValue.equalsIgnoreCase("LEFTOUTERJOIN")) {
joinType = JoinType.LEFT_OUTER_JOIN;
}
}
}
// TODO Check if *this* "containsValue" is negated, not any of them (and remove above check)
if (useSubquery) {
return containsAsSubquery(stmt, mapExpr, valExpr);
}
return containsAsJoin(stmt, mapExpr, valExpr, joinType);
}
return containsAsSubquery(stmt, mapExpr, valExpr);
}
use of org.datanucleus.store.rdbms.sql.expression.NumericExpression in project datanucleus-rdbms by datanucleus.
the class NullIfFunction 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 (expr == null) {
// Find expression type that this handles - all expressions need to be consistent in our implementation
Class exprType = null;
Class cls = Integer.class;
int clsLevel = 0;
// Priority order is Double, Float, BigDecimal, BigInteger, Long, Integer
for (int i = 0; i < args.size(); i++) {
SQLExpression argExpr = args.get(i);
if (exprType == null) {
if (argExpr instanceof NumericExpression) {
exprType = NumericExpression.class;
cls = Integer.class;
} else if (argExpr instanceof StringExpression) {
exprType = StringExpression.class;
cls = String.class;
} else if (argExpr instanceof TemporalExpression) {
exprType = TemporalExpression.class;
cls = argExpr.getJavaTypeMapping().getJavaType();
} else {
exprType = argExpr.getClass();
cls = argExpr.getJavaTypeMapping().getJavaType();
}
} else {
if (!exprType.isAssignableFrom(argExpr.getClass())) {
throw new NucleusUserException("NULLIF invocation first argument of type " + exprType.getName() + " yet subsequent argument of type " + argExpr.getClass().getName());
}
}
if (exprType == NumericExpression.class) {
// Priority order is Double, Float, BigDecimal, BigInteger, Long, Integer
Class argType = argExpr.getJavaTypeMapping().getJavaType();
if (clsLevel < 5 && (argType == double.class || argType == Double.class)) {
cls = Double.class;
clsLevel = 5;
} else if (clsLevel < 4 && (argType == float.class || argType == Float.class)) {
cls = Float.class;
clsLevel = 4;
} else if (clsLevel < 3 && argType == BigDecimal.class) {
cls = BigDecimal.class;
clsLevel = 3;
} else if (clsLevel < 2 && argType == BigInteger.class) {
cls = BigInteger.class;
clsLevel = 2;
} else if (clsLevel < 1 && (argType == long.class || argType == Long.class)) {
cls = Long.class;
clsLevel = 1;
}
}
}
if (exprType == NumericExpression.class) {
return new NumericExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(cls, true), "NULLIF", args);
} else if (exprType == StringExpression.class) {
return new StringExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(cls, true), "NULLIF", args);
} else if (exprType == TemporalExpression.class) {
return new TemporalExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(cls, true), "NULLIF", args);
} else {
return new ObjectExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(cls, true), "NULLIF", args);
}
}
throw new NucleusException(Localiser.msg("060002", "NULLIF", expr));
}
use of org.datanucleus.store.rdbms.sql.expression.NumericExpression in project datanucleus-rdbms by datanucleus.
the class SQLNumericMethod 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 ignore, List<SQLExpression> args) {
if (args == null || args.size() != 1) {
throw new NucleusUserException("Cannot invoke SQL_numeric() without a string argument");
}
SQLExpression expr = args.get(0);
if (!(expr instanceof StringLiteral)) {
throw new NucleusUserException("Cannot use SQL_numeric() without string argument");
}
String sql = (String) ((StringLiteral) expr).getValue();
JavaTypeMapping m = stmt.getSQLExpressionFactory().getMappingForType(boolean.class, false);
NumericExpression retExpr = new NumericExpression(stmt, m, sql);
return retExpr;
}
Aggregations