Search in sources :

Example 81 with SQLExpressionFactory

use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory in project datanucleus-rdbms by datanucleus.

the class MapContainsKeyMethod method containsAsJoin.

/**
 * Method to return an expression for Map.containsKey using INNER JOIN to the element.
 * This is only for use when there are no "!containsKey" and no "OR" operations.
 * Creates SQL by adding INNER JOIN to the join table (where it exists), and also to the key table
 * adding an AND condition on the element (with value of the keyExpr).
 * Returns a BooleanExpression "TRUE" (since the INNER JOIN will guarantee if the key is contained of not).
 * @param stmt SQLStatement
 * @param mapExpr Map expression
 * @param keyExpr Expression for the key
 * @param joinType Type of join
 * @return Contains expression
 */
protected SQLExpression containsAsJoin(SQLStatement stmt, MapExpression mapExpr, SQLExpression keyExpr, JoinType joinType) {
    boolean keyIsUnbound = (keyExpr instanceof UnboundExpression);
    String varName = null;
    String keyAlias = null;
    if (keyIsUnbound) {
        varName = ((UnboundExpression) keyExpr).getVariableName();
        NucleusLogger.QUERY.debug("map.containsKey(" + keyExpr + ") binding unbound variable " + varName + " using INNER JOIN");
    // TODO What if the variable is declared as a subtype, handle this see CollectionContainsMethod
    } else if (!stmt.getQueryGenerator().hasExplicitJoins()) {
        if (stmt.getJoinTypeForTable(keyExpr.getSQLTable()) == JoinType.CROSS_JOIN) {
            keyAlias = stmt.removeCrossJoin(keyExpr.getSQLTable());
            keyIsUnbound = true;
            NucleusLogger.QUERY.debug("map.containsKey(" + keyExpr + ") was previously bound as CROSS JOIN but changing to INNER JOIN");
        }
    }
    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
    AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
    AbstractClassMetaData keyCmd = mmd.getMap().getKeyClassMetaData(clr);
    if (mmd.getMap().getMapType() == MapType.MAP_TYPE_JOIN) {
        // Map formed in join table - add join to join table, then to key table (if present)
        MapTable mapTbl = (MapTable) storeMgr.getTable(mmd);
        SQLTable joinSqlTbl = stmt.join(joinType, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), mapTbl, null, mapTbl.getOwnerMapping(), null, null);
        if (keyCmd != null) {
            if (keyIsUnbound) {
                DatastoreClass keyTbl = storeMgr.getDatastoreClass(keyCmd.getFullClassName(), clr);
                SQLTable keySqlTbl = stmt.join(joinType, joinSqlTbl, mapTbl.getKeyMapping(), keyTbl, keyAlias, keyTbl.getIdMapping(), null, null);
                // Bind the variable in the QueryGenerator
                keyExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getIdMapping());
                stmt.getQueryGenerator().bindVariable(varName, keyCmd, keyExpr.getSQLTable(), keyExpr.getJavaTypeMapping());
            } else {
                // Add restrict to key
                SQLExpression keyIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getKeyMapping());
                stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
            }
        } else {
            if (keyIsUnbound) {
                // Bind the variable in the QueryGenerator
                keyExpr = exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getKeyMapping());
                stmt.getQueryGenerator().bindVariable(varName, null, keyExpr.getSQLTable(), keyExpr.getJavaTypeMapping());
            } else {
                // Add restrict to key
                SQLExpression keyIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getKeyMapping());
                stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
            }
        }
    } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
        // Map formed in value table - add join to value table, then to key table
        AbstractClassMetaData valCmd = mmd.getMap().getValueClassMetaData(clr);
        DatastoreClass valTbl = storeMgr.getDatastoreClass(valCmd.getFullClassName(), clr);
        AbstractMemberMetaData valKeyMmd = valCmd.getMetaDataForMember(mmd.getKeyMetaData().getMappedBy());
        JavaTypeMapping ownerMapping = null;
        if (mmd.getMappedBy() != null) {
            ownerMapping = valTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = valTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        SQLTable valSqlTbl = stmt.join(joinType, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), valTbl, null, ownerMapping, null, null);
        if (keyCmd != null) {
            DatastoreClass keyTbl = storeMgr.getDatastoreClass(keyCmd.getFullClassName(), clr);
            SQLTable keySqlTbl = stmt.join(joinType, valSqlTbl, valTbl.getMemberMapping(valKeyMmd), keyTbl, keyAlias, keyTbl.getIdMapping(), null, null);
            if (keyIsUnbound) {
                // Bind the variable in the QueryGenerator
                keyExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getIdMapping());
                stmt.getQueryGenerator().bindVariable(varName, keyCmd, keyExpr.getSQLTable(), keyExpr.getJavaTypeMapping());
            } else {
                // Add restrict to key
                SQLExpression keyIdExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getIdMapping());
                stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
            }
        } else {
            if (keyIsUnbound) {
                // Bind the variable in the QueryGenerator
                keyExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getMemberMapping(valKeyMmd));
                stmt.getQueryGenerator().bindVariable(varName, null, keyExpr.getSQLTable(), keyExpr.getJavaTypeMapping());
            } else {
                // Add restrict to key
                SQLExpression keyIdExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getMemberMapping(valKeyMmd));
                stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
            }
        }
    } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
        // Map formed in key table - add join to key table
        DatastoreClass keyTbl = storeMgr.getDatastoreClass(keyCmd.getFullClassName(), clr);
        JavaTypeMapping ownerMapping = null;
        if (mmd.getMappedBy() != null) {
            ownerMapping = keyTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = keyTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        SQLTable keySqlTbl = stmt.join(joinType, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), keyTbl, keyAlias, ownerMapping, null, null);
        if (keyIsUnbound) {
            // Bind the variable in the QueryGenerator
            keyExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getIdMapping());
            stmt.getQueryGenerator().bindVariable(varName, keyCmd, keyExpr.getSQLTable(), keyExpr.getJavaTypeMapping());
        } else {
            // Add restrict to key
            SQLExpression keyIdExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getIdMapping());
            stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
        }
    }
    JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
    return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, true));
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) MapTable(org.datanucleus.store.rdbms.table.MapTable) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 82 with SQLExpressionFactory

use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory 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);
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) InExpression(org.datanucleus.store.rdbms.sql.expression.InExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) MapExpression(org.datanucleus.store.rdbms.sql.expression.MapExpression) TemporalExpression(org.datanucleus.store.rdbms.sql.expression.TemporalExpression) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) JoinType(org.datanucleus.store.rdbms.sql.SQLJoin.JoinType) EnumExpression(org.datanucleus.store.rdbms.sql.expression.EnumExpression) CharacterExpression(org.datanucleus.store.rdbms.sql.expression.CharacterExpression) MapLiteral(org.datanucleus.store.rdbms.sql.expression.MapLiteral) StringExpression(org.datanucleus.store.rdbms.sql.expression.StringExpression) MapValueLiteral(org.datanucleus.store.rdbms.sql.expression.MapLiteral.MapValueLiteral) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) Map(java.util.Map)

Example 83 with SQLExpressionFactory

use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory in project datanucleus-rdbms by datanucleus.

the class MapIsEmptyMethod 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", "MapExpression"));
    }
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    if (expr instanceof MapLiteral) {
        Map map = (Map) ((MapLiteral) expr).getValue();
        boolean isEmpty = (map == null || map.size() == 0);
        JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, false);
        return new BooleanLiteral(stmt, m, isEmpty ? Boolean.TRUE : Boolean.FALSE);
    }
    SQLExpression sizeExpr = exprFactory.invokeMethod(stmt, Map.class.getName(), "size", expr, args);
    JavaTypeMapping mapping = exprFactory.getMappingForType(Integer.class, true);
    SQLExpression zeroExpr = exprFactory.newLiteral(stmt, mapping, 0);
    return sizeExpr.eq(zeroExpr);
}
Also used : MapLiteral(org.datanucleus.store.rdbms.sql.expression.MapLiteral) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) BooleanLiteral(org.datanucleus.store.rdbms.sql.expression.BooleanLiteral) NucleusException(org.datanucleus.exceptions.NucleusException) Map(java.util.Map)

Example 84 with SQLExpressionFactory

use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory in project datanucleus-rdbms by datanucleus.

the class MapKeyMethod method getAsSubquery.

/**
 * Implementation of KEY(mapExpr) using a subquery on the table representing the map.
 * @param stmt SQLStatement
 * @param mapExpr The map expression
 * @return The value expression
 */
protected SQLExpression getAsSubquery(SQLStatement stmt, MapExpression mapExpr) {
    AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
    MapMetaData mapmd = mmd.getMap();
    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
    JavaTypeMapping ownerMapping = null;
    JavaTypeMapping keyMapping = null;
    Table mapTbl = null;
    if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
        // JoinTable
        mapTbl = storeMgr.getTable(mmd);
        ownerMapping = ((MapTable) mapTbl).getOwnerMapping();
        keyMapping = ((MapTable) mapTbl).getKeyMapping();
    } else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
        // ForeignKey from value table to key
        AbstractClassMetaData valCmd = mapmd.getValueClassMetaData(clr);
        mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
        if (mmd.getMappedBy() != null) {
            ownerMapping = mapTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        String keyFieldName = mmd.getKeyMetaData().getMappedBy();
        AbstractMemberMetaData valKeyMmd = valCmd.getMetaDataForMember(keyFieldName);
        keyMapping = mapTbl.getMemberMapping(valKeyMmd);
    } else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
        // ForeignKey from key table to value
        AbstractClassMetaData keyCmd = mapmd.getKeyClassMetaData(clr);
        mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getKeyType(), clr);
        if (mmd.getMappedBy() != null) {
            ownerMapping = mapTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        keyMapping = mapTbl.getIdMapping();
    } else {
        throw new NucleusException("Invalid map for " + mapExpr + " in get() call");
    }
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    SelectStatement subStmt = new SelectStatement(stmt, storeMgr, mapTbl, null, null);
    subStmt.setClassLoaderResolver(clr);
    SQLExpression keyExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), keyMapping);
    subStmt.select(keyExpr, null);
    // Link to primary statement
    SQLExpression elementOwnerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
    SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
    subStmt.whereAnd(elementOwnerExpr.eq(ownerIdExpr), true);
    SubqueryExpression subExpr = new SubqueryExpression(stmt, subStmt);
    subExpr.setJavaTypeMapping(keyMapping);
    return subExpr;
}
Also used : Table(org.datanucleus.store.rdbms.table.Table) MapTable(org.datanucleus.store.rdbms.table.MapTable) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) MapMetaData(org.datanucleus.metadata.MapMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) SubqueryExpression(org.datanucleus.store.rdbms.sql.expression.SubqueryExpression) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 85 with SQLExpressionFactory

use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory in project datanucleus-rdbms by datanucleus.

the class MapKeyMethod method getAsJoin.

/**
 * Implementation of KEY(mapExpr) using a join to the table representing the map, and returning an expression for the key.
 * @param mapExpr The map expression
 * @return The value expression
 */
protected SQLExpression getAsJoin(SQLStatement stmt, MapExpression mapExpr) {
    JavaTypeMapping m = mapExpr.getJavaTypeMapping();
    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    AbstractMemberMetaData mmd = m.getMemberMetaData();
    // Use the statement of the table for this Map expression, since it could be in an outer query
    stmt = mapExpr.getSQLTable().getSQLStatement();
    if (mmd != null) {
        MapMetaData mapmd = mmd.getMap();
        SQLTable mapSqlTbl = mapExpr.getSQLTable();
        // Set alias of "map" table from MapExpression in case it was defined in FROM clause
        String mapJoinAlias = mapExpr.getAliasForMapTable();
        if (mapJoinAlias == null) {
            mapJoinAlias = (mapExpr.getSQLTable().getAlias().toString() + "_" + mmd.getName()).toUpperCase();
        }
        if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
            // Add join to join table
            MapTable joinTbl = (MapTable) storeMgr.getTable(mmd);
            SQLTable joinSqlTbl = stmt.getTable(mapJoinAlias);
            if (joinSqlTbl == null) {
                joinSqlTbl = stmt.join(JoinType.INNER_JOIN, mapSqlTbl, mapSqlTbl.getTable().getIdMapping(), joinTbl, mapJoinAlias, joinTbl.getOwnerMapping(), null, null);
            }
            // Return key expression
            if (mapmd.getKeyClassMetaData(clr) != null && !mapmd.isEmbeddedKey()) {
                // Persistable key so join to its table (default to "{mapJoinAlias}_KEY")
                DatastoreClass keyTable = storeMgr.getDatastoreClass(mapmd.getKeyType(), clr);
                SQLTable keySqlTbl = stmt.getTable(mapJoinAlias + "_KEY");
                if (keySqlTbl == null) {
                    keySqlTbl = stmt.join(JoinType.INNER_JOIN, joinSqlTbl, joinTbl.getKeyMapping(), keyTable, mapJoinAlias + "_KEY", keyTable.getIdMapping(), null, null);
                }
                return exprFactory.newExpression(stmt, keySqlTbl, keyTable.getIdMapping());
            }
            return exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getKeyMapping());
        } else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
            // Key stored in value table, so join to value table
            DatastoreClass valTable = storeMgr.getDatastoreClass(mapmd.getValueType(), clr);
            AbstractClassMetaData valCmd = mmd.getMap().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, mapSqlTbl, mapSqlTbl.getTable().getIdMapping(), valTable, mapJoinAlias, mapTblOwnerMapping, null, null);
            // Return key expression
            AbstractMemberMetaData valKeyMmd = mapmd.getValueClassMetaData(clr).getMetaDataForMember(mmd.getKeyMetaData().getMappedBy());
            JavaTypeMapping keyMapping = valTable.getMemberMapping(valKeyMmd);
            return exprFactory.newExpression(stmt, valSqlTbl, keyMapping);
        } else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
            // Value stored in key table, so join to key table
            DatastoreClass keyTable = storeMgr.getDatastoreClass(mapmd.getKeyType(), clr);
            AbstractClassMetaData keyCmd = mmd.getMap().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, mapSqlTbl, mapSqlTbl.getTable().getIdMapping(), keyTable, mapJoinAlias, mapTblOwnerMapping, null, null);
            // Return key expression
            return exprFactory.newExpression(stmt, keySqlTbl, keyTable.getIdMapping());
        }
    }
    throw new NucleusException("KEY(map) for the filter is not supported for " + mapExpr + ". Why not contribute support for it?");
}
Also used : MapTable(org.datanucleus.store.rdbms.table.MapTable) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) MapMetaData(org.datanucleus.metadata.MapMetaData) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager)

Aggregations

SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)111 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)98 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)81 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)49 NucleusException (org.datanucleus.exceptions.NucleusException)42 NumericExpression (org.datanucleus.store.rdbms.sql.expression.NumericExpression)40 ArrayList (java.util.ArrayList)39 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)38 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)35 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)31 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)30 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)28 StringExpression (org.datanucleus.store.rdbms.sql.expression.StringExpression)23 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)22 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)20 IntegerLiteral (org.datanucleus.store.rdbms.sql.expression.IntegerLiteral)20 NullLiteral (org.datanucleus.store.rdbms.sql.expression.NullLiteral)19 SQLLiteral (org.datanucleus.store.rdbms.sql.expression.SQLLiteral)17 BigInteger (java.math.BigInteger)16 StringLiteral (org.datanucleus.store.rdbms.sql.expression.StringLiteral)16