Search in sources :

Example 61 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method getInvokedSqlExpressionForInvokeExpression.

protected SQLExpression getInvokedSqlExpressionForInvokeExpression(InvokeExpression expr) {
    Expression invokedExpr = expr.getLeft();
    SQLExpression invokedSqlExpr = null;
    if (invokedExpr == null) {
    // Static method
    } else if (invokedExpr instanceof PrimaryExpression) {
        processPrimaryExpression((PrimaryExpression) invokedExpr);
        invokedSqlExpr = stack.pop();
    } else if (invokedExpr instanceof Literal) {
        processLiteral((Literal) invokedExpr);
        invokedSqlExpr = stack.pop();
    } else if (invokedExpr instanceof ParameterExpression) {
        // TODO May be needed to set the second parameter to "false" here and then if the method
        // being invoked needs the parameters as a normal SQLLiteral then allow it to convert it itself
        processParameterExpression((ParameterExpression) invokedExpr, true);
        invokedSqlExpr = stack.pop();
    } else if (invokedExpr instanceof InvokeExpression) {
        processInvokeExpression((InvokeExpression) invokedExpr);
        invokedSqlExpr = stack.pop();
    } else if (invokedExpr instanceof VariableExpression) {
        processVariableExpression((VariableExpression) invokedExpr);
        invokedSqlExpr = stack.pop();
    } else if (invokedExpr instanceof ArrayExpression) {
        ArrayExpression arrExpr = (ArrayExpression) invokedExpr;
        SQLExpression[] arrSqlExprs = new SQLExpression[arrExpr.getArraySize()];
        for (int i = 0; i < arrExpr.getArraySize(); i++) {
            Expression arrElemExpr = arrExpr.getElement(i);
            arrElemExpr.evaluate(this);
            arrSqlExprs[i] = stack.pop();
        }
        JavaTypeMapping m = exprFactory.getMappingForType(Object[].class, false);
        invokedSqlExpr = new org.datanucleus.store.rdbms.sql.expression.ArrayExpression(stmt, m, arrSqlExprs);
    } else if (invokedExpr instanceof DyadicExpression) {
        DyadicExpression dyExpr = (DyadicExpression) invokedExpr;
        dyExpr.evaluate(this);
        invokedSqlExpr = stack.pop();
    } else {
        throw new NucleusException("Dont currently support invoke expression " + invokedExpr);
    }
    return invokedSqlExpr;
}
Also used : InvokeExpression(org.datanucleus.store.query.expression.InvokeExpression) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) PrimaryExpression(org.datanucleus.store.query.expression.PrimaryExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) VariableExpression(org.datanucleus.store.query.expression.VariableExpression) DyadicExpression(org.datanucleus.store.query.expression.DyadicExpression) PrimaryExpression(org.datanucleus.store.query.expression.PrimaryExpression) BooleanSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression) TypeConverterExpression(org.datanucleus.store.rdbms.sql.expression.TypeConverterExpression) StringExpression(org.datanucleus.store.rdbms.sql.expression.StringExpression) NumericSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.NumericSubqueryExpression) StringSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.StringSubqueryExpression) MapExpression(org.datanucleus.store.rdbms.sql.expression.MapExpression) ArrayExpression(org.datanucleus.store.query.expression.ArrayExpression) CaseExpression(org.datanucleus.store.query.expression.CaseExpression) CreatorExpression(org.datanucleus.store.query.expression.CreatorExpression) NewObjectExpression(org.datanucleus.store.rdbms.sql.expression.NewObjectExpression) OrderExpression(org.datanucleus.store.query.expression.OrderExpression) TemporalSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.TemporalSubqueryExpression) ClassExpression(org.datanucleus.store.query.expression.ClassExpression) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) Expression(org.datanucleus.store.query.expression.Expression) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) ParameterExpression(org.datanucleus.store.query.expression.ParameterExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) TemporalExpression(org.datanucleus.store.rdbms.sql.expression.TemporalExpression) SubqueryExpression(org.datanucleus.store.query.expression.SubqueryExpression) ResultAliasExpression(org.datanucleus.store.rdbms.sql.expression.ResultAliasExpression) VariableExpression(org.datanucleus.store.query.expression.VariableExpression) TypeExpression(org.datanucleus.store.query.expression.TypeExpression) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) CollectionExpression(org.datanucleus.store.rdbms.sql.expression.CollectionExpression) DyadicExpression(org.datanucleus.store.query.expression.DyadicExpression) ColumnExpression(org.datanucleus.store.rdbms.sql.expression.ColumnExpression) JoinExpression(org.datanucleus.store.query.expression.JoinExpression) InvokeExpression(org.datanucleus.store.query.expression.InvokeExpression) TemporalLiteral(org.datanucleus.store.rdbms.sql.expression.TemporalLiteral) Literal(org.datanucleus.store.query.expression.Literal) SQLLiteral(org.datanucleus.store.rdbms.sql.expression.SQLLiteral) ParameterLiteral(org.datanucleus.store.rdbms.sql.expression.ParameterLiteral) CollectionLiteral(org.datanucleus.store.rdbms.sql.expression.CollectionLiteral) BooleanLiteral(org.datanucleus.store.rdbms.sql.expression.BooleanLiteral) IntegerLiteral(org.datanucleus.store.rdbms.sql.expression.IntegerLiteral) NullLiteral(org.datanucleus.store.rdbms.sql.expression.NullLiteral) ParameterExpression(org.datanucleus.store.query.expression.ParameterExpression) ArrayExpression(org.datanucleus.store.query.expression.ArrayExpression) NucleusException(org.datanucleus.exceptions.NucleusException)

Example 62 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class JDOQLQuery method performExecute.

protected Object performExecute(Map parameters) {
    if (statementReturnsEmpty) {
        return Collections.EMPTY_LIST;
    }
    boolean inMemory = evaluateInMemory();
    if (candidateCollection != null) {
        // Supplied collection of instances, so evaluate in-memory
        if (candidateCollection.isEmpty()) {
            return Collections.EMPTY_LIST;
        } else if (inMemory) {
            return new JDOQLInMemoryEvaluator(this, new ArrayList(candidateCollection), compilation, parameters, clr).execute(true, true, true, true, true);
        }
    } else if (type == QueryType.SELECT) {
        // Query results are cached, so return those
        List<Object> cachedResults = getQueryManager().getQueryResult(this, parameters);
        if (cachedResults != null) {
            return new CandidateIdsQueryResult(this, cachedResults);
        }
    }
    Object results = null;
    RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
    ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
    try {
        // Execute the query
        long startTime = System.currentTimeMillis();
        if (NucleusLogger.QUERY.isDebugEnabled()) {
            NucleusLogger.QUERY.debug(Localiser.msg("021046", getLanguage(), getSingleStringQuery(), null));
        }
        AbstractClassMetaData acmd = ec.getMetaDataManager().getMetaDataForClass(candidateClass, clr);
        SQLController sqlControl = storeMgr.getSQLController();
        PreparedStatement ps = null;
        try {
            if (type == QueryType.SELECT) {
                // Create PreparedStatement and apply parameters, result settings etc
                ps = RDBMSQueryUtils.getPreparedStatementForQuery(mconn, datastoreCompilation.getSQL(), this);
                SQLStatementHelper.applyParametersToStatement(ps, ec, datastoreCompilation.getStatementParameters(), datastoreCompilation.getParameterNameByPosition(), parameters);
                RDBMSQueryUtils.prepareStatementForExecution(ps, this, true);
                registerTask(ps);
                ResultSet rs = null;
                try {
                    rs = sqlControl.executeStatementQuery(ec, mconn, datastoreCompilation.getSQL(), ps);
                } finally {
                    deregisterTask();
                }
                AbstractRDBMSQueryResult qr = null;
                try {
                    if (inMemory) {
                        // IN-MEMORY EVALUATION
                        ResultObjectFactory rof = new PersistentClassROF(ec, rs, ignoreCache, getFetchPlan(), datastoreCompilation.getResultDefinitionForClass(), acmd, candidateClass);
                        // Just instantiate the candidates for later in-memory processing
                        // TODO Use a queryResult rather than an ArrayList so we load when required
                        List candidates = new ArrayList();
                        while (rs.next()) {
                            candidates.add(rof.getObject());
                        }
                        // Perform in-memory filter/result/order etc
                        results = new JDOQLInMemoryEvaluator(this, candidates, compilation, parameters, clr).execute(true, true, true, true, true);
                    } else {
                        // IN-DATASTORE EVALUATION
                        ResultObjectFactory rof = null;
                        if (result != null) {
                            // Each result row is of a result type
                            rof = new ResultClassROF(ec, rs, ignoreCache, getFetchPlan(), resultClass, datastoreCompilation.getResultDefinition());
                        } else if (resultClass != null && resultClass != candidateClass) {
                            rof = new ResultClassROF(ec, rs, resultClass, datastoreCompilation.getResultDefinitionForClass());
                        } else {
                            // Each result row is a candidate object
                            rof = new PersistentClassROF(ec, rs, ignoreCache, getFetchPlan(), datastoreCompilation.getResultDefinitionForClass(), acmd, candidateClass);
                        }
                        // Create the required type of QueryResult
                        qr = RDBMSQueryUtils.getQueryResultForQuery(this, rof, rs, getResultDistinct() ? null : candidateCollection);
                        // Register any bulk loaded member resultSets that need loading
                        Map<String, IteratorStatement> scoIterStmts = datastoreCompilation.getSCOIteratorStatements();
                        if (scoIterStmts != null) {
                            Iterator<Map.Entry<String, IteratorStatement>> scoStmtIter = scoIterStmts.entrySet().iterator();
                            while (scoStmtIter.hasNext()) {
                                Map.Entry<String, IteratorStatement> stmtIterEntry = scoStmtIter.next();
                                IteratorStatement iterStmt = stmtIterEntry.getValue();
                                String iterStmtSQL = iterStmt.getSelectStatement().getSQLText().toSQL();
                                NucleusLogger.DATASTORE_RETRIEVE.debug("JDOQL Bulk-Fetch of " + iterStmt.getBackingStore().getOwnerMemberMetaData().getFullFieldName());
                                try {
                                    PreparedStatement psSco = sqlControl.getStatementForQuery(mconn, iterStmtSQL);
                                    if (datastoreCompilation.getStatementParameters() != null) {
                                        BulkFetchHandler.applyParametersToStatement(ec, psSco, datastoreCompilation, iterStmt.getSelectStatement(), parameters);
                                    }
                                    ResultSet rsSCO = sqlControl.executeStatementQuery(ec, mconn, iterStmtSQL, psSco);
                                    qr.registerMemberBulkResultSet(iterStmt, rsSCO);
                                } catch (SQLException e) {
                                    throw new NucleusDataStoreException(Localiser.msg("056006", iterStmtSQL), e);
                                }
                            }
                        }
                        // Initialise the QueryResult for use
                        qr.initialise();
                        // Add hooks for closing query resources
                        final QueryResult qr1 = qr;
                        final ManagedConnection mconn1 = mconn;
                        ManagedConnectionResourceListener listener = new ManagedConnectionResourceListener() {

                            public void transactionFlushed() {
                            }

                            public void transactionPreClose() {
                                // Tx : disconnect query from ManagedConnection (read in unread rows etc)
                                qr1.disconnect();
                            }

                            public void managedConnectionPreClose() {
                                if (!ec.getTransaction().isActive()) {
                                    // Non-Tx : disconnect query from ManagedConnection (read in unread rows etc)
                                    qr1.disconnect();
                                }
                            }

                            public void managedConnectionPostClose() {
                            }

                            public void resourcePostClose() {
                                mconn1.removeListener(this);
                            }
                        };
                        mconn.addListener(listener);
                        qr.addConnectionListener(listener);
                        results = qr;
                    }
                } finally {
                    if (qr == null) {
                        rs.close();
                    }
                }
            } else if (type == QueryType.BULK_UPDATE || type == QueryType.BULK_DELETE) {
                long bulkResult = 0;
                List<StatementCompilation> stmtCompilations = datastoreCompilation.getStatementCompilations();
                Iterator<StatementCompilation> stmtCompileIter = stmtCompilations.iterator();
                while (stmtCompileIter.hasNext()) {
                    StatementCompilation stmtCompile = stmtCompileIter.next();
                    ps = sqlControl.getStatementForUpdate(mconn, stmtCompile.getSQL(), false);
                    SQLStatementHelper.applyParametersToStatement(ps, ec, datastoreCompilation.getStatementParameters(), datastoreCompilation.getParameterNameByPosition(), parameters);
                    RDBMSQueryUtils.prepareStatementForExecution(ps, this, false);
                    int[] execResults = sqlControl.executeStatementUpdate(ec, mconn, toString(), ps, true);
                    if (stmtCompile.useInCount()) {
                        bulkResult += execResults[0];
                    }
                }
                try {
                    // Evict all objects of this type from the cache
                    ec.getNucleusContext().getLevel2Cache().evictAll(candidateClass, subclasses);
                } catch (UnsupportedOperationException uoe) {
                // Do nothing
                }
                results = bulkResult;
            }
        } catch (SQLException sqle) {
            if (storeMgr.getDatastoreAdapter().isStatementCancel(sqle)) {
                throw new QueryInterruptedException("Query has been interrupted", sqle);
            } else if (storeMgr.getDatastoreAdapter().isStatementTimeout(sqle)) {
                throw new QueryTimeoutException("Query has been timed out", sqle);
            }
            throw new NucleusException(Localiser.msg("021042", datastoreCompilation.getSQL()), sqle);
        }
        if (NucleusLogger.QUERY.isDebugEnabled()) {
            NucleusLogger.QUERY.debug(Localiser.msg("021074", getLanguage(), "" + (System.currentTimeMillis() - startTime)));
        }
        return results;
    } finally {
        mconn.release();
    }
}
Also used : SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) IteratorStatement(org.datanucleus.store.rdbms.scostore.IteratorStatement) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) SQLController(org.datanucleus.store.rdbms.SQLController) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) QueryTimeoutException(org.datanucleus.store.query.QueryTimeoutException) QueryResult(org.datanucleus.store.query.QueryResult) CandidateIdsQueryResult(org.datanucleus.store.query.CandidateIdsQueryResult) ResultSet(java.sql.ResultSet) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) CandidateIdsQueryResult(org.datanucleus.store.query.CandidateIdsQueryResult) QueryInterruptedException(org.datanucleus.store.query.QueryInterruptedException) StatementCompilation(org.datanucleus.store.rdbms.query.RDBMSQueryCompilation.StatementCompilation) JDOQLInMemoryEvaluator(org.datanucleus.store.query.inmemory.JDOQLInMemoryEvaluator) PreparedStatement(java.sql.PreparedStatement) ManagedConnectionResourceListener(org.datanucleus.store.connection.ManagedConnectionResourceListener) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) NucleusException(org.datanucleus.exceptions.NucleusException) Map(java.util.Map) HashMap(java.util.HashMap)

Example 63 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class JDOQLQuery method compileQueryFull.

/**
 * Method to set the (native) query statement for the compiled query as a whole.
 * @param parameters Input parameters (if known)
 * @param candidateCmd Metadata for the candidate class
 */
private void compileQueryFull(Map parameters, AbstractClassMetaData candidateCmd) {
    if (type != QueryType.SELECT) {
        return;
    }
    long startTime = 0;
    if (NucleusLogger.QUERY.isDebugEnabled()) {
        startTime = System.currentTimeMillis();
        NucleusLogger.QUERY.debug(Localiser.msg("021083", getLanguage(), toString()));
    }
    if (result != null) {
        datastoreCompilation.setResultDefinition(new StatementResultMapping());
    } else {
        datastoreCompilation.setResultDefinitionForClass(new StatementClassMapping());
    }
    // Generate statement for candidate(s)
    SelectStatement stmt = null;
    try {
        boolean includeSoftDeletes = getBooleanExtensionProperty(EXTENSION_INCLUDE_SOFT_DELETES, false);
        boolean dontRestrictDiscrim = getBooleanExtensionProperty(EXTENSION_CANDIDATE_DONT_RESTRICT_DISCRIMINATOR, false);
        Set<String> options = null;
        if (includeSoftDeletes) {
            options = new HashSet<>();
            options.add(SelectStatementGenerator.OPTION_INCLUDE_SOFT_DELETES);
        }
        if (dontRestrictDiscrim) {
            if (options == null) {
                options = new HashSet<>();
            }
            options.add(SelectStatementGenerator.OPTION_DONT_RESTRICT_DISCRIM);
        }
        stmt = RDBMSQueryUtils.getStatementForCandidates((RDBMSStoreManager) getStoreManager(), null, candidateCmd, datastoreCompilation.getResultDefinitionForClass(), ec, candidateClass, subclasses, result, null, null, options);
    } catch (NucleusException ne) {
        // Statement would result in no results, so just catch it and avoid generating the statement
        NucleusLogger.QUERY.warn("Query for candidates of " + candidateClass.getName() + (subclasses ? " and subclasses" : "") + " resulted in no possible candidates : " + StringUtils.getMessageFromRootCauseOfThrowable(ne));
        statementReturnsEmpty = true;
        return;
    }
    // Update the SQLStatement with filter, ordering, result etc
    Set<String> options = new HashSet<>();
    options.add(QueryToSQLMapper.OPTION_BULK_UPDATE_VERSION);
    if (getBooleanExtensionProperty(EXTENSION_USE_IS_NULL_WHEN_EQUALS_NULL_PARAM, true)) {
        options.add(QueryToSQLMapper.OPTION_NULL_PARAM_USE_IS_NULL);
    }
    if (getBooleanExtensionProperty(EXTENSION_NON_DISTINCT_IMPLICIT_JOIN, false)) {
        options.add(QueryToSQLMapper.OPTION_NON_DISTINCT_IMPLICIT_JOINS);
    }
    QueryToSQLMapper sqlMapper = new QueryToSQLMapper(stmt, compilation, parameters, datastoreCompilation.getResultDefinitionForClass(), datastoreCompilation.getResultDefinition(), candidateCmd, subclasses, getFetchPlan(), ec, getParsedImports(), options, extensions);
    setMapperJoinTypes(sqlMapper);
    sqlMapper.compile();
    datastoreCompilation.setParameterNameByPosition(sqlMapper.getParameterNameByPosition());
    datastoreCompilation.setPrecompilable(sqlMapper.isPrecompilable());
    if (!getResultDistinct() && stmt.isDistinct()) {
        setResultDistinct(true);
        compilation.setResultDistinct();
    }
    if (candidateCollection != null) {
        // Restrict to the supplied candidate ids
        BooleanExpression candidateExpr = null;
        Iterator iter = candidateCollection.iterator();
        JavaTypeMapping idMapping = stmt.getPrimaryTable().getTable().getIdMapping();
        while (iter.hasNext()) {
            Object candidate = iter.next();
            SQLExpression idExpr = stmt.getSQLExpressionFactory().newExpression(stmt, stmt.getPrimaryTable(), idMapping);
            SQLExpression idVal = stmt.getSQLExpressionFactory().newLiteral(stmt, idMapping, candidate);
            if (candidateExpr == null) {
                candidateExpr = idExpr.eq(idVal);
            } else {
                candidateExpr = candidateExpr.ior(idExpr.eq(idVal));
            }
        }
        stmt.whereAnd(candidateExpr, true);
    }
    // Apply any range
    if (range != null) {
        long lower = fromInclNo;
        long upper = toExclNo;
        if (fromInclParam != null) {
            if (parameters.containsKey(fromInclParam)) {
                lower = ((Number) parameters.get(fromInclParam)).longValue();
            } else {
                // Must be numbered input so take penultimate
                lower = ((Number) parameters.get(Integer.valueOf(parameters.size() - 2))).longValue();
            }
        }
        if (toExclParam != null) {
            if (parameters.containsKey(toExclParam)) {
                upper = ((Number) parameters.get(toExclParam)).longValue();
            } else {
                // Must be numbered input so take ultimate
                upper = ((Number) parameters.get(Integer.valueOf(parameters.size() - 1))).longValue();
            }
        }
        stmt.setRange(lower, upper - lower);
    }
    // Set any extensions
    boolean useUpdateLock = RDBMSQueryUtils.useUpdateLockForQuery(this);
    stmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, Boolean.valueOf(useUpdateLock));
    if (getBooleanExtensionProperty(EXTENSION_FOR_UPDATE_NOWAIT, false)) {
        stmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE_NOWAIT, Boolean.TRUE);
    }
    datastoreCompilation.addStatement(stmt, stmt.getSQLText().toSQL(), false);
    datastoreCompilation.setStatementParameters(stmt.getSQLText().getParametersForStatement());
    if (result == null && !(resultClass != null && resultClass != candidateClass)) {
        // Select of candidates, so check for any immediate multi-valued fields that are marked for fetching
        // TODO If the query joins to a 1-1/N-1 and then we have a multi-valued field, we should allow that too
        FetchPlanForClass fpc = getFetchPlan().getFetchPlanForClass(candidateCmd);
        int[] fpMembers = fpc.getMemberNumbers();
        String multifetchType = getStringExtensionProperty(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH, null);
        if ("none".equalsIgnoreCase(multifetchType)) {
        } else {
            // Bulk-Fetch
            for (int i = 0; i < fpMembers.length; i++) {
                AbstractMemberMetaData fpMmd = candidateCmd.getMetaDataForManagedMemberAtAbsolutePosition(fpMembers[i]);
                if (multifetchType == null) {
                    // Default to bulk-fetch EXISTS, so advise the user of why this is happening and how to turn it off
                    NucleusLogger.QUERY.debug("You have selected field " + fpMmd.getFullFieldName() + " for fetching by this query. We will fetch it using 'EXISTS'." + " To disable this set the query extension/hint '" + RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH + "' as 'none' or remove the field" + " from the query FetchPlan. If this bulk-fetch generates an invalid or unoptimised query, please report it with a way of reproducing it");
                    multifetchType = "exists";
                }
                RelationType relType = fpMmd.getRelationType(clr);
                if (RelationType.isRelationMultiValued(relType)) {
                    if (fpMmd.hasCollection() && SCOUtils.collectionHasSerialisedElements(fpMmd)) {
                    // Ignore collections stored into the owner (retrieved in main query)
                    } else if (fpMmd.hasArray() && SCOUtils.arrayIsStoredInSingleColumn(fpMmd, ec.getMetaDataManager())) {
                    // Ignore arrays stored into the owner (retrieved in main query)
                    } else if (fpMmd.hasMap() && SCOUtils.mapHasSerialisedKeysAndValues(fpMmd)) {
                    // Ignore maps stored into the owner (retrieved in main query)
                    } else {
                        if ("exists".equalsIgnoreCase(multifetchType)) {
                            // Fetch container contents for all candidate owners
                            BulkFetchExistsHandler helper = new BulkFetchExistsHandler();
                            IteratorStatement iterStmt = helper.getStatementToBulkFetchField(candidateCmd, fpMmd, this, parameters, datastoreCompilation, options);
                            if (iterStmt != null) {
                                datastoreCompilation.setSCOIteratorStatement(fpMmd.getFullFieldName(), iterStmt);
                            } else {
                                NucleusLogger.GENERAL.info("Query has field " + fpMmd.getFullFieldName() + " marked in the FetchPlan, yet this is currently not (bulk) fetched by this query");
                            }
                        } else if ("join".equalsIgnoreCase(multifetchType)) {
                            // Fetch container contents for all candidate owners
                            BulkFetchJoinHandler helper = new BulkFetchJoinHandler();
                            IteratorStatement iterStmt = helper.getStatementToBulkFetchField(candidateCmd, fpMmd, this, parameters, datastoreCompilation, options);
                            if (iterStmt != null) {
                                datastoreCompilation.setSCOIteratorStatement(fpMmd.getFullFieldName(), iterStmt);
                            } else {
                                NucleusLogger.GENERAL.info("Query has field " + fpMmd.getFullFieldName() + " marked in the FetchPlan, yet this is currently not (bulk) fetched by this query");
                            }
                        } else {
                            NucleusLogger.GENERAL.info("Query has field " + fpMmd.getFullFieldName() + " marked in the FetchPlan, yet this is not (bulk) fetched by this query; unsupported bulk-fetch type.");
                        }
                    }
                }
            }
        }
    }
    if (NucleusLogger.QUERY.isDebugEnabled()) {
        NucleusLogger.QUERY.debug(Localiser.msg("021084", getLanguage(), System.currentTimeMillis() - startTime));
    }
}
Also used : SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) FetchPlanForClass(org.datanucleus.FetchPlanForClass) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) IteratorStatement(org.datanucleus.store.rdbms.scostore.IteratorStatement) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) RelationType(org.datanucleus.metadata.RelationType) Iterator(java.util.Iterator) HashSet(java.util.HashSet) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 64 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class JDOQLQuery method compileQueryToRetrieveCandidates.

/**
 * Method to set the statement (and parameter/results definitions) to retrieve all candidates.
 * This is used when we want to evaluate in-memory and so just retrieve all possible candidates
 * first.
 * @param parameters Input parameters (if known)
 * @param candidateCmd Metadata for the candidate class
 */
private void compileQueryToRetrieveCandidates(Map parameters, AbstractClassMetaData candidateCmd) {
    if (type != QueryType.SELECT) {
        return;
    }
    StatementClassMapping resultsDef = new StatementClassMapping();
    datastoreCompilation.setResultDefinitionForClass(resultsDef);
    // Generate statement for candidate(s)
    SelectStatement stmt = null;
    try {
        stmt = RDBMSQueryUtils.getStatementForCandidates((RDBMSStoreManager) getStoreManager(), null, candidateCmd, datastoreCompilation.getResultDefinitionForClass(), ec, candidateClass, subclasses, result, null, null, null);
    } catch (NucleusException ne) {
        // Statement would result in no results, so just catch it and avoid generating the statement
        NucleusLogger.QUERY.warn("Query for candidates of " + candidateClass.getName() + (subclasses ? " and subclasses" : "") + " resulted in no possible candidates", ne);
        statementReturnsEmpty = true;
        return;
    }
    if (stmt.allUnionsForSamePrimaryTable()) {
        // Select fetch-plan fields of candidate class
        SQLStatementHelper.selectFetchPlanOfCandidateInStatement(stmt, datastoreCompilation.getResultDefinitionForClass(), candidateCmd, getFetchPlan(), 1);
    } else {
        // Select id only since tables don't have same mappings or column names
        // TODO complete-table will come through here but maybe ought to be treated differently
        SQLStatementHelper.selectIdentityOfCandidateInStatement(stmt, datastoreCompilation.getResultDefinitionForClass(), candidateCmd);
    }
    datastoreCompilation.addStatement(stmt, stmt.getSQLText().toSQL(), false);
    datastoreCompilation.setStatementParameters(stmt.getSQLText().getParametersForStatement());
}
Also used : SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) NucleusException(org.datanucleus.exceptions.NucleusException) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager)

Example 65 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method compileUpdate.

/**
 * Method to compile the result clause of the query into the SQLStatement.
 * @param stmt UPDATE statement
 */
protected void compileUpdate(UpdateStatement stmt) {
    if (compilation.getExprUpdate() != null) {
        // Update statement, so generate update expression(s)
        compileComponent = CompilationComponent.UPDATE;
        Expression[] updateExprs = compilation.getExprUpdate();
        SQLExpression[] updateSqlExprs = new SQLExpression[updateExprs.length];
        // TODO If the field being set is in a different table omit it
        boolean performingUpdate = false;
        for (int i = 0; i < updateExprs.length; i++) {
            // "field = value"
            DyadicExpression updateExpr = (DyadicExpression) updateExprs[i];
            // Left-side has to be PrimaryExpression
            SQLExpression leftSqlExpr = null;
            if (updateExpr.getLeft() instanceof PrimaryExpression) {
                processPrimaryExpression((PrimaryExpression) updateExpr.getLeft());
                leftSqlExpr = stack.pop();
                if (leftSqlExpr.getSQLTable() != stmt.getPrimaryTable()) {
                    // Set left to null to signify that it is not applicable to the table of this UPDATE statement
                    leftSqlExpr = null;
                }
            } else {
                throw new NucleusException("Dont currently support update clause containing left expression of type " + updateExpr.getLeft());
            }
            if (leftSqlExpr != null) {
                if (!stmt.getDatastoreAdapter().supportsOption(DatastoreAdapter.UPDATE_STATEMENT_ALLOW_TABLE_ALIAS_IN_SET_CLAUSE)) {
                    // This datastore doesn't allow table alias in UPDATE SET clause, so just use column name
                    for (int j = 0; j < leftSqlExpr.getNumberOfSubExpressions(); j++) {
                        ColumnExpression colExpr = leftSqlExpr.getSubExpression(j);
                        colExpr.setOmitTableFromString(true);
                    }
                }
                performingUpdate = true;
                SQLExpression rightSqlExpr = null;
                if (updateExpr.getRight() instanceof Literal) {
                    processLiteral((Literal) updateExpr.getRight());
                    rightSqlExpr = stack.pop();
                } else if (updateExpr.getRight() instanceof ParameterExpression) {
                    ParameterExpression paramExpr = (ParameterExpression) updateExpr.getRight();
                    paramMappingForName.put(paramExpr.getId(), leftSqlExpr.getJavaTypeMapping());
                    processParameterExpression(paramExpr);
                    rightSqlExpr = stack.pop();
                } else if (updateExpr.getRight() instanceof PrimaryExpression) {
                    processPrimaryExpression((PrimaryExpression) updateExpr.getRight());
                    rightSqlExpr = stack.pop();
                } else if (updateExpr.getRight() instanceof DyadicExpression) {
                    updateExpr.getRight().evaluate(this);
                    rightSqlExpr = stack.pop();
                } else if (updateExpr.getRight() instanceof CaseExpression) {
                    CaseExpression caseExpr = (CaseExpression) updateExpr.getRight();
                    processCaseExpression(caseExpr, leftSqlExpr);
                    rightSqlExpr = stack.pop();
                } else if (updateExpr.getRight() instanceof VariableExpression) {
                    // Subquery?
                    processVariableExpression((VariableExpression) updateExpr.getRight());
                    rightSqlExpr = stack.pop();
                    if (rightSqlExpr instanceof UnboundExpression) {
                        // TODO Support whatever this is
                        throw new NucleusException("Found UnboundExpression in UPDATE clause!");
                    }
                } else {
                    throw new NucleusException("Dont currently support update clause containing right expression of type " + updateExpr.getRight());
                }
                if (rightSqlExpr != null) {
                    updateSqlExprs[i] = leftSqlExpr.eq(rightSqlExpr);
                }
            }
        }
        if (candidateCmd.isVersioned() && options.contains(OPTION_BULK_UPDATE_VERSION)) {
            SQLExpression updateSqlExpr = null;
            ClassTable table = (ClassTable) stmt.getPrimaryTable().getTable();
            JavaTypeMapping verMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, true);
            ClassTable verTable = table.getTableManagingMapping(verMapping);
            if (verTable == stmt.getPrimaryTable().getTable()) {
                VersionMetaData vermd = candidateCmd.getVersionMetaDataForClass();
                if (vermd.getStrategy() == VersionStrategy.VERSION_NUMBER) {
                    // Increment the version
                    SQLTable verSqlTbl = stmt.getTable(verTable, stmt.getPrimaryTable().getGroupName());
                    SQLExpression verExpr = new NumericExpression(stmt, verSqlTbl, verMapping);
                    SQLExpression incrExpr = verExpr.add(new IntegerLiteral(stmt, exprFactory.getMappingForType(Integer.class, false), Integer.valueOf(1), null));
                    updateSqlExpr = verExpr.eq(incrExpr);
                    SQLExpression[] oldArray = updateSqlExprs;
                    updateSqlExprs = new SQLExpression[oldArray.length + 1];
                    System.arraycopy(oldArray, 0, updateSqlExprs, 0, oldArray.length);
                    updateSqlExprs[oldArray.length] = updateSqlExpr;
                    performingUpdate = true;
                } else if (vermd.getStrategy() == VersionStrategy.DATE_TIME) {
                    // Set version to the time of update
                    SQLTable verSqlTbl = stmt.getTable(verTable, stmt.getPrimaryTable().getGroupName());
                    SQLExpression verExpr = new NumericExpression(stmt, verSqlTbl, verMapping);
                    Object newVersion = ec.getLockManager().getNextVersion(vermd, null);
                    JavaTypeMapping valMapping = exprFactory.getMappingForType(newVersion.getClass(), false);
                    SQLExpression valExpr = new TemporalLiteral(stmt, valMapping, newVersion, null);
                    updateSqlExpr = verExpr.eq(valExpr);
                    SQLExpression[] oldArray = updateSqlExprs;
                    updateSqlExprs = new SQLExpression[oldArray.length + 1];
                    System.arraycopy(oldArray, 0, updateSqlExprs, 0, oldArray.length);
                    updateSqlExprs[oldArray.length] = updateSqlExpr;
                    performingUpdate = true;
                }
            }
        }
        if (performingUpdate) {
            // Only set the updates component of the SQLStatement if anything to update in this table
            stmt.setUpdates(updateSqlExprs);
        }
    }
    compileComponent = null;
}
Also used : SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) PrimaryExpression(org.datanucleus.store.query.expression.PrimaryExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) VersionMetaData(org.datanucleus.metadata.VersionMetaData) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) TemporalLiteral(org.datanucleus.store.rdbms.sql.expression.TemporalLiteral) VariableExpression(org.datanucleus.store.query.expression.VariableExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) DyadicExpression(org.datanucleus.store.query.expression.DyadicExpression) CaseExpression(org.datanucleus.store.query.expression.CaseExpression) PrimaryExpression(org.datanucleus.store.query.expression.PrimaryExpression) BooleanSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression) TypeConverterExpression(org.datanucleus.store.rdbms.sql.expression.TypeConverterExpression) StringExpression(org.datanucleus.store.rdbms.sql.expression.StringExpression) NumericSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.NumericSubqueryExpression) StringSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.StringSubqueryExpression) MapExpression(org.datanucleus.store.rdbms.sql.expression.MapExpression) ArrayExpression(org.datanucleus.store.query.expression.ArrayExpression) CaseExpression(org.datanucleus.store.query.expression.CaseExpression) CreatorExpression(org.datanucleus.store.query.expression.CreatorExpression) NewObjectExpression(org.datanucleus.store.rdbms.sql.expression.NewObjectExpression) OrderExpression(org.datanucleus.store.query.expression.OrderExpression) TemporalSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.TemporalSubqueryExpression) ClassExpression(org.datanucleus.store.query.expression.ClassExpression) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) Expression(org.datanucleus.store.query.expression.Expression) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) ParameterExpression(org.datanucleus.store.query.expression.ParameterExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) TemporalExpression(org.datanucleus.store.rdbms.sql.expression.TemporalExpression) SubqueryExpression(org.datanucleus.store.query.expression.SubqueryExpression) ResultAliasExpression(org.datanucleus.store.rdbms.sql.expression.ResultAliasExpression) VariableExpression(org.datanucleus.store.query.expression.VariableExpression) TypeExpression(org.datanucleus.store.query.expression.TypeExpression) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) CollectionExpression(org.datanucleus.store.rdbms.sql.expression.CollectionExpression) DyadicExpression(org.datanucleus.store.query.expression.DyadicExpression) ColumnExpression(org.datanucleus.store.rdbms.sql.expression.ColumnExpression) JoinExpression(org.datanucleus.store.query.expression.JoinExpression) InvokeExpression(org.datanucleus.store.query.expression.InvokeExpression) ColumnExpression(org.datanucleus.store.rdbms.sql.expression.ColumnExpression) ClassTable(org.datanucleus.store.rdbms.table.ClassTable) TemporalLiteral(org.datanucleus.store.rdbms.sql.expression.TemporalLiteral) Literal(org.datanucleus.store.query.expression.Literal) SQLLiteral(org.datanucleus.store.rdbms.sql.expression.SQLLiteral) ParameterLiteral(org.datanucleus.store.rdbms.sql.expression.ParameterLiteral) CollectionLiteral(org.datanucleus.store.rdbms.sql.expression.CollectionLiteral) BooleanLiteral(org.datanucleus.store.rdbms.sql.expression.BooleanLiteral) IntegerLiteral(org.datanucleus.store.rdbms.sql.expression.IntegerLiteral) NullLiteral(org.datanucleus.store.rdbms.sql.expression.NullLiteral) ParameterExpression(org.datanucleus.store.query.expression.ParameterExpression) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) NucleusException(org.datanucleus.exceptions.NucleusException) IntegerLiteral(org.datanucleus.store.rdbms.sql.expression.IntegerLiteral)

Aggregations

NucleusException (org.datanucleus.exceptions.NucleusException)326 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)71 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)67 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)62 ParameterExpression (org.datanucleus.query.expression.ParameterExpression)53 PrimaryExpression (org.datanucleus.query.expression.PrimaryExpression)52 ArrayList (java.util.ArrayList)48 Literal (org.datanucleus.query.expression.Literal)47 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)44 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)43 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)40 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)37 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)36 StringExpression (org.datanucleus.store.rdbms.sql.expression.StringExpression)35 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)35 Expression (org.datanucleus.query.expression.Expression)32 HashMap (java.util.HashMap)31 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)31 VariableExpression (org.datanucleus.query.expression.VariableExpression)26 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)26