Search in sources :

Example 1 with BaseContainerStore

use of org.datanucleus.store.rdbms.scostore.BaseContainerStore in project datanucleus-rdbms by datanucleus.

the class BulkFetchExistsHandler method getStatementToBulkFetchField.

/**
 * Convenience method to generate a bulk-fetch statement for the specified multi-valued field of the owning query.
 * @param candidateCmd Metadata for the candidate
 * @param parameters Parameters for the query
 * @param mmd Metadata for the multi-valued field
 * @param datastoreCompilation The datastore compilation of the query
 * @param mapperOptions Any options for the query to SQL mapper
 * @return The bulk-fetch statement for retrieving this multi-valued field.
 */
public IteratorStatement getStatementToBulkFetchField(AbstractClassMetaData candidateCmd, AbstractMemberMetaData mmd, Query query, Map parameters, RDBMSQueryCompilation datastoreCompilation, Set<String> mapperOptions) {
    IteratorStatement iterStmt = null;
    ExecutionContext ec = query.getExecutionContext();
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    RDBMSStoreManager storeMgr = (RDBMSStoreManager) query.getStoreManager();
    Store backingStore = storeMgr.getBackingStoreForField(clr, mmd, null);
    if (backingStore instanceof JoinSetStore || backingStore instanceof JoinListStore || backingStore instanceof JoinArrayStore) {
        // Set/List/array using join-table : Generate an iterator query of the form
        if (backingStore instanceof JoinSetStore) {
            iterStmt = ((JoinSetStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false);
        } else if (backingStore instanceof JoinListStore) {
            iterStmt = ((JoinListStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false, -1, -1);
        } else if (backingStore instanceof JoinArrayStore) {
            iterStmt = ((JoinArrayStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false);
        } else {
            throw new NucleusUserException("We do not support BulkFetch using EXISTS for backingStore = " + backingStore);
        }
        // SELECT ELEM_TBL.COL1, ELEM_TBL.COL2, ... FROM JOIN_TBL INNER_JOIN ELEM_TBL WHERE JOIN_TBL.ELEMENT_ID = ELEM_TBL.ID
        // AND EXISTS (SELECT OWNER_TBL.ID FROM OWNER_TBL WHERE (queryWhereClause) AND JOIN_TBL.OWNER_ID = OWNER_TBL.ID)
        SelectStatement sqlStmt = iterStmt.getSelectStatement();
        JoinTable joinTbl = (JoinTable) sqlStmt.getPrimaryTable().getTable();
        JavaTypeMapping joinOwnerMapping = joinTbl.getOwnerMapping();
        // Generate the EXISTS subquery (based on the JDOQL/JPQL query)
        SelectStatement existsStmt = RDBMSQueryUtils.getStatementForCandidates(storeMgr, sqlStmt, candidateCmd, datastoreCompilation.getResultDefinitionForClass(), ec, query.getCandidateClass(), query.isSubclasses(), query.getResult(), null, null, null);
        Set<String> options = new HashSet<>();
        if (mapperOptions != null) {
            options.addAll(mapperOptions);
        }
        options.add(QueryToSQLMapper.OPTION_SELECT_CANDIDATE_ID_ONLY);
        QueryToSQLMapper sqlMapper = new QueryToSQLMapper(existsStmt, query.getCompilation(), parameters, null, null, candidateCmd, query.isSubclasses(), query.getFetchPlan(), ec, query.getParsedImports(), options, query.getExtensions());
        sqlMapper.compile();
        // Add EXISTS clause on iterator statement so we can restrict to just the owners in this query
        // ORDER BY in EXISTS is forbidden by some RDBMS
        existsStmt.setOrdering(null, null);
        BooleanExpression existsExpr = new BooleanSubqueryExpression(sqlStmt, "EXISTS", existsStmt);
        sqlStmt.whereAnd(existsExpr, true);
        // Join to outer statement so we restrict to collection elements for the query candidates
        SQLExpression joinTblOwnerExpr = sqlStmt.getRDBMSManager().getSQLExpressionFactory().newExpression(sqlStmt, sqlStmt.getPrimaryTable(), joinOwnerMapping);
        SQLExpression existsOwnerExpr = sqlStmt.getRDBMSManager().getSQLExpressionFactory().newExpression(existsStmt, existsStmt.getPrimaryTable(), existsStmt.getPrimaryTable().getTable().getIdMapping());
        existsStmt.whereAnd(joinTblOwnerExpr.eq(existsOwnerExpr), true);
        // Select the owner candidate so we can separate the collection elements out to their owner
        int[] ownerColIndexes = sqlStmt.select(joinTblOwnerExpr, null);
        StatementMappingIndex ownerMapIdx = new StatementMappingIndex(existsStmt.getPrimaryTable().getTable().getIdMapping());
        ownerMapIdx.setColumnPositions(ownerColIndexes);
        iterStmt.setOwnerMapIndex(ownerMapIdx);
    } else if (backingStore instanceof FKSetStore || backingStore instanceof FKListStore || backingStore instanceof FKArrayStore) {
        if (backingStore instanceof FKSetStore) {
            iterStmt = ((FKSetStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false);
        } else if (backingStore instanceof FKListStore) {
            iterStmt = ((FKListStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false, -1, -1);
        } else if (backingStore instanceof FKArrayStore) {
            iterStmt = ((FKArrayStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false);
        } else {
            throw new NucleusUserException("We do not support BulkFetch using EXISTS for backingStore = " + backingStore);
        }
        // Set/List/array using foreign-key : Generate an iterator query of the form
        // SELECT ELEM_TBL.COL1, ELEM_TBL.COL2, ... FROM ELEM_TBL
        // WHERE EXISTS (SELECT OWNER_TBL.ID FROM OWNER_TBL WHERE (queryWhereClause) AND ELEM_TBL.OWNER_ID = OWNER_TBL.ID)
        SelectStatement sqlStmt = iterStmt.getSelectStatement();
        // Generate the EXISTS subquery (based on the JDOQL/JPQL query)
        SelectStatement existsStmt = RDBMSQueryUtils.getStatementForCandidates(storeMgr, sqlStmt, candidateCmd, datastoreCompilation.getResultDefinitionForClass(), ec, query.getCandidateClass(), query.isSubclasses(), query.getResult(), null, null, null);
        Set<String> options = new HashSet<>();
        if (mapperOptions != null) {
            options.addAll(mapperOptions);
        }
        options.add(QueryToSQLMapper.OPTION_SELECT_CANDIDATE_ID_ONLY);
        QueryToSQLMapper sqlMapper = new QueryToSQLMapper(existsStmt, query.getCompilation(), parameters, null, null, candidateCmd, query.isSubclasses(), query.getFetchPlan(), ec, query.getParsedImports(), options, query.getExtensions());
        sqlMapper.compile();
        // Add EXISTS clause on iterator statement so we can restrict to just the owners in this query
        // ORDER BY in EXISTS is forbidden by some RDBMS
        existsStmt.setOrdering(null, null);
        BooleanExpression existsExpr = new BooleanSubqueryExpression(sqlStmt, "EXISTS", existsStmt);
        sqlStmt.whereAnd(existsExpr, true);
        // Join to outer statement so we restrict to collection elements for the query candidates
        SQLExpression elemTblOwnerExpr = sqlStmt.getRDBMSManager().getSQLExpressionFactory().newExpression(sqlStmt, sqlStmt.getPrimaryTable(), ((BaseContainerStore) backingStore).getOwnerMapping());
        SQLExpression existsOwnerExpr = sqlStmt.getRDBMSManager().getSQLExpressionFactory().newExpression(existsStmt, existsStmt.getPrimaryTable(), existsStmt.getPrimaryTable().getTable().getIdMapping());
        existsStmt.whereAnd(elemTblOwnerExpr.eq(existsOwnerExpr), true);
        // Select the owner candidate so we can separate the collection elements out to their owner
        int[] ownerColIndexes = sqlStmt.select(elemTblOwnerExpr, null);
        StatementMappingIndex ownerMapIdx = new StatementMappingIndex(existsStmt.getPrimaryTable().getTable().getIdMapping());
        ownerMapIdx.setColumnPositions(ownerColIndexes);
        iterStmt.setOwnerMapIndex(ownerMapIdx);
    }
    return iterStmt;
}
Also used : JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) HashSet(java.util.HashSet) Set(java.util.Set) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) IteratorStatement(org.datanucleus.store.rdbms.scostore.IteratorStatement) BaseContainerStore(org.datanucleus.store.rdbms.scostore.BaseContainerStore) JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) Store(org.datanucleus.store.types.scostore.Store) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) BaseContainerStore(org.datanucleus.store.rdbms.scostore.BaseContainerStore) HashSet(java.util.HashSet) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) ExecutionContext(org.datanucleus.ExecutionContext) BooleanSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) JoinTable(org.datanucleus.store.rdbms.table.JoinTable)

Aggregations

HashSet (java.util.HashSet)1 Set (java.util.Set)1 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)1 ExecutionContext (org.datanucleus.ExecutionContext)1 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)1 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)1 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)1 BaseContainerStore (org.datanucleus.store.rdbms.scostore.BaseContainerStore)1 FKArrayStore (org.datanucleus.store.rdbms.scostore.FKArrayStore)1 FKListStore (org.datanucleus.store.rdbms.scostore.FKListStore)1 FKSetStore (org.datanucleus.store.rdbms.scostore.FKSetStore)1 IteratorStatement (org.datanucleus.store.rdbms.scostore.IteratorStatement)1 JoinArrayStore (org.datanucleus.store.rdbms.scostore.JoinArrayStore)1 JoinListStore (org.datanucleus.store.rdbms.scostore.JoinListStore)1 JoinSetStore (org.datanucleus.store.rdbms.scostore.JoinSetStore)1 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)1 BooleanExpression (org.datanucleus.store.rdbms.sql.expression.BooleanExpression)1 BooleanSubqueryExpression (org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression)1 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)1 JoinTable (org.datanucleus.store.rdbms.table.JoinTable)1