use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class ArrayContainsMethod method containsAsSubquery.
/**
* Method to return an expression for Collection.contains using a subquery "EXISTS".
* This is for use when there are "!contains" or "OR" operations in the filter.
* Creates the following SQL,
* <ul>
* <li><b>Collection of NonPC using join table</b>
* <pre>
* SELECT 1 FROM JOIN_TBL A0_SUB
* WHERE A0_SUB.JOIN_OWN_ID = A0.ID AND A0_SUB.JOIN_ELEM_ID = {elemExpr}
* </pre>
* </li>
* <li><b>Collection of PC using join table</b>
* <pre>
* SELECT 1 FROM ELEM_TABLE A0_SUB INNER JOIN JOIN_TBL B0 ON ...
* WHERE B0.JOIN_OWN_ID = A0.ID AND A0_SUB.ID = {elemExpr}
* </pre>
* </li>
* </ul>
* and returns a BooleanSubqueryExpression ("EXISTS (subquery)")
* @param stmt SQLStatement
* @param arrExpr Collection expression
* @param elemExpr Expression for the element
* @return Contains expression
*/
protected SQLExpression containsAsSubquery(SQLStatement stmt, ArrayExpression arrExpr, SQLExpression elemExpr) {
boolean elemIsUnbound = (elemExpr instanceof UnboundExpression);
String varName = null;
if (elemIsUnbound) {
varName = ((UnboundExpression) elemExpr).getVariableName();
NucleusLogger.QUERY.debug(">> Array.contains binding unbound variable " + varName + " using SUBQUERY");
}
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
AbstractMemberMetaData mmd = arrExpr.getJavaTypeMapping().getMemberMetaData();
AbstractClassMetaData elemCmd = mmd.getArray().getElementClassMetaData(clr);
ArrayTable joinTbl = (ArrayTable) storeMgr.getTable(mmd);
SelectStatement subStmt = null;
if (joinTbl != null) {
// JoinTable array
if (elemCmd == null) {
// Array<Non-PC>
subStmt = new SelectStatement(stmt, storeMgr, joinTbl, null, null);
subStmt.setClassLoaderResolver(clr);
JavaTypeMapping oneMapping = storeMgr.getMappingManager().getMapping(Integer.class);
subStmt.select(exprFactory.newLiteral(subStmt, oneMapping, 1), null);
// Restrict to array owner
JavaTypeMapping ownerMapping = ((JoinTable) joinTbl).getOwnerMapping();
SQLExpression ownerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, arrExpr.getSQLTable(), arrExpr.getSQLTable().getTable().getIdMapping());
subStmt.whereAnd(ownerExpr.eq(ownerIdExpr), true);
SQLExpression elemIdExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), joinTbl.getElementMapping());
if (elemIsUnbound) {
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, null, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
subStmt.whereAnd(elemIdExpr.eq(elemExpr), true);
}
} else {
// Array<PC>
DatastoreClass elemTbl = storeMgr.getDatastoreClass(mmd.getArray().getElementType(), clr);
subStmt = new SelectStatement(stmt, storeMgr, elemTbl, null, null);
subStmt.setClassLoaderResolver(clr);
JavaTypeMapping oneMapping = storeMgr.getMappingManager().getMapping(Integer.class);
subStmt.select(exprFactory.newLiteral(subStmt, oneMapping, 1), null);
// Join to join table
SQLTable joinSqlTbl = subStmt.join(JoinType.INNER_JOIN, subStmt.getPrimaryTable(), elemTbl.getIdMapping(), null, joinTbl, null, joinTbl.getElementMapping(), null, null, null, true, null);
// Restrict to array owner
JavaTypeMapping ownerMapping = ((JoinTable) joinTbl).getOwnerMapping();
SQLExpression ownerExpr = exprFactory.newExpression(subStmt, joinSqlTbl, ownerMapping);
SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, arrExpr.getSQLTable(), arrExpr.getSQLTable().getTable().getIdMapping());
subStmt.whereAnd(ownerExpr.eq(ownerIdExpr), true);
SQLExpression elemIdExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), elemTbl.getIdMapping());
if (elemIsUnbound) {
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, elemCmd, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
subStmt.whereAnd(elemIdExpr.eq(elemExpr), true);
}
}
} else {
// TODO Support FK array ?
throw new NucleusException("Dont support evaluation of ARRAY.contains when no join table is used");
}
return new BooleanSubqueryExpression(stmt, "EXISTS", subStmt);
}
use of org.datanucleus.exceptions.NucleusException 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().getMappingWithColumnMapping(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;
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class CoalesceFunction 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 = null;
int clsLevel = 0;
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("COALESCE 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;
}
}
}
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
if (exprType == NumericExpression.class) {
return new NumericExpression(stmt, exprFactory.getMappingForType(cls, true), "COALESCE", args);
} else if (exprType == StringExpression.class) {
return new StringExpression(stmt, exprFactory.getMappingForType(cls, true), "COALESCE", args);
} else if (exprType == TemporalExpression.class) {
return new TemporalExpression(stmt, exprFactory.getMappingForType(cls, true), "COALESCE", args);
} else {
return new ObjectExpression(stmt, exprFactory.getMappingForType(cls, true), "COALESCE", args);
}
}
throw new NucleusException(Localiser.msg("060002", "COALESCE", expr));
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class CurrentTimeFunction 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) {
// Assume that we have something like "CURRENT_DATE()"
SQLExpression dateExpr = new TemporalExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(getClassForMapping(), true), getFunctionName(), args);
// Update the SQL manually since the default is to add brackets after the name
dateExpr.toSQLText().clearStatement();
dateExpr.toSQLText().append(getFunctionName());
return dateExpr;
}
throw new NucleusException(Localiser.msg("060002", getFunctionName(), expr));
}
use of org.datanucleus.exceptions.NucleusException 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);
}
Aggregations