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;
}
Aggregations