Search in sources :

Example 36 with SelectStatement

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

the class MapEntrySetStore method getSQLStatementForIterator.

/**
 * Method to generate an SQLStatement for iterating through entries of the map.
 * Creates a statement that selects the table holding the map definition (key/value mappings).
 * Adds a restriction on the ownerMapping of the containerTable so we can restrict to the owner object.
 * Adds a restriction on the keyMapping not being null.
 * <pre>
 * SELECT KEY, VALUE FROM MAP_TABLE WHERE OWNER_ID=? AND KEY IS NOT NULL
 * </pre>
 * @param ownerOP ObjectProvider for the owner object
 * @return The SQLStatement
 */
protected SQLStatement getSQLStatementForIterator(ObjectProvider ownerOP) {
    SelectStatement sqlStmt = new SelectStatement(storeMgr, mapTable, null, null);
    sqlStmt.setClassLoaderResolver(clr);
    // Select the key mapping
    // TODO If key is persistable and has inheritance also select a discriminator to get the type
    SQLTable entrySqlTblForKey = sqlStmt.getPrimaryTable();
    if (keyMapping.getTable() != mapTable) {
        entrySqlTblForKey = sqlStmt.getTableForDatastoreContainer(keyMapping.getTable());
        if (entrySqlTblForKey == null) {
            // Add join to key table
            entrySqlTblForKey = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), sqlStmt.getPrimaryTable().getTable().getIdMapping(), keyMapping.getTable(), null, keyMapping.getTable().getIdMapping(), null, null, true);
        }
    }
    iteratorKeyResultCols = sqlStmt.select(entrySqlTblForKey, keyMapping, null);
    // Select the value mapping
    // TODO If value is persistable and has inheritance also select a discriminator to get the type
    SQLTable entrySqlTblForVal = sqlStmt.getPrimaryTable();
    if (valueMapping.getTable() != mapTable) {
        entrySqlTblForVal = sqlStmt.getTableForDatastoreContainer(valueMapping.getTable());
        if (entrySqlTblForVal == null) {
            // Add join to key table
            entrySqlTblForVal = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), sqlStmt.getPrimaryTable().getTable().getIdMapping(), valueMapping.getTable(), null, valueMapping.getTable().getIdMapping(), null, null, true);
        }
    }
    iteratorValueResultCols = sqlStmt.select(entrySqlTblForVal, valueMapping, null);
    // Apply condition on owner field to filter by owner
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), ownerMapping);
    SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
    SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
    sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
    // Apply condition that key is not null
    SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
    SQLExpression nullExpr = exprFactory.newLiteral(sqlStmt, null, null);
    sqlStmt.whereAnd(keyExpr.ne(nullExpr), true);
    // Input parameter(s) - the owner
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
                paramPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(paramPositions);
        }
    } else {
        int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
            paramPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(paramPositions);
    }
    iteratorMappingParams = new StatementParameterMapping();
    iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
    return sqlStmt;
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex)

Example 37 with SelectStatement

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

the class MapKeySetStore method getSQLStatementForIterator.

/**
 * Method to generate an SQLStatement for iterating through keys of the map.
 * Populates the iteratorMappingDef and iteratorMappingParams.
 * Creates a statement that selects the key table(s), and adds any necessary join to the containerTable
 * if that is not the key table. If the key is embedded then selects the table it is embedded in.
 * Adds a restriction on the ownerMapping of the containerTable so we can restrict to the owner object.
 * @param ownerOP ObjectProvider for the owner object
 * @return The SQLStatement
 */
protected SelectStatement getSQLStatementForIterator(ObjectProvider ownerOP) {
    SelectStatement sqlStmt = null;
    ExecutionContext ec = ownerOP.getExecutionContext();
    final ClassLoaderResolver clr = ec.getClassLoaderResolver();
    final Class keyCls = clr.classForName(elementType);
    SQLTable containerSqlTbl = null;
    MapType mapType = getOwnerMemberMetaData().getMap().getMapType();
    FetchPlan fp = ec.getFetchPlan();
    if (elementCmd != null && elementCmd.getDiscriminatorStrategyForTable() != null && elementCmd.getDiscriminatorStrategyForTable() != DiscriminatorStrategy.NONE) {
        // Map<PC, ?> where key has discriminator
        if (ClassUtils.isReferenceType(keyCls)) {
            // Take the metadata for the first implementation of the reference type
            String[] clsNames = storeMgr.getNucleusContext().getMetaDataManager().getClassesImplementingInterface(elementType, clr);
            Class[] cls = new Class[clsNames.length];
            for (int j = 0; j < clsNames.length; j++) {
                cls[j] = clr.classForName(clsNames[j]);
            }
            sqlStmt = new DiscriminatorStatementGenerator(storeMgr, clr, cls, true, null, null).getStatement(ec);
        } else {
            sqlStmt = new DiscriminatorStatementGenerator(storeMgr, clr, clr.classForName(elementInfo[0].getClassName()), true, null, null).getStatement(ec);
        }
        containerSqlTbl = sqlStmt.getPrimaryTable();
        iterateUsingDiscriminator = true;
        if (mapType == MapType.MAP_TYPE_VALUE_IN_KEY) {
            // Select key fields
            containerSqlTbl = sqlStmt.getPrimaryTable();
            iteratorMappingDef = new StatementClassMapping();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        } else {
            // MAP_TYPE_KEY_IN_VALUE, MAP_TYPE_JOIN
            // Join to join table and select key fields
            JavaTypeMapping keyIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
            containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), keyIdMapping, containerTable, null, elementMapping, null, null, true);
            iteratorMappingDef = new StatementClassMapping();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        }
    } else {
        if (mapType == MapType.MAP_TYPE_VALUE_IN_KEY) {
            // Select of key in key table (allow union of possible key types)
            iteratorMappingDef = new StatementClassMapping();
            UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, keyCls, true, null, null);
            stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
            iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
            sqlStmt = stmtGen.getStatement(ec);
            containerSqlTbl = sqlStmt.getPrimaryTable();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        } else {
            // MAP_TYPE_KEY_IN_VALUE, MAP_TYPE_JOIN
            if (elementCmd != null) {
                // Select of key table, joining to join table
                iteratorMappingDef = new StatementClassMapping();
                UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, keyCls, true, null, null);
                stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
                iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
                sqlStmt = stmtGen.getStatement(ec);
                JavaTypeMapping keyIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
                containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), keyIdMapping, containerTable, null, elementMapping, null, null, true);
                SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
            } else {
                // Select of key in join table
                sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
                sqlStmt.setClassLoaderResolver(clr);
                containerSqlTbl = sqlStmt.getPrimaryTable();
                SQLTable elemSqlTblForKey = containerSqlTbl;
                if (elementMapping.getTable() != containerSqlTbl.getTable()) {
                    elemSqlTblForKey = sqlStmt.getTableForDatastoreContainer(elementMapping.getTable());
                    if (elemSqlTblForKey == null) {
                        // Add join to element table
                        elemSqlTblForKey = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), sqlStmt.getPrimaryTable().getTable().getIdMapping(), elementMapping.getTable(), null, elementMapping.getTable().getIdMapping(), null, null, true);
                    }
                }
                sqlStmt.select(elemSqlTblForKey, elementMapping, null);
            }
        }
    }
    // Apply condition on owner field to filter by owner
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, containerSqlTbl, ownerMapping);
    SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
    SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
    sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
    // Input parameter(s) - the owner
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
                paramPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(paramPositions);
        }
    } else {
        int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
            paramPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(paramPositions);
    }
    iteratorMappingParams = new StatementParameterMapping();
    iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
    return sqlStmt;
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) 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) FetchPlan(org.datanucleus.FetchPlan) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) MapType(org.datanucleus.metadata.MapMetaData.MapType) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) UnionStatementGenerator(org.datanucleus.store.rdbms.sql.UnionStatementGenerator) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) ExecutionContext(org.datanucleus.ExecutionContext) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) DiscriminatorStatementGenerator(org.datanucleus.store.rdbms.sql.DiscriminatorStatementGenerator) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 38 with SelectStatement

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

the class MapValueCollectionStore method getSQLStatementForIterator.

/**
 * Method to generate an SQLStatement for iterating through values of the map.
 * Populates the iteratorMappingDef and iteratorMappingParams.
 * Creates a statement that selects the value table(s), and adds any necessary join to the containerTable
 * if that is not the value table. If the value is embedded then selects the table it is embedded in.
 * Adds a restriction on the ownerMapping of the containerTable so we can restrict to the owner object.
 * @param ownerOP ObjectProvider for the owner object
 * @return The SQLStatement
 */
protected SelectStatement getSQLStatementForIterator(ObjectProvider ownerOP) {
    SelectStatement sqlStmt = null;
    ExecutionContext ec = ownerOP.getExecutionContext();
    final ClassLoaderResolver clr = ec.getClassLoaderResolver();
    final Class valueCls = clr.classForName(elementType);
    SQLTable containerSqlTbl = null;
    MapType mapType = getOwnerMemberMetaData().getMap().getMapType();
    FetchPlan fp = ec.getFetchPlan();
    if (elementCmd != null && elementCmd.getDiscriminatorStrategyForTable() != null && elementCmd.getDiscriminatorStrategyForTable() != DiscriminatorStrategy.NONE) {
        // Map<?, PC> where value has discriminator
        if (ClassUtils.isReferenceType(valueCls)) {
            // Take the metadata for the first implementation of the reference type
            String[] clsNames = storeMgr.getNucleusContext().getMetaDataManager().getClassesImplementingInterface(elementType, clr);
            Class[] cls = new Class[clsNames.length];
            for (int j = 0; j < clsNames.length; j++) {
                cls[j] = clr.classForName(clsNames[j]);
            }
            SelectStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, cls, true, null, null);
            sqlStmt = stmtGen.getStatement(ec);
        } else {
            SelectStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, valueCls, true, null, null);
            sqlStmt = stmtGen.getStatement(ec);
        }
        iterateUsingDiscriminator = true;
        if (mapType == MapType.MAP_TYPE_VALUE_IN_KEY) {
            // Join to key table and select value fields
            JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
            containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
            iteratorMappingDef = new StatementClassMapping();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        } else if (mapType == MapType.MAP_TYPE_KEY_IN_VALUE) {
            // Select value fields
            containerSqlTbl = sqlStmt.getPrimaryTable();
            iteratorMappingDef = new StatementClassMapping();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        } else {
            // Join to join table and select value fields
            JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
            containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
            iteratorMappingDef = new StatementClassMapping();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        }
    } else {
        if (mapType == MapType.MAP_TYPE_VALUE_IN_KEY) {
            if (elementCmd != null) {
                // TODO Allow for null value [change to select the key table and left outer join to the key]
                // Select of value table, joining to key table
                iteratorMappingDef = new StatementClassMapping();
                UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null);
                stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
                iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
                sqlStmt = stmtGen.getStatement(ec);
                JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
                containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
                SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
            } else {
                // Select of value in key table
                sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
                sqlStmt.setClassLoaderResolver(clr);
                containerSqlTbl = sqlStmt.getPrimaryTable();
                SQLTable elemSqlTblForValue = containerSqlTbl;
                if (elementMapping.getTable() != containerSqlTbl.getTable()) {
                    elemSqlTblForValue = sqlStmt.getTableForDatastoreContainer(elementMapping.getTable());
                    if (elemSqlTblForValue == null) {
                        // Add join to key table holding value
                        elemSqlTblForValue = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), sqlStmt.getPrimaryTable().getTable().getIdMapping(), elementMapping.getTable(), null, elementMapping.getTable().getIdMapping(), null, null, true);
                    }
                }
                sqlStmt.select(elemSqlTblForValue, elementMapping, null);
            }
        } else if (mapType == MapType.MAP_TYPE_KEY_IN_VALUE) {
            // Select of value in value table (allow union of possible value types)
            iteratorMappingDef = new StatementClassMapping();
            UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null);
            stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
            iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
            sqlStmt = stmtGen.getStatement(ec);
            containerSqlTbl = sqlStmt.getPrimaryTable();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        } else {
            if (elementCmd != null) {
                // TODO Allow for null value [change to select the join table and left outer join to the key]
                // Select of value table, joining to key table
                iteratorMappingDef = new StatementClassMapping();
                UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null);
                stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
                iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
                sqlStmt = stmtGen.getStatement(ec);
                JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
                containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
                SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
            } else {
                // Select of value in join table
                sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
                containerSqlTbl = sqlStmt.getPrimaryTable();
                sqlStmt.select(sqlStmt.getPrimaryTable(), elementMapping, null);
            }
        }
    }
    // Apply condition on owner field to filter by owner
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, containerSqlTbl, ownerMapping);
    SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
    SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
    sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
    // Input parameter(s) - the owner
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
                paramPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(paramPositions);
        }
    } else {
        int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
            paramPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(paramPositions);
    }
    iteratorMappingParams = new StatementParameterMapping();
    iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
    return sqlStmt;
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) 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) FetchPlan(org.datanucleus.FetchPlan) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) MapType(org.datanucleus.metadata.MapMetaData.MapType) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) UnionStatementGenerator(org.datanucleus.store.rdbms.sql.UnionStatementGenerator) SelectStatementGenerator(org.datanucleus.store.rdbms.sql.SelectStatementGenerator) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) ExecutionContext(org.datanucleus.ExecutionContext) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) DiscriminatorStatementGenerator(org.datanucleus.store.rdbms.sql.DiscriminatorStatementGenerator) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 39 with SelectStatement

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

the class LocateBulkRequest method getStatement.

protected String getStatement(DatastoreClass table, ObjectProvider[] ops, boolean lock) {
    RDBMSStoreManager storeMgr = table.getStoreManager();
    ClassLoaderResolver clr = storeMgr.getNucleusContext().getClassLoaderResolver(null);
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    cmd = storeMgr.getMetaDataManager().getMetaDataForClass(table.getType(), clr);
    ExecutionContext ec = ops[0].getExecutionContext();
    SelectStatement sqlStatement = new SelectStatement(storeMgr, table, null, null);
    // SELECT fields we require
    resultMapping = new StatementClassMapping();
    // a). PK fields
    if (table.getIdentityType() == IdentityType.DATASTORE) {
        JavaTypeMapping datastoreIdMapping = table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
        SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), datastoreIdMapping);
        int[] cols = sqlStatement.select(expr, null);
        StatementMappingIndex datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
        datastoreIdx.setColumnPositions(cols);
        resultMapping.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
    } else if (table.getIdentityType() == IdentityType.APPLICATION) {
        int[] pkNums = cmd.getPKMemberPositions();
        for (int i = 0; i < pkNums.length; i++) {
            AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[i]);
            JavaTypeMapping pkMapping = table.getMemberMappingInDatastoreClass(mmd);
            if (pkMapping == null) {
                pkMapping = table.getMemberMapping(mmd);
            }
            SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), pkMapping);
            int[] cols = sqlStatement.select(expr, null);
            StatementMappingIndex pkIdx = new StatementMappingIndex(pkMapping);
            pkIdx.setColumnPositions(cols);
            resultMapping.addMappingForMember(mmd.getAbsoluteFieldNumber(), pkIdx);
        }
    } else {
        throw new NucleusUserException("Cannot locate objects using nondurable identity");
    }
    JavaTypeMapping verMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, false);
    if (verMapping != null) {
        VersionMetaData currentVermd = table.getVersionMetaData();
        if (currentVermd != null && currentVermd.getFieldName() == null) {
            // Surrogate version column
            SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), verMapping);
            int[] cols = sqlStatement.select(expr, null);
            StatementMappingIndex mapIdx = new StatementMappingIndex(verMapping);
            mapIdx.setColumnPositions(cols);
            resultMapping.addMappingForMember(SurrogateColumnType.VERSION.getFieldNumber(), mapIdx);
        }
    }
    int[] nonPkFieldNums = cmd.getNonPKMemberPositions();
    if (nonPkFieldNums != null) {
        for (int i = 0; i < nonPkFieldNums.length; i++) {
            AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(nonPkFieldNums[i]);
            JavaTypeMapping mapping = table.getMemberMapping(mmd);
            if (mapping != null && mapping.includeInFetchStatement()) {
                if (mapping instanceof PersistableMapping) {
                    // Ignore 1-1/N-1 for now
                    continue;
                }
                SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), mapping);
                int[] cols = sqlStatement.select(expr, null);
                StatementMappingIndex mapIdx = new StatementMappingIndex(mapping);
                mapIdx.setColumnPositions(cols);
                resultMapping.addMappingForMember(mmd.getAbsoluteFieldNumber(), mapIdx);
            }
        }
    }
    JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
    if (multitenancyMapping != null) {
        // Add WHERE clause restricting to tenant
        SQLExpression tenantExpr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), multitenancyMapping);
        SQLExpression tenantVal = exprFactory.newLiteral(sqlStatement, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, cmd));
        sqlStatement.whereAnd(tenantExpr.eq(tenantVal), true);
    }
    JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
    if (softDeleteMapping != null) {
        // Add WHERE clause restricting to soft-delete unset
        SQLExpression softDeleteExpr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), softDeleteMapping);
        SQLExpression softDeleteVal = exprFactory.newLiteral(sqlStatement, softDeleteMapping, Boolean.FALSE);
        sqlStatement.whereAnd(softDeleteExpr.eq(softDeleteVal), true);
    }
    // Add WHERE clause restricting to the identities of the objects
    mappingDefinitions = new StatementClassMapping[ops.length];
    int inputParamNum = 1;
    for (int i = 0; i < ops.length; i++) {
        mappingDefinitions[i] = new StatementClassMapping();
        if (table.getIdentityType() == IdentityType.DATASTORE) {
            // Datastore identity value for input
            JavaTypeMapping datastoreIdMapping = table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
            SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), datastoreIdMapping);
            SQLExpression val = exprFactory.newLiteralParameter(sqlStatement, datastoreIdMapping, null, "ID");
            sqlStatement.whereOr(expr.eq(val), true);
            StatementMappingIndex datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
            mappingDefinitions[i].addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
            datastoreIdx.addParameterOccurrence(new int[] { inputParamNum++ });
        } else if (table.getIdentityType() == IdentityType.APPLICATION) {
            // Application identity value(s) for input
            BooleanExpression pkExpr = null;
            int[] pkNums = cmd.getPKMemberPositions();
            for (int j = 0; j < pkNums.length; j++) {
                AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[j]);
                JavaTypeMapping pkMapping = table.getMemberMappingInDatastoreClass(mmd);
                if (pkMapping == null) {
                    pkMapping = table.getMemberMapping(mmd);
                }
                SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), pkMapping);
                SQLExpression val = exprFactory.newLiteralParameter(sqlStatement, pkMapping, null, "PK" + j);
                BooleanExpression fieldEqExpr = expr.eq(val);
                if (pkExpr == null) {
                    pkExpr = fieldEqExpr;
                } else {
                    pkExpr = pkExpr.and(fieldEqExpr);
                }
                StatementMappingIndex pkIdx = new StatementMappingIndex(pkMapping);
                mappingDefinitions[i].addMappingForMember(mmd.getAbsoluteFieldNumber(), pkIdx);
                int[] inputParams = new int[pkMapping.getNumberOfDatastoreMappings()];
                for (int k = 0; k < pkMapping.getNumberOfDatastoreMappings(); k++) {
                    inputParams[k] = inputParamNum++;
                }
                pkIdx.addParameterOccurrence(inputParams);
            }
            if (pkExpr == null) {
                throw new NucleusException("Unable to generate PK expression for WHERE clause of locate statement");
            }
            pkExpr = (BooleanExpression) pkExpr.encloseInParentheses();
            sqlStatement.whereOr(pkExpr, true);
        }
    }
    // Generate the appropriate JDBC statement allowing for locking
    if (lock) {
        sqlStatement.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, Boolean.TRUE);
        return sqlStatement.getSQLText().toSQL();
    }
    return sqlStatement.getSQLText().toSQL();
}
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) VersionMetaData(org.datanucleus.metadata.VersionMetaData) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) ExecutionContext(org.datanucleus.ExecutionContext) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 40 with SelectStatement

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

the class JoinMapStore method getSQLStatementForGet.

/**
 * Method to return an SQLStatement for retrieving the value for a key.
 * Selects the join table and optionally joins to the value table if it has its own table.
 * @param ownerOP ObjectProvider for the owning object
 * @return The SQLStatement
 */
protected SelectStatement getSQLStatementForGet(ObjectProvider ownerOP) {
    SelectStatement sqlStmt = null;
    ExecutionContext ec = ownerOP.getExecutionContext();
    final ClassLoaderResolver clr = ownerOP.getExecutionContext().getClassLoaderResolver();
    Class valueCls = clr.classForName(this.valueType);
    if (valuesAreEmbedded || valuesAreSerialised) {
        // Value is stored in join table
        sqlStmt = new SelectStatement(storeMgr, mapTable, null, null);
        sqlStmt.setClassLoaderResolver(clr);
        sqlStmt.select(sqlStmt.getPrimaryTable(), valueMapping, null);
    } else {
        // Value is stored in own table
        getMappingDef = new StatementClassMapping();
        if (!valueCmd.getFullClassName().equals(valueCls.getName())) {
            valueCls = clr.classForName(valueCmd.getFullClassName());
        }
        UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null, mapTable, null, valueMapping);
        stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
        getMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
        sqlStmt = stmtGen.getStatement(ec);
        // Select the value field(s)
        SQLTable valueSqlTbl = sqlStmt.getTable(valueTable, sqlStmt.getPrimaryTable().getGroupName());
        if (valueSqlTbl == null) {
            // Root value candidate has no table, so try to find a value candidate with a table that exists in this statement
            Collection<String> valueSubclassNames = storeMgr.getSubClassesForClass(valueType, true, clr);
            if (valueSubclassNames != null && !valueSubclassNames.isEmpty()) {
                for (String valueSubclassName : valueSubclassNames) {
                    DatastoreClass valueTbl = storeMgr.getDatastoreClass(valueSubclassName, clr);
                    if (valueTbl != null) {
                        valueSqlTbl = sqlStmt.getTable(valueTbl, sqlStmt.getPrimaryTable().getGroupName());
                        if (valueSqlTbl != null) {
                            break;
                        }
                    }
                }
            }
        }
        SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, getMappingDef, ec.getFetchPlan(), valueSqlTbl, valueCmd, ec.getFetchPlan().getMaxFetchDepth());
    }
    // Apply condition on owner field to filter by owner
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), ownerMapping);
    SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
    SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
    sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
    // Apply condition on key
    if (keyMapping instanceof SerialisedMapping) {
        // if the keyMapping contains a BLOB column (or any other column not supported by the database
        // as primary key), uses like instead of the operator OP_EQ (=)
        // in future do not check if the keyMapping is of ObjectMapping, but use the database
        // adapter to check the data types not supported as primary key
        // if object mapping (BLOB) use like
        SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
        SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
        sqlStmt.whereAnd(new org.datanucleus.store.rdbms.sql.expression.BooleanExpression(keyExpr, Expression.OP_LIKE, keyVal), true);
    } else {
        SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
        SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
        sqlStmt.whereAnd(keyExpr.eq(keyVal), true);
    }
    // Input parameter(s) - owner, key
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    StatementMappingIndex keyIdx = new StatementMappingIndex(keyMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < ownerPositions.length; k++) {
                ownerPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(ownerPositions);
            int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < keyPositions.length; k++) {
                keyPositions[k] = inputParamNum++;
            }
            keyIdx.addParameterOccurrence(keyPositions);
        }
    } else {
        int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < ownerPositions.length; k++) {
            ownerPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(ownerPositions);
        int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < keyPositions.length; k++) {
            keyPositions[k] = inputParamNum++;
        }
        keyIdx.addParameterOccurrence(keyPositions);
    }
    getMappingParams = new StatementParameterMapping();
    getMappingParams.addMappingForParameter("owner", ownerIdx);
    getMappingParams.addMappingForParameter("key", keyIdx);
    return sqlStmt;
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) UnionStatementGenerator(org.datanucleus.store.rdbms.sql.UnionStatementGenerator) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) ExecutionContext(org.datanucleus.ExecutionContext) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) SerialisedMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedMapping) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Aggregations

SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)49 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)36 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)31 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)30 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)27 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)25 NucleusException (org.datanucleus.exceptions.NucleusException)25 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)24 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)19 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)19 StatementClassMapping (org.datanucleus.store.rdbms.query.StatementClassMapping)19 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)16 ExecutionContext (org.datanucleus.ExecutionContext)14 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)14 UnionStatementGenerator (org.datanucleus.store.rdbms.sql.UnionStatementGenerator)12 DiscriminatorStatementGenerator (org.datanucleus.store.rdbms.sql.DiscriminatorStatementGenerator)11 PreparedStatement (java.sql.PreparedStatement)10 ResultSet (java.sql.ResultSet)10 SQLException (java.sql.SQLException)10 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)10