use of org.datanucleus.store.rdbms.sql.expression.ArrayLiteral in project datanucleus-rdbms by datanucleus.
the class ArrayContainsMethod 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() != 1) {
throw new NucleusException("Incorrect arguments for Array.contains(SQLExpression)");
}
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
ArrayExpression arrExpr = (ArrayExpression) expr;
SQLExpression elemExpr = args.get(0);
if (elemExpr.isParameter()) {
// Element is a parameter so make sure its type is set
AbstractMemberMetaData mmd = arrExpr.getJavaTypeMapping().getMemberMetaData();
if (mmd != null) {
stmt.getQueryGenerator().bindParameter(elemExpr.getParameterName(), mmd.getType().getComponentType());
}
}
if (expr instanceof ArrayLiteral) {
if (elemExpr instanceof UnboundExpression) {
Class elemCls = clr.classForName(arrExpr.getJavaTypeMapping().getType()).getComponentType();
elemExpr = stmt.getQueryGenerator().bindVariable((UnboundExpression) elemExpr, elemCls);
}
ArrayLiteral lit = (ArrayLiteral) expr;
Object array = lit.getValue();
JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
if (array == null || Array.getLength(array) == 0) {
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
}
if (arrExpr.isParameter()) {
stmt.getQueryGenerator().useParameterExpressionAsLiteral((ArrayLiteral) arrExpr);
}
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);
}
// TODO If elemExpr is a parameter and collExpr is derived from a parameter ?
BooleanExpression bExpr = null;
List<SQLExpression> elementExprs = lit.getElementExpressions();
for (int i = 0; i < elementExprs.size(); i++) {
SQLExpression arrElemExpr = elementExprs.get(i);
if (bExpr == null) {
bExpr = arrElemExpr.eq(elemExpr);
} else {
bExpr = bExpr.ior(arrElemExpr.eq(elemExpr));
}
}
if (bExpr != null) {
bExpr.encloseInParentheses();
}
return bExpr;
} else if (arrExpr.getElementExpressions() != null) {
if (elemExpr instanceof UnboundExpression) {
Class elemCls = clr.classForName(arrExpr.getJavaTypeMapping().getType()).getComponentType();
elemExpr = stmt.getQueryGenerator().bindVariable((UnboundExpression) elemExpr, elemCls);
}
// Array defined in query that has some expressions for elements, so just do OR chain
BooleanExpression bExpr = null;
List<SQLExpression> elementExprs = arrExpr.getElementExpressions();
for (int i = 0; i < elementExprs.size(); i++) {
SQLExpression arrElemExpr = elementExprs.get(i);
if (bExpr == null) {
bExpr = arrElemExpr.eq(elemExpr);
} else {
bExpr = bExpr.ior(arrElemExpr.eq(elemExpr));
}
}
if (bExpr != null) {
bExpr.encloseInParentheses();
}
return bExpr;
} else {
// TODO Support inner join variant
return containsAsSubquery(stmt, arrExpr, elemExpr);
}
}
use of org.datanucleus.store.rdbms.sql.expression.ArrayLiteral in project datanucleus-rdbms by datanucleus.
the class ArrayIsEmptyMethod 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) {
throw new NucleusException(Localiser.msg("060015", "isEmpty", "ArrayExpression"));
}
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
if (expr instanceof ArrayLiteral) {
Object arr = ((ArrayLiteral) expr).getValue();
boolean isEmpty = (arr == null || Array.getLength(arr) == 0);
JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, false);
return new BooleanLiteral(stmt, m, isEmpty ? Boolean.TRUE : Boolean.FALSE);
}
SQLExpression sizeExpr = exprFactory.invokeMethod(stmt, "ARRAY", "size", expr, args);
JavaTypeMapping mapping = exprFactory.getMappingForType(Integer.class, true);
SQLExpression zeroExpr = exprFactory.newLiteral(stmt, mapping, 0);
return sizeExpr.eq(zeroExpr);
}
use of org.datanucleus.store.rdbms.sql.expression.ArrayLiteral in project datanucleus-rdbms by datanucleus.
the class ArraySizeMethod 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) {
throw new NucleusException(Localiser.msg("060015", "size/length", "ArrayExpression"));
}
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
if (expr instanceof ArrayLiteral) {
// Just return the array length since we have the value
return exprFactory.newLiteral(stmt, exprFactory.getMappingForType(int.class, false), Integer.valueOf(Array.getLength(((ArrayLiteral) expr).getValue())));
}
AbstractMemberMetaData ownerMmd = expr.getJavaTypeMapping().getMemberMetaData();
String elementType = ownerMmd.getArray().getElementType();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
// TODO Allow for interface elements, etc
JavaTypeMapping ownerMapping = null;
Table arrayTbl = null;
if (ownerMmd.getMappedBy() != null) {
// Bidirectional
AbstractMemberMetaData elementMmd = ownerMmd.getRelatedMemberMetaData(clr)[0];
if (ownerMmd.getJoinMetaData() != null || elementMmd.getJoinMetaData() != null) {
// JoinTable
arrayTbl = storeMgr.getTable(ownerMmd);
ownerMapping = ((JoinTable) arrayTbl).getOwnerMapping();
} else {
// ForeignKey
arrayTbl = storeMgr.getDatastoreClass(elementType, clr);
ownerMapping = arrayTbl.getMemberMapping(elementMmd);
}
} else {
// Unidirectional
if (ownerMmd.getJoinMetaData() != null) {
// JoinTable
arrayTbl = storeMgr.getTable(ownerMmd);
ownerMapping = ((JoinTable) arrayTbl).getOwnerMapping();
} else {
// ForeignKey
arrayTbl = storeMgr.getDatastoreClass(elementType, clr);
ownerMapping = ((DatastoreClass) arrayTbl).getExternalMapping(ownerMmd, MappingType.EXTERNAL_FK);
}
}
SelectStatement subStmt = new SelectStatement(stmt, storeMgr, arrayTbl, null, null);
subStmt.setClassLoaderResolver(clr);
JavaTypeMapping mapping = storeMgr.getMappingManager().getMappingWithDatastoreMapping(String.class, false, false, clr);
SQLExpression countExpr = exprFactory.newLiteral(subStmt, mapping, "COUNT(*)");
((StringLiteral) countExpr).generateStatementWithoutQuotes();
subStmt.select(countExpr, null);
SQLExpression elementOwnerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, expr.getSQLTable(), expr.getSQLTable().getTable().getIdMapping());
subStmt.whereAnd(elementOwnerExpr.eq(ownerIdExpr), true);
JavaTypeMapping subqMapping = exprFactory.getMappingForType(Integer.class, false);
SQLExpression subqExpr = new NumericSubqueryExpression(stmt, subStmt);
subqExpr.setJavaTypeMapping(subqMapping);
return subqExpr;
}
Aggregations