use of com.blazebit.persistence.impl.query.EntityFunctionNode in project blaze-persistence by Blazebit.
the class PaginatedCriteriaBuilderImpl method getIdQuery.
private TypedQuery<Object[]> getIdQuery(String idQueryString, boolean normalQueryMode, Set<JoinNode> keyRestrictedLeftJoins, List<JoinNode> entityFunctions) {
if (normalQueryMode && isEmpty(keyRestrictedLeftJoins, ID_QUERY_CLAUSE_EXCLUSIONS)) {
TypedQuery<Object[]> idQuery = em.createQuery(idQueryString, Object[].class);
if (isCacheable()) {
mainQuery.jpaProvider.setCacheable(idQuery);
}
if (firstResult < maximumCount && withCountQuery && withInlineCountQuery && maximumCount != Long.MAX_VALUE) {
parameterManager.parameterizeQuery(idQuery, getDualNodeAlias());
idQuery.setParameter(getDualNodeAlias() + "_value_0", 0L);
} else {
parameterManager.parameterizeQuery(idQuery);
}
return parameterManager.getCriteriaNameMapping() == null ? idQuery : new TypedQueryWrapper<>(idQuery, parameterManager.getCriteriaNameMapping());
}
TypedQuery<Object[]> baseQuery = em.createQuery(idQueryString, Object[].class);
Set<String> parameterListNames = parameterManager.getParameterListNames(baseQuery);
List<String> keyRestrictedLeftJoinAliases = getKeyRestrictedLeftJoinAliases(baseQuery, keyRestrictedLeftJoins, ID_QUERY_CLAUSE_EXCLUSIONS);
List<EntityFunctionNode> entityFunctionNodes = getEntityFunctionNodes(baseQuery, entityFunctions);
boolean shouldRenderCteNodes = renderCteNodes(false);
List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(false) : Collections.EMPTY_LIST;
QuerySpecification querySpecification = new CustomQuerySpecification(this, baseQuery, parameterManager.getParameterImpls(), parameterListNames, null, null, keyRestrictedLeftJoinAliases, entityFunctionNodes, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled(), null);
CustomSQLTypedQuery<Object[]> idQuery = new CustomSQLTypedQuery<Object[]>(querySpecification, baseQuery, parameterManager.getCriteriaNameMapping(), parameterManager.getTransformers(), parameterManager.getValuesParameters(), parameterManager.getValuesBinders());
if (firstResult < maximumCount && withCountQuery && withInlineCountQuery && maximumCount != Long.MAX_VALUE) {
parameterManager.parameterizeQuery(idQuery, getDualNodeAlias());
idQuery.setParameter(getDualNodeAlias() + "_value_0", 0L);
} else {
parameterManager.parameterizeQuery(idQuery);
}
return idQuery;
}
use of com.blazebit.persistence.impl.query.EntityFunctionNode in project blaze-persistence by Blazebit.
the class AbstractCommonQueryBuilder method getTypedQuery.
protected TypedQuery<QueryResultType> getTypedQuery(StringBuilder lateralSb, JoinNode lateralJoinNode) {
// NOTE: This must happen first because it generates implicit joins
String baseQueryString = getBaseQueryStringWithCheck(lateralSb, lateralJoinNode);
// We can only use the query directly if we have no ctes, entity functions or hibernate bugs
Set<JoinNode> keyRestrictedLeftJoins = getKeyRestrictedLeftJoins();
final boolean needsSqlReplacement = isMainQuery && mainQuery.cteManager.hasCtes() || joinManager.hasEntityFunctions() || !keyRestrictedLeftJoins.isEmpty() || !isMainQuery && hasLimit();
if (!needsSqlReplacement) {
TypedQuery<QueryResultType> query = (TypedQuery<QueryResultType>) em.createQuery(baseQueryString, selectManager.getExpectedQueryResultType());
if (firstResult != 0) {
query.setFirstResult(firstResult);
}
if (maxResults != Integer.MAX_VALUE) {
query.setMaxResults(maxResults);
}
if (isCacheable()) {
mainQuery.jpaProvider.setCacheable(query);
}
parameterManager.parameterizeQuery(query);
return applyObjectBuilder(query);
}
TypedQuery<QueryResultType> baseQuery = (TypedQuery<QueryResultType>) em.createQuery(baseQueryString, selectManager.getExpectedQueryResultType());
if (isCacheable()) {
mainQuery.jpaProvider.setCacheable(baseQuery);
}
Set<String> parameterListNames = parameterManager.getParameterListNames(baseQuery);
String limit = null;
String offset = null;
// The main query will handle that separately
if (!isMainQuery && lateralSb == null) {
if (firstResult != 0) {
offset = Integer.toString(firstResult);
}
if (maxResults != Integer.MAX_VALUE) {
limit = Integer.toString(maxResults);
}
}
List<String> keyRestrictedLeftJoinAliases = getKeyRestrictedLeftJoinAliases(baseQuery, keyRestrictedLeftJoins, Collections.<ClauseType>emptySet());
List<EntityFunctionNode> entityFunctionNodes = getEntityFunctionNodes(baseQuery);
boolean shouldRenderCteNodes = lateralSb == null && renderCteNodes(false);
List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(false) : Collections.<CTENode>emptyList();
QuerySpecification querySpecification = new CustomQuerySpecification(this, baseQuery, parameterManager.getParameterImpls(), parameterListNames, limit, offset, keyRestrictedLeftJoinAliases, entityFunctionNodes, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled(), null);
TypedQuery<QueryResultType> query = new CustomSQLTypedQuery<QueryResultType>(querySpecification, baseQuery, parameterManager.getCriteriaNameMapping(), parameterManager.getTransformers(), parameterManager.getValuesParameters(), parameterManager.getValuesBinders());
// The main query will use the native mechanism for limit/offset
if (isMainQuery && lateralSb == null) {
if (firstResult != 0) {
query.setFirstResult(firstResult);
}
if (maxResults != Integer.MAX_VALUE) {
query.setMaxResults(maxResults);
}
}
parameterManager.parameterizeQuery(query);
return applyObjectBuilder(query);
}
use of com.blazebit.persistence.impl.query.EntityFunctionNode in project blaze-persistence by Blazebit.
the class AbstractFullQueryBuilder method getCountQuery.
protected TypedQuery<Long> getCountQuery(String countQueryString, boolean useCountWrapper) {
// We can only use the query directly if we have no ctes, entity functions or hibernate bugs
Set<JoinNode> keyRestrictedLeftJoins = getKeyRestrictedLeftJoins();
Set<JoinNode> alwaysIncludedNodes = getIdentifierExpressionsToUseNonRootJoinNodes();
List<JoinNode> entityFunctions = null;
boolean normalQueryMode = !useCountWrapper && (!isMainQuery || (!mainQuery.cteManager.hasCtes() && (entityFunctions = joinManager.getEntityFunctions(COUNT_QUERY_GROUP_BY_CLAUSE_EXCLUSIONS, true, alwaysIncludedNodes)).isEmpty() && keyRestrictedLeftJoins.isEmpty()));
Collection<Parameter<?>> parameters;
Map<String, String> valuesParameters;
Map<String, ValuesParameterBinder> valuesBinders;
JoinNode dualNode = null;
if (cachedMaximumCount == Long.MAX_VALUE) {
if (normalQueryMode && isEmpty(keyRestrictedLeftJoins, COUNT_QUERY_CLAUSE_EXCLUSIONS)) {
TypedQuery<Long> countQuery = em.createQuery(countQueryString, Long.class);
if (isCacheable()) {
mainQuery.jpaProvider.setCacheable(countQuery);
}
parameterManager.parameterizeQuery(countQuery);
return parameterManager.getCriteriaNameMapping() == null ? countQuery : new TypedQueryWrapper<>(countQuery, parameterManager.getCriteriaNameMapping());
}
parameters = (Collection<Parameter<?>>) (Collection<?>) parameterManager.getParameterImpls();
valuesParameters = parameterManager.getValuesParameters();
valuesBinders = parameterManager.getValuesBinders();
} else {
parameters = new ArrayList<>(parameterManager.getParameters());
valuesParameters = new HashMap<>(parameterManager.getValuesParameters());
valuesBinders = parameterManager.getValuesBinders();
dualNode = createDualNode();
entityFunctions = new ArrayList<>();
entityFunctions.add(dualNode);
String valueParameterName = dualNode.getAlias() + "_value_0";
String[][] parameterNames = new String[1][1];
parameterNames[0][0] = valueParameterName;
ParameterManager.ValuesParameterWrapper valuesParameterWrapper = new ParameterManager.ValuesParameterWrapper(dualNode.getJavaType(), parameterNames, new AttributeAccessor[1]);
parameters.add(new ParameterManager.ParameterImpl<Object>(dualNode.getAlias(), false, null, null, valuesParameterWrapper));
valuesParameters.put(valueParameterName, dualNode.getAlias());
valuesBinders.put(dualNode.getAlias(), valuesParameterWrapper.getBinder());
}
if (entityFunctions == null) {
entityFunctions = joinManager.getEntityFunctions(COUNT_QUERY_GROUP_BY_CLAUSE_EXCLUSIONS, true, alwaysIncludedNodes);
}
Query baseQuery = em.createQuery(countQueryString);
Set<String> parameterListNames = parameterManager.getParameterListNames(baseQuery);
String limit = null;
String offset = null;
if (firstResult != 0) {
offset = Integer.toString(firstResult);
}
if (maxResults != Integer.MAX_VALUE) {
limit = Integer.toString(maxResults);
}
List<String> keyRestrictedLeftJoinAliases = getKeyRestrictedLeftJoinAliases(baseQuery, keyRestrictedLeftJoins, COUNT_QUERY_CLAUSE_EXCLUSIONS);
List<EntityFunctionNode> entityFunctionNodes;
if (dualNode == null) {
entityFunctionNodes = getEntityFunctionNodes(baseQuery, entityFunctions);
} else {
entityFunctionNodes = getEntityFunctionNodes(baseQuery, entityFunctions, Collections.<JoinNode>emptyList(), false);
}
boolean shouldRenderCteNodes = renderCteNodes(false);
List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(false) : Collections.EMPTY_LIST;
QuerySpecification querySpecification = new CustomQuerySpecification(this, baseQuery, parameters, parameterListNames, limit, offset, keyRestrictedLeftJoinAliases, entityFunctionNodes, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled(), useCountWrapper ? getCountExampleQuery() : null);
CustomSQLTypedQuery<Long> countQuery = new CustomSQLTypedQuery<>(querySpecification, baseQuery, parameterManager.getCriteriaNameMapping(), parameterManager.getTransformers(), valuesParameters, valuesBinders);
if (dualNode == null) {
parameterManager.parameterizeQuery(countQuery);
} else {
parameterManager.parameterizeQuery(countQuery, dualNode.getAlias());
countQuery.setParameter(dualNode.getAlias(), Collections.singleton(0L));
}
return countQuery;
}
use of com.blazebit.persistence.impl.query.EntityFunctionNode in project blaze-persistence by Blazebit.
the class AbstractInsertCollectionCriteriaBuilder method getQuerySpecification.
private <R> QuerySpecification getQuerySpecification(Query baseQuery, Query exampleQuery, String[] returningColumns, ReturningObjectBuilder<R> objectBuilder, Map<DbmsModificationState, String> includedModificationStates) {
Set<String> parameterListNames = parameterManager.getParameterListNames(baseQuery);
Set<JoinNode> keyRestrictedLeftJoins = getKeyRestrictedLeftJoins();
List<String> keyRestrictedLeftJoinAliases = getKeyRestrictedLeftJoinAliases(baseQuery, keyRestrictedLeftJoins, Collections.EMPTY_SET);
List<EntityFunctionNode> entityFunctionNodes = getEntityFunctionNodes(baseQuery);
boolean isEmbedded = this instanceof ReturningBuilder;
boolean shouldRenderCteNodes = renderCteNodes(isEmbedded);
List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(isEmbedded) : Collections.EMPTY_LIST;
ExtendedQuerySupport extendedQuerySupport = getService(ExtendedQuerySupport.class);
Query insertExampleQuery = getInsertExampleQuery();
String insertExampleSql = extendedQuerySupport.getSql(em, insertExampleQuery);
String ownerAlias = extendedQuerySupport.getSqlAlias(em, insertExampleQuery, entityAlias);
String targetAlias = extendedQuerySupport.getSqlAlias(em, insertExampleQuery, JoinManager.COLLECTION_DML_BASE_QUERY_ALIAS);
JoinTable joinTable = mainQuery.jpaProvider.getJoinTable(entityType, collectionName);
int joinTableIndex = SqlUtils.indexOfTableName(insertExampleSql, joinTable.getTableName());
String collectionAlias = SqlUtils.extractAlias(insertExampleSql, joinTableIndex + joinTable.getTableName().length());
String[] selectItemExpressions = SqlUtils.getSelectItemExpressions(insertExampleSql, SqlUtils.indexOfSelect(insertExampleSql));
// Prepare a Map<EntityAlias.idColumnName, CollectionAlias.idColumnName>
// This is used to replace references to id columns properly in the final sql query
Map<String, String> columnExpressionRemappings = new HashMap<>(selectItemExpressions.length);
String[] discriminatorColumnCheck = mainQuery.jpaProvider.getDiscriminatorColumnCheck(entityType);
if (discriminatorColumnCheck != null) {
columnExpressionRemappings.put(ownerAlias + "." + discriminatorColumnCheck[0] + "=" + discriminatorColumnCheck[1], "1=1");
}
if (joinTable.getKeyColumnMappings() != null) {
for (Map.Entry<String, String> entry : joinTable.getKeyColumnMappings().entrySet()) {
columnExpressionRemappings.put(collectionAlias + "." + entry.getValue(), entry.getKey());
}
}
for (Map.Entry<String, String> entry : joinTable.getIdColumnMappings().entrySet()) {
columnExpressionRemappings.put(ownerAlias + "." + entry.getValue(), entry.getKey());
}
for (Map.Entry<String, String> entry : joinTable.getTargetColumnMappings().entrySet()) {
columnExpressionRemappings.put(targetAlias + "." + entry.getValue(), entry.getKey());
}
int cutoffColumns = 0;
StringBuilder insertSqlSb = new StringBuilder();
insertSqlSb.append("insert into ").append(joinTable.getTableName()).append("(");
for (String selectItemExpression : selectItemExpressions) {
String columnExpression = columnExpressionRemappings.get(selectItemExpression.trim());
// It should never be null, but the workaround for https://hibernate.atlassian.net/browse/HHH-13045 requires us to filter out the entity fetch columns
if (columnExpression == null) {
cutoffColumns++;
} else {
insertSqlSb.append(columnExpression).append(',');
}
}
insertSqlSb.setCharAt(insertSqlSb.length() - 1, ')');
return new CollectionInsertModificationQuerySpecification(this, baseQuery, exampleQuery, parameterManager.getParameterImpls(), parameterListNames, keyRestrictedLeftJoinAliases, entityFunctionNodes, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, isEmbedded, returningColumns, objectBuilder, includedModificationStates, returningAttributeBindingMap, getInsertExecutorQuery(), insertSqlSb.toString(), cutoffColumns, getForeignKeyParticipatingQueries(), mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled());
}
use of com.blazebit.persistence.impl.query.EntityFunctionNode in project blaze-persistence by Blazebit.
the class AbstractCTECriteriaBuilder method getQuery.
protected Query getQuery(String baseQueryString) {
Set<JoinNode> keyRestrictedLeftJoins = getKeyRestrictedLeftJoins();
Query query;
if (hasLimit() || joinManager.hasEntityFunctions() || !keyRestrictedLeftJoins.isEmpty()) {
// We need to change the underlying sql when doing a limit
query = em.createQuery(baseQueryString);
Set<String> parameterListNames = parameterManager.getParameterListNames(query);
String limit = null;
String offset = null;
// The main query will handle that separately
if (!isMainQuery) {
if (firstResult != 0) {
query.setFirstResult(firstResult);
offset = Integer.toString(firstResult);
}
if (maxResults != Integer.MAX_VALUE) {
query.setMaxResults(maxResults);
limit = Integer.toString(maxResults);
}
}
List<String> keyRestrictedLeftJoinAliases = getKeyRestrictedLeftJoinAliases(query, keyRestrictedLeftJoins, Collections.<ClauseType>emptySet());
List<EntityFunctionNode> entityFunctionNodes = getEntityFunctionNodes(query);
QuerySpecification querySpecification = new CTEQuerySpecification(this, query, parameterManager.getParameterImpls(), parameterListNames, limit, offset, keyRestrictedLeftJoinAliases, entityFunctionNodes);
query = new CustomSQLQuery(querySpecification, query, parameterManager.getCriteriaNameMapping(), parameterManager.getTransformers(), parameterManager.getValuesParameters(), parameterManager.getValuesBinders());
} else {
query = em.createQuery(baseQueryString);
if (parameterManager.getCriteriaNameMapping() != null) {
query = new QueryWrapper(query, parameterManager.getCriteriaNameMapping());
}
}
parameterManager.parameterizeQuery(query);
return query;
}
Aggregations