Search in sources :

Example 11 with StringLiteral

use of com.blazebit.persistence.parser.expression.StringLiteral in project blaze-persistence by Blazebit.

the class TestLiterals method testCharacterLiteral.

@Test
public void testCharacterLiteral() {
    StringLiteral result = (StringLiteral) parse("'a'");
    assertEquals(new StringLiteral("a"), result);
}
Also used : StringLiteral(com.blazebit.persistence.parser.expression.StringLiteral) Test(org.junit.Test)

Example 12 with StringLiteral

use of com.blazebit.persistence.parser.expression.StringLiteral in project blaze-persistence by Blazebit.

the class TestLiterals method testStringLiteralWithBackslash.

@Test
public void testStringLiteralWithBackslash() {
    StringLiteral result = (StringLiteral) parse("'a\\_'");
    assertEquals(new StringLiteral("a\\_"), result);
}
Also used : StringLiteral(com.blazebit.persistence.parser.expression.StringLiteral) Test(org.junit.Test)

Example 13 with StringLiteral

use of com.blazebit.persistence.parser.expression.StringLiteral in project blaze-persistence by Blazebit.

the class SizeTransformationVisitor method getSizeExpression.

private Expression getSizeExpression(ExpressionModifier parentModifier, PathExpression sizeArg) {
    JoinNode sizeArgJoin = (JoinNode) sizeArg.getBaseNode();
    String property = sizeArg.getPathReference().getField();
    final Type<?> nodeType = ((JoinNode) sizeArg.getBaseNode()).getNodeType();
    if (!(nodeType instanceof EntityType<?>)) {
        throw new IllegalArgumentException("Size on a collection owned by a non-entity type is not supported yet: " + sizeArg);
    }
    final EntityType<?> startType = (EntityType<?>) nodeType;
    AttributeHolder result = JpaUtils.getAttributeForJoining(metamodel, sizeArg);
    PluralAttribute<?, ?, ?> targetAttribute = (PluralAttribute<?, ?, ?>) result.getAttribute();
    if (targetAttribute == null) {
        throw new RuntimeException("Attribute [" + property + "] not found on class " + startType.getJavaType().getName());
    }
    final PluralAttribute.CollectionType collectionType = targetAttribute.getCollectionType();
    final boolean isElementCollection = jpaProvider.getJpaMetamodelAccessor().isElementCollection(targetAttribute);
    boolean subqueryRequired;
    if (isElementCollection) {
        subqueryRequired = false;
    } else {
        ManagedType<?> managedTargetType = (ManagedType<?>) result.getAttributeType();
        if (managedTargetType instanceof EntityType<?>) {
            // we could also generate counts for collections with embeddable id but we do not implement this for now
            subqueryRequired = ((EntityType<?>) managedTargetType).getIdType().getPersistenceType() == PersistenceType.EMBEDDABLE;
        } else {
            throw new RuntimeException("Path [" + sizeArg.toString() + "] does not refer to a collection");
        }
    }
    // build group by id clause
    List<PathExpression> groupByExprs = new ArrayList<>();
    for (SingularAttribute<?, ?> idAttribute : JpaMetamodelUtils.getIdAttributes(startType)) {
        List<PathElementExpression> pathElementExpr = new ArrayList<>(2);
        pathElementExpr.add(new PropertyExpression(sizeArgJoin.getAlias()));
        pathElementExpr.add(new PropertyExpression(idAttribute.getName()));
        PathExpression groupByExpr = new PathExpression(pathElementExpr);
        groupByExprs.add(groupByExpr);
    }
    subqueryRequired = subqueryRequired || // we could also generate counts for collections with IdClass attributes but we do not implement this for now
    !startType.hasSingleIdAttribute() || joinManager.getRoots().size() > 1 || clause == ClauseType.JOIN || !isCountTransformationEnabled() || // for now, we always generate a subquery when a bag is encountered
    jpaProvider.isBag((EntityType<?>) targetAttribute.getDeclaringType(), targetAttribute.getName()) || requiresBlacklistedNode(sizeArg) || aggregateFunctionContext;
    if (subqueryRequired) {
        return wrapSubqueryConditionally(generateSubquery(sizeArg), aggregateFunctionContext);
    } else {
        if (currentJoinNode != null && (!currentJoinNode.equals(sizeArgJoin))) {
            int currentJoinDepth = currentJoinNode.getJoinDepth();
            int sizeArgJoinDepth = sizeArgJoin.getJoinDepth();
            if (currentJoinDepth > sizeArgJoinDepth) {
                return wrapSubqueryConditionally(generateSubquery(sizeArg), aggregateFunctionContext);
            } else {
                // we have to change all transformed expressions to subqueries
                for (TransformedExpressionEntry transformedExpressionEntry : transformedExpressions) {
                    PathExpression originalSizeArg = transformedExpressionEntry.getOriginalSizeArg();
                    Expression subquery = wrapSubqueryConditionally(generateSubquery(originalSizeArg), transformedExpressionEntry.isAggregateFunctionContext());
                    transformedExpressionEntry.getParentModifier().set(subquery);
                }
                transformedExpressions.clear();
                requiredGroupBys.clear();
                lateJoins.clear();
                distinctRequired = false;
                if (currentJoinDepth == sizeArgJoinDepth) {
                    return wrapSubqueryConditionally(generateSubquery(sizeArg), aggregateFunctionContext);
                }
            }
        }
        for (PathExpression groupByExpr : groupByExprs) {
            joinManager.implicitJoin(groupByExpr, true, true, true, null, null, new HashSet<String>(), false, false, false, false);
        }
        PathExpression originalSizeArg = sizeArg.copy(ExpressionCopyContext.EMPTY);
        originalSizeArg.setPathReference(sizeArg.getPathReference());
        sizeArg.setUsedInCollectionFunction(false);
        List<Expression> countArguments = new ArrayList<>();
        String joinLookupKey = getJoinLookupKey(sizeArg);
        LateJoinEntry lateJoin = lateJoins.get(joinLookupKey);
        if (lateJoin == null) {
            lateJoin = new LateJoinEntry();
            lateJoins.put(joinLookupKey, lateJoin);
        }
        lateJoin.getExpressionsToJoin().add(sizeArg);
        lateJoin.getClauseDependencies().add(clause);
        if ((isElementCollection && collectionType != PluralAttribute.CollectionType.MAP) || collectionType == PluralAttribute.CollectionType.SET) {
            if (IDENTIFIABLE_PERSISTENCE_TYPES.contains(targetAttribute.getElementType().getPersistenceType()) && targetAttribute.isCollection()) {
                // append id attribute name of joinable size argument
                PluralAttribute<?, ?, ?> sizeArgTargetAttribute = (PluralAttribute<?, ?, ?>) JpaMetamodelUtils.getAttribute(startType, sizeArg.getPathReference().getField());
                for (Attribute<?, ?> idAttribute : JpaMetamodelUtils.getIdAttributes(((IdentifiableType<?>) sizeArgTargetAttribute.getElementType()))) {
                    List<PathElementExpression> pathElementExpressions = new ArrayList<>(sizeArg.getExpressions().size() + 1);
                    pathElementExpressions.addAll(sizeArg.getExpressions());
                    pathElementExpressions.add(new PropertyExpression(idAttribute.getName()));
                    PathExpression pathExpression = new PathExpression(pathElementExpressions);
                    countArguments.add(pathExpression);
                    lateJoin.getExpressionsToJoin().add(pathExpression);
                }
            } else {
                countArguments.add(sizeArg);
            }
        } else {
            sizeArg.setCollectionQualifiedPath(true);
            if (collectionType == PluralAttribute.CollectionType.LIST) {
                countArguments.add(new ListIndexExpression(sizeArg));
            } else {
                countArguments.add(new MapKeyExpression(sizeArg));
            }
        }
        AggregateExpression countExpr = createCountFunction(distinctRequired, countArguments);
        transformedExpressions.add(new TransformedExpressionEntry(countExpr, originalSizeArg, parentModifier, aggregateFunctionContext));
        currentJoinNode = (JoinNode) originalSizeArg.getBaseNode();
        if (!distinctRequired) {
            if (lateJoins.size() + joinManager.getCollectionJoins().size() > 1) {
                distinctRequired = true;
                /*
                     *  As soon as we encounter another collection join, set previously
                     *  performed transformations to distinct.
                     */
                for (TransformedExpressionEntry transformedExpressionEntry : transformedExpressions) {
                    AggregateExpression transformedExpr = transformedExpressionEntry.getTransformedExpression();
                    if (ExpressionUtils.isCustomFunctionInvocation(transformedExpr) && AbstractCountFunction.FUNCTION_NAME.equalsIgnoreCase(((StringLiteral) transformedExpr.getExpressions().get(0)).getValue())) {
                        Expression possibleDistinct = transformedExpr.getExpressions().get(1);
                        if (!(possibleDistinct instanceof StringLiteral) || !AbstractCountFunction.DISTINCT_QUALIFIER.equals(((StringLiteral) possibleDistinct).getValue())) {
                            transformedExpr.getExpressions().add(1, new StringLiteral(AbstractCountFunction.DISTINCT_QUALIFIER));
                        }
                    } else {
                        transformedExpr.setDistinct(true);
                    }
                }
            }
        }
        for (Expression groupByExpr : groupByExprs) {
            String groupByExprString = groupByExpr.toString();
            ResolvedExpression resolvedExpression = new ResolvedExpression(groupByExprString, groupByExpr);
            Set<ClauseType> clauseTypes = requiredGroupBys.get(resolvedExpression);
            if (clauseTypes == null) {
                requiredGroupBys.put(resolvedExpression, EnumSet.of(clause));
            } else {
                clauseTypes.add(clause);
            }
        }
        return countExpr;
    }
}
Also used : ArrayList(java.util.ArrayList) ResolvedExpression(com.blazebit.persistence.impl.ResolvedExpression) MapKeyExpression(com.blazebit.persistence.parser.expression.MapKeyExpression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) ListIndexExpression(com.blazebit.persistence.parser.expression.ListIndexExpression) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression) AttributeHolder(com.blazebit.persistence.impl.AttributeHolder) ManagedType(javax.persistence.metamodel.ManagedType) IdentifiableType(javax.persistence.metamodel.IdentifiableType) PluralAttribute(javax.persistence.metamodel.PluralAttribute) JoinNode(com.blazebit.persistence.impl.JoinNode) AggregateExpression(com.blazebit.persistence.parser.expression.AggregateExpression) EntityType(javax.persistence.metamodel.EntityType) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) StringLiteral(com.blazebit.persistence.parser.expression.StringLiteral) ListIndexExpression(com.blazebit.persistence.parser.expression.ListIndexExpression) Expression(com.blazebit.persistence.parser.expression.Expression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) AggregateExpression(com.blazebit.persistence.parser.expression.AggregateExpression) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression) ResolvedExpression(com.blazebit.persistence.impl.ResolvedExpression) FunctionExpression(com.blazebit.persistence.parser.expression.FunctionExpression) SubqueryExpression(com.blazebit.persistence.parser.expression.SubqueryExpression) MapKeyExpression(com.blazebit.persistence.parser.expression.MapKeyExpression) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) ClauseType(com.blazebit.persistence.impl.ClauseType)

Example 14 with StringLiteral

use of com.blazebit.persistence.parser.expression.StringLiteral in project blaze-persistence by Blazebit.

the class AbstractCommonQueryBuilder method asExpression.

protected Expression asExpression(AbstractCommonQueryBuilder<?, ?, ?, ?, ?> queryBuilder, boolean externalRepresentation, boolean quantifiedPredicate) {
    if (queryBuilder instanceof BaseFinalSetOperationBuilderImpl<?, ?, ?>) {
        return queryBuilder.asExpression(externalRepresentation, quantifiedPredicate);
    }
    final String queryString = queryBuilder.buildBaseQueryString(externalRepresentation);
    Expression expression = new SubqueryExpression(new Subquery() {

        @Override
        public String getQueryString() {
            return queryString;
        }
    });
    if (externalRepresentation) {
        return expression;
    }
    if (queryBuilder.joinManager.hasEntityFunctions()) {
        for (EntityFunctionNode node : queryBuilder.getEntityFunctionNodes(null)) {
            List<Expression> arguments = new ArrayList<>(6);
            arguments.add(new StringLiteral("ENTITY_FUNCTION"));
            arguments.add(expression);
            String subquery = node.getSubquery();
            String aliases = node.getAliases();
            String syntheticPredicate = node.getSyntheticPredicate();
            // TODO: this is a hibernate specific integration detail
            // Replace the subview subselect that is generated for this subselect
            String entityName = node.getEntityName();
            arguments.add(new StringLiteral(entityName));
            arguments.add(new StringLiteral(subquery));
            arguments.add(new StringLiteral(aliases == null ? "" : aliases));
            arguments.add(new StringLiteral(syntheticPredicate == null ? "" : syntheticPredicate));
            expression = new FunctionExpression("FUNCTION", arguments);
        }
    }
    if (queryBuilder.hasLimit()) {
        final boolean hasFirstResult = queryBuilder.getFirstResult() != 0;
        final boolean hasMaxResults = queryBuilder.getMaxResults() != Integer.MAX_VALUE;
        List<Expression> arguments = new ArrayList<>(2);
        arguments.add(new StringLiteral(LimitFunction.FUNCTION_NAME));
        arguments.add(expression);
        if (!hasMaxResults) {
            throw new IllegalArgumentException("First result without max results is not supported!");
        } else {
            arguments.add(new NumericLiteral(Integer.toString(queryBuilder.getMaxResults()), NumericType.INTEGER));
        }
        if (hasFirstResult) {
            arguments.add(new NumericLiteral(Integer.toString(queryBuilder.getFirstResult()), NumericType.INTEGER));
        }
        expression = new FunctionExpression("FUNCTION", arguments);
        if (quantifiedPredicate && !mainQuery.dbmsDialect.supportsLimitInQuantifiedPredicateSubquery()) {
            arguments = new ArrayList<>(2);
            arguments.add(new StringLiteral(QueryWrapperFunction.FUNCTION_NAME));
            arguments.add(expression);
            expression = new FunctionExpression("FUNCTION", arguments);
        }
    }
    return expression;
}
Also used : NumericLiteral(com.blazebit.persistence.parser.expression.NumericLiteral) ArrayList(java.util.ArrayList) Subquery(com.blazebit.persistence.parser.expression.Subquery) SubqueryExpression(com.blazebit.persistence.parser.expression.SubqueryExpression) FunctionExpression(com.blazebit.persistence.parser.expression.FunctionExpression) StringLiteral(com.blazebit.persistence.parser.expression.StringLiteral) ParameterExpression(javax.persistence.criteria.ParameterExpression) ArrayExpression(com.blazebit.persistence.parser.expression.ArrayExpression) FunctionExpression(com.blazebit.persistence.parser.expression.FunctionExpression) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) Expression(com.blazebit.persistence.parser.expression.Expression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression) SubqueryExpression(com.blazebit.persistence.parser.expression.SubqueryExpression) EntityFunctionNode(com.blazebit.persistence.impl.query.EntityFunctionNode)

Example 15 with StringLiteral

use of com.blazebit.persistence.parser.expression.StringLiteral in project blaze-persistence by Blazebit.

the class AbstractFullQueryBuilder method applyPageIdQueryInto.

protected void applyPageIdQueryInto(AbstractCommonQueryBuilder<?, ?, ?, ?, ?> newBuilder, KeysetPage keysetPage, int firstResult, int maxResults, ResolvedExpression[] identifierExpressionsToUse, boolean withAlias) {
    ExpressionCopyContext expressionCopyContext = newBuilder.applyFrom(this, true, false, false, false, ID_QUERY_GROUP_BY_CLAUSE_EXCLUSIONS, getIdentifierExpressionsToUseNonRootJoinNodes(identifierExpressionsToUse), new IdentityHashMap<JoinManager, JoinManager>(), ExpressionCopyContext.EMPTY);
    newBuilder.setFirstResult(firstResult);
    newBuilder.setMaxResults(maxResults);
    // Paginated criteria builders always need the last order by expression to be unique
    List<OrderByExpression> orderByExpressions = orderByManager.getOrderByExpressions(false, whereManager.rootPredicate.getPredicate(), hasGroupBy ? Arrays.asList(getIdentifierExpressions()) : Collections.<ResolvedExpression>emptyList(), null);
    if (!orderByExpressions.get(orderByExpressions.size() - 1).isResultUnique()) {
        throw new IllegalStateException("The order by items of the query builder are not guaranteed to produce unique tuples! Consider also ordering by the entity identifier!");
    }
    if (keysetPage != null) {
        KeysetMode keysetMode = KeysetPaginationHelper.getKeysetMode(keysetPage, null, firstResult, maxResults);
        if (keysetMode == KeysetMode.NONE) {
            newBuilder.keysetManager.setKeysetLink(null);
        } else if (keysetMode == KeysetMode.NEXT) {
            newBuilder.keysetManager.setKeysetLink(new SimpleKeysetLink(keysetPage.getHighest(), keysetMode));
        } else {
            newBuilder.keysetManager.setKeysetLink(new SimpleKeysetLink(keysetPage.getLowest(), keysetMode));
        }
        newBuilder.keysetManager.initialize(orderByExpressions);
    }
    // Applying order by items needs special care for page id queries because we have to re-alias the items to avoid collisions
    Map<String, Integer> identifierExpressionStringMap = new HashMap<>(identifierExpressionsToUse.length);
    for (int i = 0; i < identifierExpressionsToUse.length; i++) {
        identifierExpressionStringMap.put(identifierExpressionsToUse[i].getExpressionString(), i);
    }
    String[] identifierToUseSelectAliases = newBuilder.orderByManager.applyFrom(orderByManager, identifierExpressionStringMap);
    if (withAlias) {
        for (int i = 0; i < identifierExpressionsToUse.length; i++) {
            List<Expression> args = new ArrayList<>(2);
            args.add(identifierExpressionsToUse[i].getExpression().copy(expressionCopyContext));
            args.add(new StringLiteral(ColumnTruncFunction.SYNTHETIC_COLUMN_PREFIX + i));
            newBuilder.selectManager.select(new FunctionExpression(AliasFunction.FUNCTION_NAME, args), identifierToUseSelectAliases[i]);
        }
    } else {
        for (int i = 0; i < identifierExpressionsToUse.length; i++) {
            newBuilder.selectManager.select(identifierExpressionsToUse[i].getExpression().copy(expressionCopyContext), identifierToUseSelectAliases[i]);
        }
    }
}
Also used : IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ExpressionCopyContext(com.blazebit.persistence.parser.expression.ExpressionCopyContext) FunctionExpression(com.blazebit.persistence.parser.expression.FunctionExpression) StringLiteral(com.blazebit.persistence.parser.expression.StringLiteral) Expression(com.blazebit.persistence.parser.expression.Expression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) FunctionExpression(com.blazebit.persistence.parser.expression.FunctionExpression) KeysetMode(com.blazebit.persistence.impl.keyset.KeysetMode) SimpleKeysetLink(com.blazebit.persistence.impl.keyset.SimpleKeysetLink)

Aggregations

StringLiteral (com.blazebit.persistence.parser.expression.StringLiteral)16 FunctionExpression (com.blazebit.persistence.parser.expression.FunctionExpression)11 PathExpression (com.blazebit.persistence.parser.expression.PathExpression)11 Expression (com.blazebit.persistence.parser.expression.Expression)10 ArrayList (java.util.ArrayList)10 PropertyExpression (com.blazebit.persistence.parser.expression.PropertyExpression)9 PathElementExpression (com.blazebit.persistence.parser.expression.PathElementExpression)7 SubqueryExpression (com.blazebit.persistence.parser.expression.SubqueryExpression)7 MapKeyExpression (com.blazebit.persistence.parser.expression.MapKeyExpression)5 ListIndexExpression (com.blazebit.persistence.parser.expression.ListIndexExpression)4 NumericLiteral (com.blazebit.persistence.parser.expression.NumericLiteral)4 Test (org.junit.Test)4 ArrayExpression (com.blazebit.persistence.parser.expression.ArrayExpression)3 ParameterExpression (com.blazebit.persistence.parser.expression.ParameterExpression)3 Subquery (com.blazebit.persistence.parser.expression.Subquery)3 ResolvedExpression (com.blazebit.persistence.impl.ResolvedExpression)2 AggregateExpression (com.blazebit.persistence.parser.expression.AggregateExpression)2 GeneralCaseExpression (com.blazebit.persistence.parser.expression.GeneralCaseExpression)2 MapEntryExpression (com.blazebit.persistence.parser.expression.MapEntryExpression)2 MapValueExpression (com.blazebit.persistence.parser.expression.MapValueExpression)2