Search in sources :

Example 1 with DbmsModificationState

use of com.blazebit.persistence.spi.DbmsModificationState in project blaze-persistence by Blazebit.

the class AbstractCommonQueryBuilder method getCteNodes.

protected List<CTENode> getCteNodes(boolean isSubquery) {
    List<CTENode> cteNodes = new ArrayList<CTENode>();
    // NOTE: Delete statements could cause CTEs to be generated for the cascading deletes
    if (!isMainQuery || isSubquery || !mainQuery.dbmsDialect.supportsWithClause() || !mainQuery.cteManager.hasCtes() && statementType != DbmsStatementType.DELETE || statementType != DbmsStatementType.SELECT && !mainQuery.dbmsDialect.supportsWithClauseInModificationQuery()) {
        return cteNodes;
    }
    StringBuilder sb = new StringBuilder();
    for (CTEInfo cteInfo : mainQuery.cteManager.getCtes()) {
        if (!cteInfo.inline) {
            // Build queries and add as participating queries
            Map<DbmsModificationState, String> modificationStates = cteInfo.nonRecursiveCriteriaBuilder.getModificationStates(explicitVersionEntities);
            Query nonRecursiveQuery = cteInfo.nonRecursiveCriteriaBuilder.getQuery(modificationStates);
            QuerySpecification<?> nonRecursiveQuerySpecification = getQuerySpecification(nonRecursiveQuery);
            Map<String, String> nonRecursiveTableNameRemappings = null;
            if (nonRecursiveQuery instanceof CustomSQLQuery) {
                // EntityAlias -> CteName
                nonRecursiveTableNameRemappings = cteInfo.nonRecursiveCriteriaBuilder.getModificationStateRelatedTableNameRemappings(explicitVersionEntities);
            }
            Query recursiveQuery;
            QuerySpecification<?> recursiveQuerySpecification = null;
            Map<String, String> recursiveTableNameRemappings = null;
            if (cteInfo.recursive) {
                modificationStates = cteInfo.nonRecursiveCriteriaBuilder.getModificationStates(explicitVersionEntities);
                recursiveQuery = cteInfo.recursiveCriteriaBuilder.getQuery(modificationStates);
                if (!mainQuery.dbmsDialect.supportsJoinsInRecursiveCte() && cteInfo.recursiveCriteriaBuilder.joinManager.hasNonEmulatableJoins()) {
                    throw new IllegalStateException("The dbms dialect does not support joins in the recursive part of a CTE!");
                }
                recursiveQuerySpecification = getQuerySpecification(recursiveQuery);
                if (recursiveQuery instanceof CustomSQLQuery) {
                    // EntityAlias -> CteName
                    recursiveTableNameRemappings = cteInfo.recursiveCriteriaBuilder.getModificationStateRelatedTableNameRemappings(explicitVersionEntities);
                }
            }
            String cteName = cteInfo.cteType.getName();
            final List<String> columnNames = cteInfo.columnNames;
            String head;
            String[] aliases;
            if (mainQuery.dbmsDialect.supportsWithClauseHead()) {
                sb.setLength(0);
                sb.append(cteName);
                sb.append('(');
                for (int i = 0; i < columnNames.size(); i++) {
                    String column = columnNames.get(i);
                    if (i != 0) {
                        sb.append(", ");
                    }
                    sb.append(column);
                }
                sb.append(')');
                head = sb.toString();
                aliases = null;
            } else {
                sb.setLength(0);
                sb.append(cteName);
                List<String> list = new ArrayList<>(columnNames.size());
                for (int i = 0; i < columnNames.size(); i++) {
                    String[] columns = mainQuery.metamodel.getManagedType(ExtendedManagedType.class, cteInfo.cteType.getJavaType()).getAttribute(columnNames.get(i)).getColumnNames();
                    for (String column : columns) {
                        list.add(column);
                    }
                }
                head = sb.toString();
                aliases = list.toArray(new String[list.size()]);
            }
            String nonRecursiveWithClauseSuffix = null;
            if (!cteInfo.recursive && !mainQuery.dbmsDialect.supportsNonRecursiveWithClause()) {
                sb.setLength(0);
                sb.append(" UNION ALL ");
                sb.append("SELECT ");
                sb.append("NULL");
                for (int i = 1; i < columnNames.size(); i++) {
                    sb.append(", ");
                    sb.append("NULL");
                }
                sb.append(" FROM DUAL WHERE 1=0");
                nonRecursiveWithClauseSuffix = sb.toString();
            }
            cteNodes.add(new CTENode(cteInfo.name, cteInfo.cteType.getName(), head, aliases, cteInfo.unionAll, nonRecursiveQuerySpecification, recursiveQuerySpecification, nonRecursiveTableNameRemappings, recursiveTableNameRemappings, nonRecursiveWithClauseSuffix));
        }
    }
    return cteNodes;
}
Also used : DbmsModificationState(com.blazebit.persistence.spi.DbmsModificationState) CustomSQLTypedQuery(com.blazebit.persistence.impl.query.CustomSQLTypedQuery) AbstractCustomQuery(com.blazebit.persistence.impl.query.AbstractCustomQuery) TypedQuery(javax.persistence.TypedQuery) CustomSQLQuery(com.blazebit.persistence.impl.query.CustomSQLQuery) Query(javax.persistence.Query) ObjectBuilderTypedQuery(com.blazebit.persistence.impl.query.ObjectBuilderTypedQuery) CustomSQLQuery(com.blazebit.persistence.impl.query.CustomSQLQuery) ArrayList(java.util.ArrayList) CTENode(com.blazebit.persistence.impl.query.CTENode)

Aggregations

AbstractCustomQuery (com.blazebit.persistence.impl.query.AbstractCustomQuery)1 CTENode (com.blazebit.persistence.impl.query.CTENode)1 CustomSQLQuery (com.blazebit.persistence.impl.query.CustomSQLQuery)1 CustomSQLTypedQuery (com.blazebit.persistence.impl.query.CustomSQLTypedQuery)1 ObjectBuilderTypedQuery (com.blazebit.persistence.impl.query.ObjectBuilderTypedQuery)1 DbmsModificationState (com.blazebit.persistence.spi.DbmsModificationState)1 ArrayList (java.util.ArrayList)1 Query (javax.persistence.Query)1 TypedQuery (javax.persistence.TypedQuery)1