use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class MappingManagerImpl method getMapping.
/**
* Accessor for the mapping for the member of the specified table.
* Can be used for members of a class, element of a collection of a class, element of an array of a class,
* keys of a map of a class, values of a map of a class; this is controlled by the role argument.
* @param table Table to add the mapping to
* @param mmd MetaData for the member to map
* @param clr The ClassLoaderResolver
* @param fieldRole Role that this mapping plays for the field
* @return The mapping for the member.
*/
@Override
public JavaTypeMapping getMapping(Table table, AbstractMemberMetaData mmd, ClassLoaderResolver clr, FieldRole fieldRole) {
if (fieldRole == FieldRole.ROLE_COLLECTION_ELEMENT || fieldRole == FieldRole.ROLE_ARRAY_ELEMENT) {
// Mapping a collection/array element (in a join table)
return getElementMapping(table, mmd, fieldRole, clr);
} else if (fieldRole == FieldRole.ROLE_MAP_KEY) {
// Mapping a map key (in a join table)
return getKeyMapping(table, mmd, clr);
} else if (fieldRole == FieldRole.ROLE_MAP_VALUE) {
// Mapping a map value (in a join table)
return getValueMapping(table, mmd, clr);
}
// Check for use of TypeConverter (either specific, or auto-apply for this type)
TypeManager typeMgr = table.getStoreManager().getNucleusContext().getTypeManager();
TypeConverter conv = null;
if (!mmd.isTypeConversionDisabled()) {
// User-specified TypeConverter defined for the whole member, or an autoApply is present for this member type
if (mmd.getTypeConverterName() != null) {
conv = typeMgr.getTypeConverterForName(mmd.getTypeConverterName());
if (conv == null) {
throw new NucleusUserException(Localiser.msg("044062", mmd.getFullFieldName(), mmd.getTypeConverterName()));
}
} else {
TypeConverter autoApplyConv = typeMgr.getAutoApplyTypeConverterForType(mmd.getType());
if (autoApplyConv != null) {
conv = autoApplyConv;
}
}
if (conv != null) {
// Create the mapping of the selected type
JavaTypeMapping m = null;
if (conv instanceof MultiColumnConverter) {
Class mc = TypeConverterMultiMapping.class;
try {
m = (JavaTypeMapping) mc.getDeclaredConstructor().newInstance();
m.setRoleForMember(FieldRole.ROLE_FIELD);
((TypeConverterMultiMapping) m).initialize(mmd, table, clr, conv);
return m;
} catch (Exception e) {
throw new NucleusException(Localiser.msg("041009", mc.getName(), e), e).setFatal();
}
}
Class mc = TypeConverterMapping.class;
try {
m = (JavaTypeMapping) mc.getDeclaredConstructor().newInstance();
m.setRoleForMember(FieldRole.ROLE_FIELD);
((TypeConverterMapping) m).initialize(mmd, table, clr, conv);
return m;
} catch (Exception e) {
throw new NucleusException(Localiser.msg("041009", mc.getName(), e), e).setFatal();
}
}
}
AbstractMemberMetaData overrideMmd = null;
MappingConverterDetails mcd = null;
Class<? extends JavaTypeMapping> mc = null;
String userMappingClassName = mmd.getValueForExtension("mapping-class");
if (userMappingClassName != null) {
// User has defined their own mapping class for this field so use that
try {
mc = clr.classForName(userMappingClassName);
} catch (NucleusException ne) {
throw new NucleusUserException(Localiser.msg("041014", mmd.getFullFieldName(), userMappingClassName)).setFatal();
}
} else {
AbstractClassMetaData typeCmd = (mmd.getType().isInterface()) ? storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForInterface(mmd.getType(), clr) : storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(mmd.getType(), clr);
if (mmd.hasExtension(SerialisedLocalFileMapping.EXTENSION_SERIALIZE_TO_FOLDER) && Serializable.class.isAssignableFrom(mmd.getType())) {
// Special case : use file serialization mapping
mc = SerialisedLocalFileMapping.class;
} else if (mmd.isSerialized()) {
// Field is marked as serialised then we have no other option - serialise it
mcd = getMappingClass(mmd.getType(), true, false, null, mmd.getFullFieldName());
} else if (mmd.getEmbeddedMetaData() != null) {
// Field has an <embedded> specification so use that
mcd = getMappingClass(mmd.getType(), false, true, null, mmd.getFullFieldName());
} else if (typeCmd != null && typeCmd.isEmbeddedOnly()) {
// Reference type is declared with embedded only
mcd = getMappingClass(mmd.getType(), false, true, null, mmd.getFullFieldName());
} else if (// TODO Check this since it will push all basic nonPC fields through here
mmd.isEmbedded()) {
// Otherwise, if the field is embedded then we request that it be serialised into the owner table
// This is particularly for java.lang.Object which should be "embedded" by default, and hence serialised
mcd = getMappingClass(mmd.getType(), true, false, mmd.getColumnMetaData(), mmd.getFullFieldName());
} else {
// Non-embedded/non-serialised - Just get the basic mapping for the type
Class memberType = mmd.getType();
mcd = getMappingClass(memberType, false, false, mmd.getColumnMetaData(), mmd.getFullFieldName());
if (mmd.getParent() instanceof EmbeddedMetaData && mmd.getRelationType(clr) != RelationType.NONE) {
// See NUCCORE-697 - always need to use the real member metadata for the mapping
// so that it can find sub-fields when persisting/querying etc
AbstractClassMetaData cmdForFmd = table.getStoreManager().getMetaDataManager().getMetaDataForClass(mmd.getClassName(), clr);
overrideMmd = cmdForFmd.getMetaDataForMember(mmd.getName());
}
}
}
// Create the mapping of the selected type
if (mcd != null) {
mc = mcd.mappingClass;
// Allow override by Oracle
mc = getOverrideMappingClass(mc, mmd, fieldRole);
}
if (mc != null && (mcd == null || mcd.typeConverter == null)) {
try {
JavaTypeMapping m = mc.getDeclaredConstructor().newInstance();
m.setRoleForMember(FieldRole.ROLE_FIELD);
m.initialize(mmd, table, clr);
if (overrideMmd != null) {
// Note cannot just use this overrideMmd in the initialize(...) call above, a test fails.
m.setMemberMetaData(overrideMmd);
}
return m;
} catch (Exception e) {
throw new NucleusException(Localiser.msg("041009", mc.getName(), e), e).setFatal();
}
} else if (mcd != null && mcd.typeConverter != null) {
try {
JavaTypeMapping m = mcd.mappingClass.getDeclaredConstructor().newInstance();
m.setRoleForMember(FieldRole.ROLE_FIELD);
if (m instanceof TypeConverterMapping) {
((TypeConverterMapping) m).initialize(mmd, table, clr, mcd.typeConverter);
} else if (m instanceof TypeConverterMultiMapping) {
((TypeConverterMultiMapping) m).initialize(mmd, table, clr, mcd.typeConverter);
}
if (overrideMmd != null) {
// Note cannot just use this overrideMmd in the initialize(...) call above, a test fails.
m.setMemberMetaData(overrideMmd);
}
return m;
} catch (Exception e) {
throw new NucleusException(Localiser.msg("041009", mc.getName(), e), e).setFatal();
}
}
throw new NucleusException("Unable to create mapping for member at " + mmd.getFullFieldName() + " - no available mapping");
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class MappingManagerImpl method getElementMapping.
/**
* Convenience accessor for the element mapping for the element of a collection/array of elements.
* @param table The table
* @param mmd MetaData for the collection member containing the collection/array of PCs
* @param fieldRole role of this mapping for this member
* @param clr ClassLoader resolver
* @return The mapping
*/
protected JavaTypeMapping getElementMapping(Table table, AbstractMemberMetaData mmd, FieldRole fieldRole, ClassLoaderResolver clr) {
if (!mmd.hasCollection() && !mmd.hasArray()) {
// TODO Localise this message
throw new NucleusException("Attempt to get element mapping for field " + mmd.getFullFieldName() + " that has no collection/array!").setFatal();
}
if (mmd.getJoinMetaData() == null) {
AbstractMemberMetaData[] refMmds = mmd.getRelatedMemberMetaData(clr);
if (refMmds == null || refMmds.length == 0) {
// TODO Localise this
throw new NucleusException("Attempt to get element mapping for field " + mmd.getFullFieldName() + " that has no join table defined for the collection/array").setFatal();
}
if (refMmds[0].getJoinMetaData() == null) {
// TODO Localise this
throw new NucleusException("Attempt to get element mapping for field " + mmd.getFullFieldName() + " that has no join table defined for the collection/array").setFatal();
}
}
MappingConverterDetails mcd = null;
Class<? extends JavaTypeMapping> mc = null;
String userMappingClassName = null;
String userTypeConverterName = null;
if (mmd.getElementMetaData() != null) {
userTypeConverterName = mmd.getElementMetaData().getValueForExtension(MetaData.EXTENSION_MEMBER_TYPE_CONVERTER_NAME);
userMappingClassName = mmd.getElementMetaData().getValueForExtension("mapping-class");
}
if (userTypeConverterName != null) {
TypeConverter conv = storeMgr.getNucleusContext().getTypeManager().getTypeConverterForName(userTypeConverterName);
if (conv == null) {
throw new NucleusUserException("Field " + mmd.getFullFieldName() + " ELEMENT has been specified to use type converter " + userTypeConverterName + " but not found!");
}
// TODO Could be TypeConverterMultiMapping?
mcd = new MappingConverterDetails(TypeConverterMapping.class, conv);
} else if (userMappingClassName != null) {
// User has defined their own mapping class for this element so use that
try {
mc = clr.classForName(userMappingClassName);
} catch (NucleusException jpe) {
throw new NucleusUserException(Localiser.msg("041014", userMappingClassName)).setFatal();
}
} else {
boolean serialised = ((mmd.hasCollection() && mmd.getCollection().isSerializedElement()) || (mmd.hasArray() && mmd.getArray().isSerializedElement()));
boolean embeddedPC = (mmd.hasCollection() && mmd.getCollection().elementIsPersistent() && mmd.getCollection().isEmbeddedElement()) || (mmd.getElementMetaData() != null && mmd.getElementMetaData().getEmbeddedMetaData() != null);
boolean elementPC = ((mmd.hasCollection() && mmd.getCollection().elementIsPersistent()) || (mmd.hasArray() && mmd.getArray().elementIsPersistent()));
boolean embedded = true;
Class elementCls = null;
if (mmd.hasCollection()) {
embedded = mmd.getCollection().isEmbeddedElement();
elementCls = clr.classForName(mmd.getCollection().getElementType());
} else if (mmd.hasArray()) {
// Use declared element type rather than any restricted type specified in metadata
embedded = mmd.getArray().isEmbeddedElement();
elementCls = mmd.getType().getComponentType();
}
boolean elementReference = ClassUtils.isReferenceType(elementCls);
if (serialised) {
if (elementPC) {
// Serialised PC element
mc = SerialisedElementPCMapping.class;
} else if (elementReference) {
// Serialised Reference element
mc = SerialisedReferenceMapping.class;
} else {
// Serialised Non-PC element
mc = SerialisedMapping.class;
}
} else if (embedded) {
if (embeddedPC) {
// Embedded PC type
mc = EmbeddedElementPCMapping.class;
} else if (elementPC) {
// "Embedded" PC type but no <embedded> so dont embed for now. Is this correct?
mc = PersistableMapping.class;
} else {
// Embedded Non-PC type
mcd = getMappingClass(elementCls, serialised, embedded, mmd.getElementMetaData() != null ? mmd.getElementMetaData().getColumnMetaData() : null, mmd.getFullFieldName());
}
} else {
// Normal element mapping
mcd = getMappingClass(elementCls, serialised, embedded, mmd.getElementMetaData() != null ? mmd.getElementMetaData().getColumnMetaData() : null, mmd.getFullFieldName());
}
}
if (mcd != null && mcd.typeConverter == null) {
mc = mcd.mappingClass;
}
if (mc != null && (mcd == null || mcd.typeConverter == null)) {
// Create the mapping of the selected type
JavaTypeMapping m = null;
try {
m = mc.getDeclaredConstructor().newInstance();
m.setRoleForMember(fieldRole);
m.initialize(mmd, table, clr);
return m;
} catch (Exception e) {
throw new NucleusException(Localiser.msg("041009", mc.getName(), e), e).setFatal();
}
} else if (mcd != null && mcd.typeConverter != null) {
try {
JavaTypeMapping m = mcd.mappingClass.getDeclaredConstructor().newInstance();
m.setRoleForMember(fieldRole);
if (m instanceof TypeConverterMapping) {
((TypeConverterMapping) m).initialize(mmd, table, clr, mcd.typeConverter);
} else if (m instanceof TypeConverterMultiMapping) {
((TypeConverterMultiMapping) m).initialize(mmd, table, clr, mcd.typeConverter);
}
return m;
} catch (Exception e) {
throw new NucleusException(Localiser.msg("041009", mc != null ? mc.getName() : null, e), e).setFatal();
}
}
throw new NucleusException("Unable to create mapping for element of collection/array at " + mmd.getFullFieldName() + " - no available mapping");
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class MapContainsKeyMethod 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", "containsKey", "MapExpression", 1));
}
MapExpression mapExpr = (MapExpression) expr;
SQLExpression keyExpr = args.get(0);
if (keyExpr.isParameter()) {
// Key is a parameter so make sure its type is set
AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
if (mmd != null && mmd.getMap() != null) {
Class keyCls = stmt.getQueryGenerator().getClassLoaderResolver().classForName(mmd.getMap().getKeyType());
stmt.getQueryGenerator().bindParameter(keyExpr.getParameterName(), keyCls);
}
}
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
if (expr instanceof MapLiteral) {
// Literal Map
MapLiteral lit = (MapLiteral) expr;
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> mapKeyExprs = lit.getKeyLiteral().getKeyExpressions();
if (mapKeyExprs != null && !mapKeyExprs.isEmpty()) {
// Make sure the the map key(s) are compatible with the keyExpr
boolean incompatible = true;
Class elemtype = clr.classForName(keyExpr.getJavaTypeMapping().getType());
Iterator<SQLExpression> mapKeyExprIter = mapKeyExprs.iterator();
while (mapKeyExprIter.hasNext()) {
SQLExpression mapKeyExpr = mapKeyExprIter.next();
Class mapKeyType = clr.classForName(mapKeyExpr.getJavaTypeMapping().getType());
if (keyTypeCompatible(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 = mapKeyExprs.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 = (mapKeyExprs != null ? mapKeyExprs.toArray(new SQLExpression[mapKeyExprs.size()]) : null);
return new InExpression(keyExpr, exprs);
}
// TODO If keyExpr is a parameter and mapExpr is derived from a parameter ?
MapKeyLiteral mapKeyLiteral = lit.getKeyLiteral();
BooleanExpression bExpr = null;
List<SQLExpression> elementExprs = mapKeyLiteral.getKeyExpressions();
for (int i = 0; i < elementExprs.size(); i++) {
if (bExpr == null) {
bExpr = (elementExprs.get(i)).eq(keyExpr);
} else {
bExpr = bExpr.ior((elementExprs.get(i)).eq(keyExpr));
}
}
if (bExpr != null) {
bExpr.encloseInParentheses();
}
return bExpr;
}
if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.FILTER) {
boolean useSubquery = getNeedsSubquery(stmt);
JoinType joinType = JoinType.INNER_JOIN;
if (keyExpr instanceof UnboundExpression) {
// See if the user has defined what should be used
String varName = ((UnboundExpression) keyExpr).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* "containsKey" is negated, not any of them (and remove above check)
if (useSubquery) {
return containsAsSubquery(stmt, mapExpr, keyExpr);
}
return containsAsJoin(stmt, mapExpr, keyExpr, joinType);
}
return containsAsSubquery(stmt, mapExpr, keyExpr);
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class MapGetMethod method getAsInnerJoin.
/**
* Implementation of Map.get() using an inner join to the table representing the map, adding a condition on the key and returning the value.
* @param stmt SQLStatement
* @param mapExpr The map expression
* @param keyValExpr The key value expression
* @return The value expression
*/
protected SQLExpression getAsInnerJoin(SQLStatement stmt, MapExpression mapExpr, SQLExpression keyValExpr) {
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
JavaTypeMapping m = mapExpr.getJavaTypeMapping();
AbstractMemberMetaData mmd = m.getMemberMetaData();
if (mmd != null) {
MapMetaData mapmd = mmd.getMap();
if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
MapTable joinTbl = (MapTable) stmt.getRDBMSManager().getTable(mmd);
// Add join to join table
SQLTable joinSqlTbl = stmt.join(JoinType.INNER_JOIN, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), joinTbl, null, joinTbl.getOwnerMapping(), null, null);
// Add condition on key
SQLExpression keyExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getKeyMapping());
stmt.whereAnd(keyExpr.eq(keyValExpr), true);
// Return value expression
if (mapmd.getValueClassMetaData(clr) != null) {
// Persistable value so join to its table
DatastoreClass valTable = stmt.getRDBMSManager().getDatastoreClass(mapmd.getValueType(), clr);
SQLTable valueSqlTbl = stmt.join(JoinType.INNER_JOIN, joinSqlTbl, joinTbl.getValueMapping(), valTable, null, valTable.getIdMapping(), null, null);
return exprFactory.newExpression(stmt, valueSqlTbl, valTable.getIdMapping());
}
// Return mapping for the value in the join table
SQLExpression valueExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getValueMapping());
return valueExpr;
} else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
// Key stored in value table, so join to value table
DatastoreClass valTable = stmt.getRDBMSManager().getDatastoreClass(mapmd.getValueType(), clr);
AbstractClassMetaData valCmd = mapmd.getValueClassMetaData(clr);
JavaTypeMapping mapTblOwnerMapping;
if (mmd.getMappedBy() != null) {
mapTblOwnerMapping = valTable.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
mapTblOwnerMapping = valTable.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable valSqlTbl = stmt.join(JoinType.INNER_JOIN, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), valTable, null, mapTblOwnerMapping, null, null);
// Add condition on key
JavaTypeMapping keyMapping = valTable.getMemberMapping(valCmd.getMetaDataForMember(mmd.getKeyMetaData().getMappedBy()));
SQLExpression keyExpr = exprFactory.newExpression(stmt, valSqlTbl, keyMapping);
stmt.whereAnd(keyExpr.eq(keyValExpr), true);
// Return value expression
SQLExpression valueExpr = exprFactory.newExpression(stmt, valSqlTbl, valTable.getIdMapping());
return valueExpr;
} else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
// Value stored in key table, so join to key table
DatastoreClass keyTable = stmt.getRDBMSManager().getDatastoreClass(mapmd.getKeyType(), clr);
AbstractClassMetaData keyCmd = mapmd.getKeyClassMetaData(clr);
JavaTypeMapping mapTblOwnerMapping;
if (mmd.getMappedBy() != null) {
mapTblOwnerMapping = keyTable.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
mapTblOwnerMapping = keyTable.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable keySqlTbl = stmt.join(JoinType.INNER_JOIN, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), keyTable, null, mapTblOwnerMapping, null, null);
// Add condition on key
SQLExpression keyExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTable.getIdMapping());
stmt.whereAnd(keyExpr.eq(keyValExpr), true);
// Return value expression
JavaTypeMapping valueMapping = keyTable.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getValueMetaData().getMappedBy()));
SQLExpression valueExpr = exprFactory.newExpression(stmt, keySqlTbl, valueMapping);
return valueExpr;
}
}
throw new NucleusException("Map.get() for the filter is not supported for " + mapExpr + " with an argument of " + keyValExpr + ". Why not contribute support for it?");
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class ListGetMethod 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", "get", "CollectionExpression", 1));
}
CollectionExpression listSqlExpr = (CollectionExpression) expr;
AbstractMemberMetaData mmd = listSqlExpr.getJavaTypeMapping().getMemberMetaData();
if (mmd == null) {
// TODO Cater for the List being an input parameter
throw new NucleusException(Localiser.msg("060020", "indexOf", listSqlExpr.getClass().getName()));
}
if (!List.class.isAssignableFrom(mmd.getType())) {
throw new UnsupportedOperationException("Query contains " + expr + ".get(int) yet the field is not a List!");
} else if (mmd.getOrderMetaData() != null && !mmd.getOrderMetaData().isIndexedList()) {
throw new UnsupportedOperationException("Query contains " + expr + ".get(int) yet the field is not an 'indexed' List!");
}
SQLExpression idxExpr = args.get(0);
if (idxExpr instanceof SQLLiteral) {
if (!(((SQLLiteral) idxExpr).getValue() instanceof Number)) {
throw new UnsupportedOperationException("Query contains " + expr + ".get(int) yet the index is not a numeric literal so not yet supported");
}
} else {
throw new UnsupportedOperationException("Query contains " + expr + ".get(int) yet the index is not a numeric literal so not yet supported");
}
if (listSqlExpr instanceof CollectionLiteral && idxExpr instanceof SQLLiteral) {
CollectionLiteral lit = (CollectionLiteral) expr;
if (lit.getValue() == null) {
return new NullLiteral(stmt, null, null, null);
}
return lit.invoke("get", args);
}
if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.FILTER) {
return getAsInnerJoin(stmt, listSqlExpr, idxExpr);
} else if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.ORDERING || stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.RESULT || stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.HAVING) {
return getAsSubquery(stmt, listSqlExpr, idxExpr);
}
throw new NucleusException("List.get() is not supported for " + listSqlExpr + " with argument " + idxExpr + " for query component " + stmt.getQueryGenerator().getCompilationComponent());
}
Aggregations