Search in sources :

Example 1 with SelectClause

use of org.hibernate.sql.ast.tree.select.SelectClause in project hibernate-orm by hibernate.

the class AbstractCollectionPersister method selectFragment.

/**
 * Generate a list of collection index, key and element columns
 */
@Override
public String selectFragment(String alias, String columnSuffix) {
    final PluralAttributeMapping attributeMapping = getAttributeMapping();
    final QuerySpec rootQuerySpec = new QuerySpec(true);
    final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState(rootQuerySpec, new SqlAliasBaseManager(), new SimpleFromClauseAccessImpl(), LockOptions.NONE, (fetchParent, querySpec, creationState) -> new ArrayList<>(), true, getFactory());
    final NavigablePath entityPath = new NavigablePath(attributeMapping.getRootPathName());
    final TableGroup rootTableGroup = attributeMapping.createRootTableGroup(true, entityPath, null, () -> p -> {
    }, new SqlAliasBaseConstant(alias), sqlAstCreationState.getSqlExpressionResolver(), sqlAstCreationState.getFromClauseAccess(), getFactory());
    rootQuerySpec.getFromClause().addRoot(rootTableGroup);
    sqlAstCreationState.getFromClauseAccess().registerTableGroup(entityPath, rootTableGroup);
    attributeMapping.createDomainResult(entityPath, rootTableGroup, null, sqlAstCreationState);
    // Wrap expressions with aliases
    final SelectClause selectClause = rootQuerySpec.getSelectClause();
    final java.util.List<SqlSelection> sqlSelections = selectClause.getSqlSelections();
    int i = 0;
    for (String keyAlias : keyColumnAliases) {
        sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), keyAlias + columnSuffix)));
        i++;
    }
    if (hasIndex) {
        for (String indexAlias : indexColumnAliases) {
            sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), indexAlias + columnSuffix)));
            i++;
        }
    }
    if (hasIdentifier) {
        sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), identifierColumnAlias + columnSuffix)));
        i++;
    }
    for (int columnIndex = 0; i < sqlSelections.size(); i++, columnIndex++) {
        final SqlSelection sqlSelection = sqlSelections.get(i);
        sqlSelections.set(i, new SqlSelectionImpl(sqlSelection.getValuesArrayPosition(), sqlSelection.getJdbcResultSetIndex(), new AliasedExpression(sqlSelection.getExpression(), elementColumnAliases[columnIndex] + columnSuffix)));
    }
    final String sql = getFactory().getJdbcServices().getDialect().getSqlAstTranslatorFactory().buildSelectTranslator(getFactory(), new SelectStatement(rootQuerySpec)).translate(null, QueryOptions.NONE).getSql();
    final int fromIndex = sql.lastIndexOf(" from");
    final String expression;
    if (fromIndex != -1) {
        expression = sql.substring("select ".length(), fromIndex);
    } else {
        expression = sql.substring("select ".length());
    }
    return expression;
}
Also used : SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) NavigablePath(org.hibernate.query.spi.NavigablePath) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) SimpleFromClauseAccessImpl(org.hibernate.sql.ast.spi.SimpleFromClauseAccessImpl) SqlAliasBaseManager(org.hibernate.sql.ast.spi.SqlAliasBaseManager) SqlAliasBaseConstant(org.hibernate.sql.ast.spi.SqlAliasBaseConstant) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection) AliasedExpression(org.hibernate.sql.ast.tree.expression.AliasedExpression) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) LoaderSqlAstCreationState(org.hibernate.loader.ast.internal.LoaderSqlAstCreationState) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec)

Example 2 with SelectClause

use of org.hibernate.sql.ast.tree.select.SelectClause in project hibernate-orm by hibernate.

the class AbstractCteMutationHandler method createIdSubQueryPredicate.

protected Predicate createIdSubQueryPredicate(List<? extends Expression> lhsExpressions, CteStatement idSelectCte, ModelPart fkModelPart, SessionFactoryImplementor factory) {
    final NamedTableReference idSelectTableReference = new NamedTableReference(idSelectCte.getCteTable().getTableExpression(), CTE_TABLE_IDENTIFIER, false, factory);
    final Junction predicate = new Junction(Junction.Nature.CONJUNCTION);
    final List<CteColumn> cteColumns = idSelectCte.getCteTable().getCteColumns();
    final int size = lhsExpressions.size();
    final QuerySpec subQuery = new QuerySpec(false, 1);
    subQuery.getFromClause().addRoot(new CteTableGroup(idSelectTableReference));
    final SelectClause subQuerySelectClause = subQuery.getSelectClause();
    if (fkModelPart == null) {
        for (int i = 0; i < size; i++) {
            final CteColumn cteColumn = cteColumns.get(i);
            subQuerySelectClause.addSqlSelection(new SqlSelectionImpl(i + 1, i, new ColumnReference(idSelectTableReference, cteColumn.getColumnExpression(), cteColumn.getJdbcMapping(), factory)));
        }
    } else {
        fkModelPart.forEachSelectable((selectionIndex, selectableMapping) -> {
            subQuerySelectClause.addSqlSelection(new SqlSelectionImpl(selectionIndex + 1, selectionIndex, new ColumnReference(idSelectTableReference, selectableMapping.getSelectionExpression(), selectableMapping.getJdbcMapping(), factory)));
        });
    }
    final Expression lhs;
    if (lhsExpressions.size() == 1) {
        lhs = lhsExpressions.get(0);
    } else {
        lhs = new SqlTuple(lhsExpressions, null);
    }
    predicate.add(new InSubQueryPredicate(lhs, subQuery, false));
    return predicate;
}
Also used : CteColumn(org.hibernate.sql.ast.tree.cte.CteColumn) SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) CteTableGroup(org.hibernate.sql.ast.tree.cte.CteTableGroup) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) SqlTuple(org.hibernate.sql.ast.tree.expression.SqlTuple) Junction(org.hibernate.sql.ast.tree.predicate.Junction) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Example 3 with SelectClause

use of org.hibernate.sql.ast.tree.select.SelectClause in project hibernate-orm by hibernate.

the class AggregateWindowEmulationQueryTransformer method transform.

@Override
public QuerySpec transform(CteContainer cteContainer, QuerySpec querySpec, SqmToSqlAstConverter converter) {
    final SessionFactoryImplementor factory = converter.getCreationContext().getSessionFactory();
    final QuerySpec outerQuerySpec = new QuerySpec(querySpec.isRoot());
    final String identifierVariable = "hhh_";
    final NavigablePath navigablePath = new NavigablePath(identifierVariable, identifierVariable);
    final SelectClause selectClause = outerQuerySpec.getSelectClause();
    final QuerySpec subQuerySpec = querySpec.asSubQuery();
    final SelectClause subSelectClause = subQuerySpec.getSelectClause();
    final List<SqlSelection> subSelections = subSelectClause.getSqlSelections();
    final List<String> columnNames = new ArrayList<>(subSelections.size());
    // A map to find the select item position for an expression
    // which is needed to decide if we need to introduce synthetic select items
    // for group by items, since these group by items are migrated to the outer query
    final Map<Expression, Integer> selectionMapping = new HashMap<>(subSelections.size());
    // for the QueryPartTableGroup within which the sub query spec is embedded
    for (int i = 0; i < subSelections.size(); i++) {
        final BasicValuedMapping mapping = (BasicValuedMapping) subSelections.get(i).getExpressionType();
        final String columnName = "col" + i;
        final ColumnReference columnReference = new ColumnReference(identifierVariable, columnName, false, null, null, mapping.getJdbcMapping(), factory);
        final Expression expression = subSelections.get(i).getExpression();
        final Expression finalExpression;
        if (expression == windowFunction) {
            finalExpression = new SelfRenderingAggregateFunctionSqlAstExpression("min", (sqlAppender, sqlAstArguments, walker1) -> {
                sqlAppender.appendSql("min(");
                sqlAstArguments.get(0).accept(walker1);
                sqlAppender.append(')');
            }, Collections.singletonList(columnReference), null, (ReturnableType<?>) mapping.getMappedType(), expression.getExpressionType());
        } else {
            finalExpression = columnReference;
            selectionMapping.put(expression, i);
        }
        columnNames.add(columnName);
        selectClause.addSqlSelection(new ResolvedSqlSelection(i + 1, i, finalExpression, (BasicType<Object>) mapping.getJdbcMapping()));
    }
    // Migrate the group by clause to the outer query
    // and push group by expressions into the partition by clause of the window function
    final List<Expression> groupByExpressions = new ArrayList<>(subQuerySpec.getGroupByClauseExpressions().size());
    for (Expression groupByClauseExpression : subQuerySpec.getGroupByClauseExpressions()) {
        final Expression realExpression;
        final Expression outerGroupByExpression;
        if (groupByClauseExpression instanceof SqlSelectionExpression) {
            final SqlSelection selection = ((SqlSelectionExpression) groupByClauseExpression).getSelection();
            outerGroupByExpression = new SqlSelectionExpression(selectClause.getSqlSelections().get(selection.getValuesArrayPosition()));
            realExpression = selection.getExpression();
        } else {
            if (groupByClauseExpression instanceof SqmPathInterpretation<?>) {
                realExpression = ((SqmPathInterpretation<?>) groupByClauseExpression).getSqlExpression();
            } else {
                realExpression = groupByClauseExpression;
            }
            final Integer position = selectionMapping.get(realExpression);
            if (position == null) {
                // Group by something that has no corresponding selection item,
                // so we need to introduce an intermediate selection item
                final int valuesPosition = selectClause.getSqlSelections().size();
                final String columnName = "col" + valuesPosition;
                final JdbcMapping jdbcMapping = realExpression.getExpressionType().getJdbcMappings().get(0);
                final ColumnReference columnReference = new ColumnReference(identifierVariable, columnName, false, null, null, jdbcMapping, factory);
                final int subValuesPosition = subSelectClause.getSqlSelections().size();
                final SqlSelection subSelection = new ResolvedSqlSelection(subValuesPosition + 1, subValuesPosition, realExpression, (BasicType<Object>) jdbcMapping);
                columnNames.add(columnName);
                subSelectClause.addSqlSelection(subSelection);
                outerGroupByExpression = columnReference;
                selectionMapping.put(realExpression, subValuesPosition);
            } else {
                outerGroupByExpression = new SqlSelectionExpression(selectClause.getSqlSelections().get(position));
            }
        }
        windowFunction.getPartitions().add(realExpression);
        groupByExpressions.add(outerGroupByExpression);
    }
    outerQuerySpec.setGroupByClauseExpressions(groupByExpressions);
    subQuerySpec.setGroupByClauseExpressions(null);
    // Migrate the having clause to the outer query
    if (subQuerySpec.getHavingClauseRestrictions() != null) {
        final Predicate predicate = new ExpressionReplacementWalker() {

            @Override
            protected <X extends SqlAstNode> X replaceExpression(X expression) {
                if (expression instanceof Literal || expression instanceof JdbcParameter) {
                    return expression;
                }
                final Expression outerExpression;
                if (expression instanceof SqlSelectionExpression) {
                    final SqlSelection selection = ((SqlSelectionExpression) expression).getSelection();
                    outerExpression = selectClause.getSqlSelections().get(selection.getValuesArrayPosition()).getExpression();
                } else {
                    final Expression realExpression;
                    if (expression instanceof SqmPathInterpretation<?>) {
                        realExpression = ((SqmPathInterpretation<?>) expression).getSqlExpression();
                    } else {
                        realExpression = (Expression) expression;
                    }
                    final Integer position = selectionMapping.get(realExpression);
                    if (position == null) {
                        // An expression that has no corresponding selection item,
                        // so we need to introduce an intermediate selection item
                        final int valuesPosition = selectClause.getSqlSelections().size();
                        final String columnName = "col" + valuesPosition;
                        final JdbcMapping jdbcMapping = realExpression.getExpressionType().getJdbcMappings().get(0);
                        final ColumnReference columnReference = new ColumnReference(identifierVariable, columnName, false, null, null, jdbcMapping, factory);
                        final int subValuesPosition = subSelectClause.getSqlSelections().size();
                        final SqlSelection subSelection = new ResolvedSqlSelection(subValuesPosition + 1, subValuesPosition, realExpression, (BasicType<Object>) jdbcMapping);
                        columnNames.add(columnName);
                        subSelectClause.addSqlSelection(subSelection);
                        outerExpression = columnReference;
                        selectionMapping.put(realExpression, subValuesPosition);
                    } else {
                        outerExpression = selectClause.getSqlSelections().get(position).getExpression();
                    }
                }
                return (X) outerExpression;
            }
        }.replaceExpressions(subQuerySpec.getHavingClauseRestrictions());
        outerQuerySpec.setHavingClauseRestrictions(predicate);
        subQuerySpec.setHavingClauseRestrictions(null);
    }
    // Migrate the order by clause to the outer query
    if (subQuerySpec.hasSortSpecifications()) {
        for (SortSpecification sortSpecification : subQuerySpec.getSortSpecifications()) {
            final Expression sortExpression = sortSpecification.getSortExpression();
            final Expression outerSortExpression;
            if (sortExpression instanceof SqlSelectionExpression) {
                final SqlSelection selection = ((SqlSelectionExpression) sortExpression).getSelection();
                outerSortExpression = new SqlSelectionExpression(selectClause.getSqlSelections().get(selection.getValuesArrayPosition()));
            } else {
                final Expression realExpression;
                if (sortExpression instanceof SqmPathInterpretation<?>) {
                    realExpression = ((SqmPathInterpretation<?>) sortExpression).getSqlExpression();
                } else {
                    realExpression = sortExpression;
                }
                final Integer position = selectionMapping.get(realExpression);
                if (position == null) {
                    // Group by something that has no corresponding selection item,
                    // so we need to introduce an intermediate selection item
                    final int valuesPosition = selectClause.getSqlSelections().size();
                    final String columnName = "col" + valuesPosition;
                    final JdbcMapping jdbcMapping = realExpression.getExpressionType().getJdbcMappings().get(0);
                    final ColumnReference columnReference = new ColumnReference(identifierVariable, columnName, false, null, null, jdbcMapping, factory);
                    final int subValuesPosition = subSelectClause.getSqlSelections().size();
                    final SqlSelection subSelection = new ResolvedSqlSelection(subValuesPosition + 1, subValuesPosition, realExpression, (BasicType<Object>) jdbcMapping);
                    columnNames.add(columnName);
                    subSelectClause.addSqlSelection(subSelection);
                    outerSortExpression = columnReference;
                    selectionMapping.put(realExpression, subValuesPosition);
                } else {
                    outerSortExpression = new SqlSelectionExpression(selectClause.getSqlSelections().get(position));
                }
            }
            outerQuerySpec.addSortSpecification(new SortSpecification(outerSortExpression, sortSpecification.getSortOrder(), sortSpecification.getNullPrecedence()));
        }
        subQuerySpec.getSortSpecifications().clear();
    }
    // We need to add selection items for the expressions we order by to the sub query spec.
    final int selectionOffset = columnNames.size();
    // Collect the sorting column references so we can apply the filter later
    final List<ColumnReference> sortingColumns = new ArrayList<>(withinGroup.size());
    for (int i = 0; i < withinGroup.size(); i++) {
        final int valueIndex = selectionOffset + i;
        final Expression sortExpression = withinGroup.get(i).getSortExpression();
        final BasicValuedMapping mapping = (BasicValuedMapping) sortExpression.getExpressionType();
        final String columnName = "col" + valueIndex;
        final int oldValueIndex = subSelectClause.getSqlSelections().size();
        columnNames.add(columnName);
        subSelectClause.addSqlSelection(new ResolvedSqlSelection(oldValueIndex + 1, oldValueIndex, sortExpression, (BasicType<Object>) mapping.getJdbcMapping()));
        sortingColumns.add(new ColumnReference(identifierVariable, columnName, false, null, null, mapping.getJdbcMapping(), factory));
    }
    if (arguments != null) {
        // So we add a filter to the outer query so we can extract the rank
        switch(arguments.size()) {
            case 0:
                break;
            case 1:
                outerQuerySpec.applyPredicate(new ComparisonPredicate(sortingColumns.get(0), ComparisonOperator.EQUAL, (Expression) arguments.get(0)));
                break;
            default:
                outerQuerySpec.applyPredicate(new ComparisonPredicate(new SqlTuple(sortingColumns, null), ComparisonOperator.EQUAL, new SqlTuple((List<? extends Expression>) (List<?>) arguments, null)));
        }
    }
    final QueryPartTableGroup queryPartTableGroup = new QueryPartTableGroup(navigablePath, null, subQuerySpec, identifierVariable, columnNames, false, true, factory);
    outerQuerySpec.getFromClause().addRoot(queryPartTableGroup);
    // Migrate the offset/fetch clause
    outerQuerySpec.setOffsetClauseExpression(subQuerySpec.getOffsetClauseExpression());
    outerQuerySpec.setFetchClauseExpression(subQuerySpec.getFetchClauseExpression(), subQuerySpec.getFetchClauseType());
    subQuerySpec.setOffsetClauseExpression(null);
    subQuerySpec.setFetchClauseExpression(null, null);
    return outerQuerySpec;
}
Also used : JdbcMapping(org.hibernate.metamodel.mapping.JdbcMapping) BasicType(org.hibernate.type.BasicType) CteContainer(org.hibernate.sql.ast.tree.cte.CteContainer) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) HashMap(java.util.HashMap) SortSpecification(org.hibernate.sql.ast.tree.select.SortSpecification) ArrayList(java.util.ArrayList) ExpressionReplacementWalker(org.hibernate.sql.ast.spi.ExpressionReplacementWalker) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) Map(java.util.Map) SqlAstNode(org.hibernate.sql.ast.tree.SqlAstNode) ComparisonOperator(org.hibernate.query.sqm.ComparisonOperator) ReturnableType(org.hibernate.query.ReturnableType) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection) SelfRenderingAggregateFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression) Predicate(org.hibernate.sql.ast.tree.predicate.Predicate) ResolvedSqlSelection(org.hibernate.sql.results.internal.ResolvedSqlSelection) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) NavigablePath(org.hibernate.query.spi.NavigablePath) BasicValuedMapping(org.hibernate.metamodel.mapping.BasicValuedMapping) Expression(org.hibernate.sql.ast.tree.expression.Expression) SqmToSqlAstConverter(org.hibernate.query.sqm.sql.SqmToSqlAstConverter) QueryTransformer(org.hibernate.sql.ast.tree.expression.QueryTransformer) SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) List(java.util.List) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) QueryPartTableGroup(org.hibernate.sql.ast.tree.from.QueryPartTableGroup) Literal(org.hibernate.sql.ast.tree.expression.Literal) SqlTuple(org.hibernate.sql.ast.tree.expression.SqlTuple) Over(org.hibernate.sql.ast.tree.expression.Over) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) Collections(java.util.Collections) SqmPathInterpretation(org.hibernate.query.sqm.sql.internal.SqmPathInterpretation) SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) SelfRenderingAggregateFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression) NavigablePath(org.hibernate.query.spi.NavigablePath) BasicType(org.hibernate.type.BasicType) JdbcMapping(org.hibernate.metamodel.mapping.JdbcMapping) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection) ResolvedSqlSelection(org.hibernate.sql.results.internal.ResolvedSqlSelection) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) Predicate(org.hibernate.sql.ast.tree.predicate.Predicate) ReturnableType(org.hibernate.query.ReturnableType) ExpressionReplacementWalker(org.hibernate.sql.ast.spi.ExpressionReplacementWalker) Literal(org.hibernate.sql.ast.tree.expression.Literal) ResolvedSqlSelection(org.hibernate.sql.results.internal.ResolvedSqlSelection) SqmPathInterpretation(org.hibernate.query.sqm.sql.internal.SqmPathInterpretation) ArrayList(java.util.ArrayList) List(java.util.List) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) QueryPartTableGroup(org.hibernate.sql.ast.tree.from.QueryPartTableGroup) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) BasicValuedMapping(org.hibernate.metamodel.mapping.BasicValuedMapping) SelfRenderingAggregateFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) SortSpecification(org.hibernate.sql.ast.tree.select.SortSpecification) SqlTuple(org.hibernate.sql.ast.tree.expression.SqlTuple) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Example 4 with SelectClause

use of org.hibernate.sql.ast.tree.select.SelectClause in project hibernate-orm by hibernate.

the class AbstractEntityPersister method selectFragment.

@Override
public String selectFragment(String alias, String suffix) {
    final QuerySpec rootQuerySpec = new QuerySpec(true);
    final String rootTableName = getRootTableName();
    final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState(rootQuerySpec, new SqlAliasBaseManager(), new SimpleFromClauseAccessImpl(), LockOptions.NONE, (fetchParent, querySpec, creationState) -> {
        final List<Fetch> fetches = new ArrayList<>();
        fetchParent.getReferencedMappingContainer().visitFetchables(fetchable -> {
            // Ignore plural attributes
            if (fetchable instanceof PluralAttributeMapping) {
                return;
            }
            FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming();
            final boolean selectable;
            if (fetchable instanceof StateArrayContributorMapping) {
                final int propertyNumber = ((StateArrayContributorMapping) fetchable).getStateArrayPosition();
                final int tableNumber = getSubclassPropertyTableNumber(propertyNumber);
                selectable = !isSubclassTableSequentialSelect(tableNumber) && propertySelectable[propertyNumber];
            } else {
                selectable = true;
            }
            if (fetchable instanceof BasicValuedModelPart) {
                // Ignore lazy basic columns
                if (fetchTiming == FetchTiming.DELAYED) {
                    return;
                }
            } else if (fetchable instanceof Association) {
                final Association association = (Association) fetchable;
                // Ignore the fetchable if the FK is on the other side
                if (association.getSideNature() == ForeignKeyDescriptor.Nature.TARGET) {
                    return;
                }
                // Ensure the FK comes from the root table
                if (!rootTableName.equals(association.getForeignKeyDescriptor().getKeyTable())) {
                    return;
                }
                fetchTiming = FetchTiming.DELAYED;
            }
            if (selectable) {
                final NavigablePath navigablePath = fetchParent.resolveNavigablePath(fetchable);
                final Fetch fetch = fetchParent.generateFetchableFetch(fetchable, navigablePath, fetchTiming, true, null, creationState);
                fetches.add(fetch);
            }
        }, null);
        return fetches;
    }, true, getFactory());
    final NavigablePath entityPath = new NavigablePath(getRootPathName());
    final TableGroup rootTableGroup = createRootTableGroup(true, entityPath, null, () -> p -> {
    }, new SqlAliasBaseConstant(alias), sqlAstCreationState.getSqlExpressionResolver(), sqlAstCreationState.getFromClauseAccess(), getFactory());
    rootQuerySpec.getFromClause().addRoot(rootTableGroup);
    sqlAstCreationState.getFromClauseAccess().registerTableGroup(entityPath, rootTableGroup);
    createDomainResult(entityPath, rootTableGroup, null, sqlAstCreationState);
    // Wrap expressions with aliases
    final SelectClause selectClause = rootQuerySpec.getSelectClause();
    final List<SqlSelection> sqlSelections = selectClause.getSqlSelections();
    int i = 0;
    for (String identifierAlias : identifierAliases) {
        sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), identifierAlias + suffix)));
        i++;
    }
    if (entityMetamodel.hasSubclasses()) {
        sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), getDiscriminatorAlias() + suffix)));
        i++;
    }
    if (hasRowId()) {
        sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), ROWID_ALIAS + suffix)));
        i++;
    }
    final String[] columnAliases = getSubclassColumnAliasClosure();
    final String[] formulaAliases = getSubclassFormulaAliasClosure();
    int columnIndex = 0;
    int formulaIndex = 0;
    for (; i < sqlSelections.size(); i++) {
        final SqlSelection sqlSelection = sqlSelections.get(i);
        final ColumnReference columnReference = (ColumnReference) sqlSelection.getExpression();
        final String selectAlias;
        if (!columnReference.isColumnExpressionFormula()) {
            // Skip over columns that are not selectable like in the fetch generation
            while (!subclassColumnSelectableClosure[columnIndex]) {
                columnIndex++;
            }
            selectAlias = columnAliases[columnIndex++] + suffix;
        } else {
            selectAlias = formulaAliases[formulaIndex++] + suffix;
        }
        sqlSelections.set(i, new SqlSelectionImpl(sqlSelection.getValuesArrayPosition(), sqlSelection.getJdbcResultSetIndex(), new AliasedExpression(sqlSelection.getExpression(), selectAlias)));
    }
    final String sql = getFactory().getJdbcServices().getDialect().getSqlAstTranslatorFactory().buildSelectTranslator(getFactory(), new SelectStatement(rootQuerySpec)).translate(null, QueryOptions.NONE).getSql();
    final int fromIndex = sql.lastIndexOf(" from");
    final String expression;
    if (fromIndex != -1) {
        expression = sql.substring("select ".length(), fromIndex);
    } else {
        expression = sql.substring("select ".length());
    }
    return expression;
}
Also used : SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) NavigablePath(org.hibernate.query.spi.NavigablePath) ArrayList(java.util.ArrayList) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) SqlAliasBaseManager(org.hibernate.sql.ast.spi.SqlAliasBaseManager) SqlAliasBaseConstant(org.hibernate.sql.ast.spi.SqlAliasBaseConstant) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection) AliasedExpression(org.hibernate.sql.ast.tree.expression.AliasedExpression) Fetch(org.hibernate.sql.results.graph.Fetch) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) Association(org.hibernate.metamodel.mapping.Association) StandardTableGroup(org.hibernate.sql.ast.tree.from.StandardTableGroup) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) BasicValuedModelPart(org.hibernate.metamodel.mapping.BasicValuedModelPart) SimpleFromClauseAccessImpl(org.hibernate.sql.ast.spi.SimpleFromClauseAccessImpl) StateArrayContributorMapping(org.hibernate.metamodel.mapping.StateArrayContributorMapping) LoaderSqlAstCreationState(org.hibernate.loader.ast.internal.LoaderSqlAstCreationState) FetchTiming(org.hibernate.engine.FetchTiming) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Example 5 with SelectClause

use of org.hibernate.sql.ast.tree.select.SelectClause in project hibernate-orm by hibernate.

the class SqlAstQueryPartProcessingStateImpl method resolveSqlSelection.

@Override
public SqlSelection resolveSqlSelection(Expression expression, JavaType<?> javaType, TypeConfiguration typeConfiguration) {
    final SqlSelection existing;
    if (sqlSelectionMap == null) {
        sqlSelectionMap = new HashMap<>();
        existing = null;
    } else {
        existing = sqlSelectionMap.get(expression);
    }
    if (existing != null && deduplicateSelectionItems) {
        return existing;
    }
    final SelectClause selectClause = ((QuerySpec) queryPart).getSelectClause();
    final int valuesArrayPosition = selectClause.getSqlSelections().size();
    final SqlSelection sqlSelection = expression.createSqlSelection(valuesArrayPosition + 1, valuesArrayPosition, javaType, typeConfiguration);
    sqlSelectionMap.put(expression, sqlSelection);
    selectClause.addSqlSelection(sqlSelection);
    return sqlSelection;
}
Also used : SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection)

Aggregations

SelectClause (org.hibernate.sql.ast.tree.select.SelectClause)10 SqlSelection (org.hibernate.sql.ast.spi.SqlSelection)7 ColumnReference (org.hibernate.sql.ast.tree.expression.ColumnReference)6 QuerySpec (org.hibernate.sql.ast.tree.select.QuerySpec)6 SqlSelectionImpl (org.hibernate.sql.results.internal.SqlSelectionImpl)6 NavigablePath (org.hibernate.query.spi.NavigablePath)5 TableGroup (org.hibernate.sql.ast.tree.from.TableGroup)5 SelectStatement (org.hibernate.sql.ast.tree.select.SelectStatement)5 Expression (org.hibernate.sql.ast.tree.expression.Expression)4 ArrayList (java.util.ArrayList)3 PluralAttributeMapping (org.hibernate.metamodel.mapping.PluralAttributeMapping)3 SqmSelectStatement (org.hibernate.query.sqm.tree.select.SqmSelectStatement)3 SqlAliasBaseManager (org.hibernate.sql.ast.spi.SqlAliasBaseManager)3 SqlTuple (org.hibernate.sql.ast.tree.expression.SqlTuple)3 Collections (java.util.Collections)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 FetchTiming (org.hibernate.engine.FetchTiming)2 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)2