use of org.datanucleus.store.rdbms.sql.expression.StringExpression in project datanucleus-rdbms by datanucleus.
the class Concat3Operation method getExpression.
/* (non-Javadoc)
* @see org.datanucleus.store.rdbms.sql.operation.SQLOperation#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, org.datanucleus.store.rdbms.sql.expression.SQLExpression)
*/
public SQLExpression getExpression(SQLExpression expr, SQLExpression expr2) {
/*
* We cast it to VARCHAR otherwise the concatenation in derby it is promoted to LONG VARCHAR.
*
* In Derby, ? string parameters are promoted to LONG VARCHAR, and Derby
* does not allow comparisons between LONG VARCHAR types. so the below
* example would be invalid in Derby
* (THIS.FIRSTNAME||?) = ?
*
* Due to that we convert it to
* (CAST(THIS.FIRSTNAME||? AS VARCHAR(4000))) = ?
*
* The only issue with this solution is for columns bigger than 4000 chars.
* Secondly, if both operands are parameters, derby does not allow concatenation e.g.
* ? || ? is not allowed by derby
*
* so we do
* CAST(? AS VARCHAR(4000)) || CAST(? AS VARCHAR(4000))
*
* If both situations happen,
* (CAST(CAST( ? AS VARCHAR(4000) ) || CAST( ? AS VARCHAR(4000) ) AS VARCHAR(4000))) = ?
*/
JavaTypeMapping m = expr.getSQLStatement().getSQLExpressionFactory().getMappingForType(String.class, false);
List types = new ArrayList();
types.add("VARCHAR(4000)");
List argsOp1 = new ArrayList();
argsOp1.add(expr);
SQLExpression firstExpr = new StringExpression(expr.getSQLStatement(), m, "CAST", argsOp1, types).encloseInParentheses();
List argsOp2 = new ArrayList();
argsOp2.add(expr2);
SQLExpression secondExpr = new StringExpression(expr.getSQLStatement(), m, "CAST", argsOp2, types).encloseInParentheses();
StringExpression concatExpr = new StringExpression(expr.getSQLStatement(), null, null);
SQLText sql = concatExpr.toSQLText();
sql.clearStatement();
sql.append(firstExpr);
sql.append("||");
sql.append(secondExpr);
List args = new ArrayList();
args.add(concatExpr);
return new StringExpression(expr.getSQLStatement(), m, "CAST", args, types);
}
use of org.datanucleus.store.rdbms.sql.expression.StringExpression in project datanucleus-rdbms by datanucleus.
the class TemporalMonthMethod2 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) {
SQLExpression invokedExpr = getInvokedExpression(expr, args, "MONTH");
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
JavaTypeMapping mapping2 = storeMgr.getMappingManager().getMapping(String.class);
ArrayList funcArgs = new ArrayList();
funcArgs.add(invokedExpr);
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
funcArgs.add(exprFactory.newLiteral(stmt, mapping2, "MM"));
StringExpression charExpr = new StringExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(int.class, true), "TO_CHAR", funcArgs);
ArrayList funcArgs2 = new ArrayList();
funcArgs2.add(charExpr);
NumericExpression numExpr = new NumericExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(int.class, true), "TO_NUMBER", funcArgs2);
numExpr.encloseInParentheses();
return numExpr;
}
use of org.datanucleus.store.rdbms.sql.expression.StringExpression in project datanucleus-rdbms by datanucleus.
the class TemporalMinuteMethod2 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) {
SQLExpression invokedExpr = getInvokedExpression(expr, args, "MINUTE");
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
JavaTypeMapping mapping = storeMgr.getMappingManager().getMapping(String.class);
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
SQLExpression mi = exprFactory.newLiteral(stmt, mapping, "MI");
ArrayList funcArgs = new ArrayList();
funcArgs.add(invokedExpr);
funcArgs.add(mi);
ArrayList funcArgs2 = new ArrayList();
funcArgs2.add(new StringExpression(stmt, mapping, "TO_CHAR", funcArgs));
return new NumericExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(int.class, true), "TO_NUMBER", funcArgs2);
}
use of org.datanucleus.store.rdbms.sql.expression.StringExpression in project datanucleus-rdbms by datanucleus.
the class TemporalSecondMethod2 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) {
SQLExpression invokedExpr = getInvokedExpression(expr, args, "SECOND");
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
JavaTypeMapping mapping = storeMgr.getMappingManager().getMapping(String.class);
ArrayList funcArgs = new ArrayList();
funcArgs.add(invokedExpr);
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
funcArgs.add(exprFactory.newLiteral(stmt, mapping, "SS"));
ArrayList funcArgs2 = new ArrayList();
funcArgs2.add(new StringExpression(stmt, mapping, "TO_CHAR", funcArgs));
return new NumericExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(int.class, true), "TO_NUMBER", funcArgs2);
}
use of org.datanucleus.store.rdbms.sql.expression.StringExpression 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);
}
Aggregations