Search in sources :

Example 26 with BooleanExpression

use of org.datanucleus.store.rdbms.sql.expression.BooleanExpression in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method compileHaving.

/**
 * Method to compile the having clause of the query into the SQLStatement.
 * @param stmt SELECT statement
 */
protected void compileHaving(SelectStatement stmt) {
    if (compilation.getExprHaving() != null) {
        // Apply any having to the statement
        compileComponent = CompilationComponent.HAVING;
        Expression havingExpr = compilation.getExprHaving();
        Object havingEval = havingExpr.evaluate(this);
        if (!(havingEval instanceof BooleanExpression)) {
            // Non-boolean having clause should be user exception
            throw new NucleusUserException(Localiser.msg("021051", havingExpr));
        }
        stmt.setHaving((BooleanExpression) havingEval);
        compileComponent = null;
    }
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) CaseExpression(org.datanucleus.query.expression.CaseExpression) BooleanSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression) StringExpression(org.datanucleus.store.rdbms.sql.expression.StringExpression) JoinExpression(org.datanucleus.query.expression.JoinExpression) NumericSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.NumericSubqueryExpression) StringSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.StringSubqueryExpression) ClassExpression(org.datanucleus.query.expression.ClassExpression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) MapExpression(org.datanucleus.store.rdbms.sql.expression.MapExpression) SubqueryExpression(org.datanucleus.query.expression.SubqueryExpression) NewObjectExpression(org.datanucleus.store.rdbms.sql.expression.NewObjectExpression) TemporalSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.TemporalSubqueryExpression) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) OrderExpression(org.datanucleus.query.expression.OrderExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) TemporalExpression(org.datanucleus.store.rdbms.sql.expression.TemporalExpression) ArrayExpression(org.datanucleus.query.expression.ArrayExpression) ResultAliasExpression(org.datanucleus.store.rdbms.sql.expression.ResultAliasExpression) CreatorExpression(org.datanucleus.query.expression.CreatorExpression) Expression(org.datanucleus.query.expression.Expression) TypeExpression(org.datanucleus.query.expression.TypeExpression) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) CollectionExpression(org.datanucleus.store.rdbms.sql.expression.CollectionExpression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression) ParameterExpression(org.datanucleus.query.expression.ParameterExpression) ColumnExpression(org.datanucleus.store.rdbms.sql.expression.ColumnExpression) VariableExpression(org.datanucleus.query.expression.VariableExpression) NucleusUserException(org.datanucleus.exceptions.NucleusUserException)

Example 27 with BooleanExpression

use of org.datanucleus.store.rdbms.sql.expression.BooleanExpression in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method processGtExpression.

/* (non-Javadoc)
     * @see org.datanucleus.query.evaluator.AbstractExpressionEvaluator#processGtExpression(org.datanucleus.query.expression.Expression)
     */
@Override
protected Object processGtExpression(Expression expr) {
    SQLExpression right = stack.pop();
    SQLExpression left = stack.pop();
    if (left instanceof ParameterLiteral && !(right instanceof ParameterLiteral)) {
        left = replaceParameterLiteral((ParameterLiteral) left, right.getJavaTypeMapping());
    } else if (right instanceof ParameterLiteral && !(left instanceof ParameterLiteral)) {
        right = replaceParameterLiteral((ParameterLiteral) right, left.getJavaTypeMapping());
    }
    ExpressionUtils.checkAndCorrectExpressionMappingsForBooleanComparison(left, right);
    if (left instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) left);
        left = stack.pop();
    }
    if (right instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) right);
        right = stack.pop();
    }
    BooleanExpression opExpr = left.gt(right);
    stack.push(opExpr);
    return opExpr;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) ParameterLiteral(org.datanucleus.store.rdbms.sql.expression.ParameterLiteral) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression)

Example 28 with BooleanExpression

use of org.datanucleus.store.rdbms.sql.expression.BooleanExpression in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method processEqExpression.

/* (non-Javadoc)
     * @see org.datanucleus.query.evaluator.AbstractExpressionEvaluator#processEqExpression(org.datanucleus.query.expression.Expression)
     */
protected Object processEqExpression(Expression expr) {
    SQLExpression right = stack.pop();
    SQLExpression left = stack.pop();
    if (left instanceof ParameterLiteral && !(right instanceof ParameterLiteral)) {
        left = replaceParameterLiteral((ParameterLiteral) left, right.getJavaTypeMapping());
    } else if (right instanceof ParameterLiteral && !(left instanceof ParameterLiteral)) {
        right = replaceParameterLiteral((ParameterLiteral) right, left.getJavaTypeMapping());
    }
    if (left.isParameter() && right.isParameter()) {
        if (left.isParameter() && left instanceof SQLLiteral && ((SQLLiteral) left).getValue() != null) {
            // Change this parameter to a plain literal
            useParameterExpressionAsLiteral((SQLLiteral) left);
        }
        if (right.isParameter() && right instanceof SQLLiteral && ((SQLLiteral) right).getValue() != null) {
            // Change this parameter to a plain literal
            useParameterExpressionAsLiteral((SQLLiteral) right);
        }
    }
    ExpressionUtils.checkAndCorrectExpressionMappingsForBooleanComparison(left, right);
    if (left instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) left);
        left = stack.pop();
    }
    if (right instanceof UnboundExpression) {
        processUnboundExpression((UnboundExpression) right);
        right = stack.pop();
    }
    // Logic for when one side is cross-joined (variable) and other side not, so transfer to a left outer join
    if (!options.contains(OPTION_EXPLICIT_JOINS)) {
        boolean leftIsCrossJoin = (stmt.getJoinTypeForTable(left.getSQLTable()) == JoinType.CROSS_JOIN);
        boolean rightIsCrossJoin = (stmt.getJoinTypeForTable(right.getSQLTable()) == JoinType.CROSS_JOIN);
        if (leftIsCrossJoin && !rightIsCrossJoin && !(right instanceof SQLLiteral)) {
            // "a == b" and a is cross-joined currently (includes variable) so change to left outer join
            String varName = getAliasForSQLTable(left.getSQLTable());
            JoinType joinType = getRequiredJoinTypeForAlias(varName);
            if (joinType != null) {
                NucleusLogger.QUERY.debug("QueryToSQL.eq variable " + varName + " is mapped to table " + left.getSQLTable() + " was previously bound as CROSS JOIN but changing to " + joinType);
                String leftTblAlias = stmt.removeCrossJoin(left.getSQLTable());
                if (joinType == JoinType.LEFT_OUTER_JOIN) {
                    stmt.join(JoinType.LEFT_OUTER_JOIN, right.getSQLTable(), right.getJavaTypeMapping(), left.getSQLTable().getTable(), leftTblAlias, left.getJavaTypeMapping(), null, left.getSQLTable().getGroupName(), true);
                } else {
                    stmt.join(JoinType.INNER_JOIN, right.getSQLTable(), right.getJavaTypeMapping(), left.getSQLTable().getTable(), leftTblAlias, left.getJavaTypeMapping(), null, left.getSQLTable().getGroupName(), true);
                }
                JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
                SQLExpression opExpr = exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, true));
                stack.push(opExpr);
                return opExpr;
            }
        } else if (!leftIsCrossJoin && rightIsCrossJoin && !(left instanceof SQLLiteral)) {
            // "a == b" and b is cross-joined currently (includes variable) so change to left outer join
            String varName = getAliasForSQLTable(right.getSQLTable());
            JoinType joinType = getRequiredJoinTypeForAlias(varName);
            if (joinType != null) {
                NucleusLogger.QUERY.debug("QueryToSQL.eq variable " + varName + " is mapped to table " + right.getSQLTable() + " was previously bound as CROSS JOIN but changing to " + joinType);
                String rightTblAlias = stmt.removeCrossJoin(right.getSQLTable());
                if (joinType == JoinType.LEFT_OUTER_JOIN) {
                    stmt.join(JoinType.LEFT_OUTER_JOIN, left.getSQLTable(), left.getJavaTypeMapping(), right.getSQLTable().getTable(), rightTblAlias, right.getJavaTypeMapping(), null, right.getSQLTable().getGroupName(), true);
                } else {
                    stmt.join(JoinType.INNER_JOIN, left.getSQLTable(), left.getJavaTypeMapping(), right.getSQLTable().getTable(), rightTblAlias, right.getJavaTypeMapping(), null, right.getSQLTable().getGroupName(), true);
                }
                JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
                SQLExpression opExpr = exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, true));
                stack.push(opExpr);
                return opExpr;
            }
        }
    }
    BooleanExpression opExpr = left.eq(right);
    stack.push(opExpr);
    return opExpr;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) ParameterLiteral(org.datanucleus.store.rdbms.sql.expression.ParameterLiteral) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLLiteral(org.datanucleus.store.rdbms.sql.expression.SQLLiteral) JoinType(org.datanucleus.store.rdbms.sql.SQLJoin.JoinType) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression)

Example 29 with BooleanExpression

use of org.datanucleus.store.rdbms.sql.expression.BooleanExpression in project datanucleus-rdbms by datanucleus.

the class QueryToSQLMapper method processBitAndExpression.

/* (non-Javadoc)
     * @see org.datanucleus.query.evaluator.AbstractExpressionEvaluator#processBitAndExpression(org.datanucleus.query.expression.Expression)
     */
@Override
protected Object processBitAndExpression(Expression expr) {
    SQLExpression rightExpr = stack.pop();
    SQLExpression leftExpr = stack.pop();
    if (rightExpr instanceof BooleanExpression && leftExpr instanceof BooleanExpression) {
        // Handle as Boolean logical AND
        stack.push(leftExpr);
        stack.push(rightExpr);
        return processAndExpression(expr);
    } else if (rightExpr instanceof NumericExpression && leftExpr instanceof NumericExpression) {
        if (storeMgr.getDatastoreAdapter().supportsOption(DatastoreAdapter.OPERATOR_BITWISE_AND)) {
            SQLExpression bitAndExpr = new NumericExpression(leftExpr, Expression.OP_BIT_AND, rightExpr).encloseInParentheses();
            stack.push(bitAndExpr);
            return bitAndExpr;
        }
    }
    throw new NucleusUserException("Operation BITWISE AND is not supported for " + leftExpr + " and " + rightExpr + " for this datastore");
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression)

Example 30 with BooleanExpression

use of org.datanucleus.store.rdbms.sql.expression.BooleanExpression in project datanucleus-rdbms by datanucleus.

the class SQLStatement method getJoinConditionForJoin.

/**
 * Convenience method to generate the join condition between source and target tables for the supplied mappings.
 * @param sourceTable Source table
 * @param sourceMapping Mapping in source table
 * @param sourceParentMapping Optional parent of this source mapping (if joining an impl of an interface)
 * @param targetTable Target table
 * @param targetMapping Mapping in target table
 * @param targetParentMapping Optional parent of this target mapping (if joining an impl of an interface)
 * @param discrimValues Optional discriminator values to further restrict
 * @return The join condition
 */
protected BooleanExpression getJoinConditionForJoin(SQLTable sourceTable, JavaTypeMapping sourceMapping, JavaTypeMapping sourceParentMapping, SQLTable targetTable, JavaTypeMapping targetMapping, JavaTypeMapping targetParentMapping, Object[] discrimValues) {
    BooleanExpression joinCondition = null;
    if (sourceMapping != null && targetMapping != null) {
        // Join condition(s) - INNER, LEFT OUTER, RIGHT OUTER joins
        if (sourceMapping.getNumberOfDatastoreMappings() != targetMapping.getNumberOfDatastoreMappings()) {
            throw new NucleusException("Cannot join from " + sourceMapping + " to " + targetMapping + " since they have different numbers of datastore columns!");
        }
        SQLExpressionFactory factory = rdbmsMgr.getSQLExpressionFactory();
        // Set joinCondition to be "source = target"
        SQLExpression sourceExpr = null;
        if (sourceParentMapping == null) {
            sourceExpr = factory.newExpression(this, sourceTable != null ? sourceTable : primaryTable, sourceMapping);
        } else {
            sourceExpr = factory.newExpression(this, sourceTable != null ? sourceTable : primaryTable, sourceMapping, sourceParentMapping);
        }
        SQLExpression targetExpr = null;
        if (targetParentMapping == null) {
            targetExpr = factory.newExpression(this, targetTable, targetMapping);
        } else {
            targetExpr = factory.newExpression(this, targetTable, targetMapping, targetParentMapping);
        }
        joinCondition = sourceExpr.eq(targetExpr);
        // Process discriminator for any additional conditions
        JavaTypeMapping discrimMapping = targetTable.getTable().getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, false);
        if (discrimMapping != null && discrimValues != null) {
            SQLExpression discrimExpr = factory.newExpression(this, targetTable, discrimMapping);
            BooleanExpression discrimCondition = null;
            for (Object discrimValue : discrimValues) {
                SQLExpression discrimVal = factory.newLiteral(this, discrimMapping, discrimValue);
                BooleanExpression condition = discrimExpr.eq(discrimVal);
                if (discrimCondition == null) {
                    discrimCondition = condition;
                } else {
                    discrimCondition = discrimCondition.ior(condition);
                }
            }
            if (discrimCondition != null) {
                discrimCondition.encloseInParentheses();
                joinCondition = joinCondition.and(discrimCondition);
            }
        }
    }
    return joinCondition;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) NucleusException(org.datanucleus.exceptions.NucleusException)

Aggregations

BooleanExpression (org.datanucleus.store.rdbms.sql.expression.BooleanExpression)39 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)33 NucleusException (org.datanucleus.exceptions.NucleusException)14 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)14 UnboundExpression (org.datanucleus.store.rdbms.sql.expression.UnboundExpression)14 ParameterLiteral (org.datanucleus.store.rdbms.sql.expression.ParameterLiteral)13 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)12 NumericExpression (org.datanucleus.store.rdbms.sql.expression.NumericExpression)11 StringExpression (org.datanucleus.store.rdbms.sql.expression.StringExpression)11 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)10 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)8 CharacterExpression (org.datanucleus.store.rdbms.sql.expression.CharacterExpression)8 TemporalExpression (org.datanucleus.store.rdbms.sql.expression.TemporalExpression)7 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)7 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)6 BooleanSubqueryExpression (org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression)6 MapExpression (org.datanucleus.store.rdbms.sql.expression.MapExpression)6 ArrayList (java.util.ArrayList)5 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)5 CollectionExpression (org.datanucleus.store.rdbms.sql.expression.CollectionExpression)5