Search in sources :

Example 11 with BooleanExpression

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

the class DeleteStatement method getSQLText.

public synchronized SQLText getSQLText() {
    if (sql != null) {
        return sql;
    }
    sql = new SQLText(rdbmsMgr.getDatastoreAdapter().getDeleteTableStatement(primaryTable));
    if (joins != null) {
        // Joins present so convert to "DELETE FROM MYTABLE WHERE EXISTS (SELECT * FROM OTHER_TBL ...)"
        Iterator<SQLJoin> joinIter = joins.iterator();
        // Create sub-statement selecting the first joined table, joining back to the outer statement
        SQLJoin subJoin = joinIter.next();
        SQLStatement subStmt = new SelectStatement(this, rdbmsMgr, subJoin.getTargetTable().getTable(), subJoin.getTargetTable().getAlias(), subJoin.getTargetTable().getGroupName());
        subStmt.whereAnd(subJoin.getCondition(), false);
        if (where != null) {
            // Move the WHERE clause to the sub-statement
            subStmt.whereAnd(where, false);
        }
        // Put any remaining joins into the sub-statement
        while (joinIter.hasNext()) {
            SQLJoin join = joinIter.next();
            subStmt.joins.add(join);
        }
        // Set WHERE clause of outer statement to "EXISTS (sub-statement)"
        BooleanExpression existsExpr = new BooleanSubqueryExpression(this, "EXISTS", subStmt);
        where = existsExpr;
    }
    if (where != null) {
        sql.append(" WHERE ").append(where.toSQLText());
    }
    return sql;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) BooleanSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression)

Example 12 with BooleanExpression

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

the class DiscriminatorStatementGenerator method getStatement.

/**
 * Accessor for the SelectStatement.
 * @param ec ExecutionContext
 * @return The SelectStatement for iterating through objects with a discriminator column
 */
public SelectStatement getStatement(ExecutionContext ec) {
    SelectStatement stmt = null;
    SQLTable discrimSqlTbl = null;
    if (joinTable == null) {
        // Select of candidate table
        stmt = new SelectStatement(parentStmt, storeMgr, candidateTable, candidateTableAlias, candidateTableGroupName);
        stmt.setClassLoaderResolver(clr);
        discrimSqlTbl = stmt.getPrimaryTable();
    } else {
        // Select of join table, with join to element table
        stmt = new SelectStatement(parentStmt, storeMgr, joinTable, joinTableAlias, candidateTableGroupName);
        stmt.setClassLoaderResolver(clr);
        JavaTypeMapping candidateIdMapping = candidateTable.getIdMapping();
        if (hasOption(OPTION_ALLOW_NULLS)) {
            // Put element table in same table group since all relates to the elements
            discrimSqlTbl = stmt.join(JoinType.LEFT_OUTER_JOIN, null, joinElementMapping, candidateTable, null, candidateIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
        } else {
            // Put element table in same table group since all relates to the elements
            discrimSqlTbl = stmt.join(JoinType.INNER_JOIN, null, joinElementMapping, candidateTable, null, candidateIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
        }
    }
    JavaTypeMapping discMapping = candidateTable.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, true);
    if (discMapping != null) {
        // Allow for discriminator being in super-table of the candidate table
        discrimSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(stmt, discrimSqlTbl, discMapping);
    }
    DiscriminatorMetaData dismd = discrimSqlTbl.getTable().getDiscriminatorMetaData();
    boolean hasDiscriminator = (discMapping != null && dismd != null && dismd.getStrategy() != DiscriminatorStrategy.NONE);
    // Check if we can omit the discriminator restriction
    boolean restrictDiscriminator = hasOption(OPTION_RESTRICT_DISCRIM);
    if (hasDiscriminator && restrictDiscriminator) {
        // Add the discriminator expression to restrict accepted values
        boolean multipleCandidates = false;
        BooleanExpression discExpr = null;
        if (candidates != null) {
            // Multiple candidates
            if (candidates.length > 1) {
                multipleCandidates = true;
            }
            for (int i = 0; i < candidates.length; i++) {
                if (Modifier.isAbstract(candidates[i].getModifiers())) {
                    // No point selecting this candidate since can't be instantiated
                    continue;
                }
                BooleanExpression discExprCandidate = SQLStatementHelper.getExpressionForDiscriminatorForClass(stmt, candidates[i].getName(), dismd, discMapping, discrimSqlTbl, clr);
                if (discExpr != null) {
                    discExpr = discExpr.ior(discExprCandidate);
                } else {
                    discExpr = discExprCandidate;
                }
                if (includeSubclasses) {
                    Collection<String> subclassNames = storeMgr.getSubClassesForClass(candidateType.getName(), true, clr);
                    Iterator<String> subclassIter = subclassNames.iterator();
                    if (!multipleCandidates) {
                        multipleCandidates = (subclassNames.size() > 0);
                    }
                    while (subclassIter.hasNext()) {
                        String subclassName = subclassIter.next();
                        BooleanExpression discExprSub = SQLStatementHelper.getExpressionForDiscriminatorForClass(stmt, subclassName, dismd, discMapping, discrimSqlTbl, clr);
                        discExpr = discExpr.ior(discExprSub);
                    }
                }
            }
        } else {
            // Single candidate
            if (!Modifier.isAbstract(candidateType.getModifiers())) {
                discExpr = SQLStatementHelper.getExpressionForDiscriminatorForClass(stmt, candidateType.getName(), dismd, discMapping, discrimSqlTbl, clr);
            }
            if (includeSubclasses) {
                Collection<String> subclassNames = storeMgr.getSubClassesForClass(candidateType.getName(), true, clr);
                Iterator<String> subclassIter = subclassNames.iterator();
                multipleCandidates = (subclassNames.size() > 0);
                while (subclassIter.hasNext()) {
                    String subclassName = subclassIter.next();
                    Class subclass = clr.classForName(subclassName);
                    if ((Modifier.isAbstract(subclass.getModifiers()))) {
                        continue;
                    }
                    BooleanExpression discExprCandidate = SQLStatementHelper.getExpressionForDiscriminatorForClass(stmt, subclassName, dismd, discMapping, discrimSqlTbl, clr);
                    if (discExpr == null) {
                        discExpr = discExprCandidate;
                    } else {
                        discExpr = discExpr.ior(discExprCandidate);
                    }
                }
            }
            if (discExpr == null) {
                // No possible candidates, so set expression as "1=0"
                SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
                JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
                discExpr = exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
            }
        }
        if (discExpr != null) {
            if (hasOption(OPTION_ALLOW_NULLS)) {
                // Allow for null value of discriminator
                SQLExpression expr = stmt.getSQLExpressionFactory().newExpression(stmt, discrimSqlTbl, discMapping);
                SQLExpression val = new NullLiteral(stmt, null, null, null);
                BooleanExpression nullDiscExpr = expr.eq(val);
                discExpr = discExpr.ior(nullDiscExpr);
                if (!multipleCandidates) {
                    multipleCandidates = true;
                }
            }
            // Apply the discriminator to the query statement
            if (multipleCandidates) {
                discExpr.encloseInParentheses();
            }
            stmt.whereAnd(discExpr, true);
        }
    }
    JavaTypeMapping multitenancyMapping = candidateTable.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
    if (multitenancyMapping != null) {
        // Multi-tenancy restriction
        AbstractClassMetaData cmd = candidateTable.getClassMetaData();
        SQLTable tenantSqlTbl = stmt.getTable(multitenancyMapping.getTable(), discrimSqlTbl.getGroupName());
        SQLExpression tenantExpr = stmt.getSQLExpressionFactory().newExpression(stmt, tenantSqlTbl, multitenancyMapping);
        SQLExpression tenantVal = stmt.getSQLExpressionFactory().newLiteral(stmt, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, cmd));
        stmt.whereAnd(tenantExpr.eq(tenantVal), true);
    }
    JavaTypeMapping softDeleteMapping = candidateTable.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
    if (softDeleteMapping != null && !hasOption(OPTION_INCLUDE_SOFT_DELETES)) {
        // Soft-delete restriction
        SQLTable softDeleteSqlTbl = stmt.getTable(softDeleteMapping.getTable(), discrimSqlTbl.getGroupName());
        SQLExpression softDeleteExpr = stmt.getSQLExpressionFactory().newExpression(stmt, softDeleteSqlTbl, softDeleteMapping);
        SQLExpression softDeleteVal = stmt.getSQLExpressionFactory().newLiteral(stmt, softDeleteMapping, Boolean.FALSE);
        stmt.whereAnd(softDeleteExpr.eq(softDeleteVal), true);
    }
    return stmt;
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) DiscriminatorMetaData(org.datanucleus.metadata.DiscriminatorMetaData) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) NullLiteral(org.datanucleus.store.rdbms.sql.expression.NullLiteral)

Example 13 with BooleanExpression

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

the class SelectStatement method join.

@Override
public SQLTable join(JoinType joinType, SQLTable sourceTable, JavaTypeMapping sourceMapping, JavaTypeMapping sourceParentMapping, Table target, String targetAlias, JavaTypeMapping targetMapping, JavaTypeMapping targetParentMapping, Object[] discrimValues, String tableGrpName, boolean applyToUnions, SQLJoin parentJoin) {
    invalidateStatement();
    // Create the SQLTable to join to.
    if (tables == null) {
        tables = new HashMap();
    }
    if (tableGrpName == null) {
        tableGrpName = "Group" + tableGroups.size();
    }
    if (targetAlias == null) {
        targetAlias = namer.getAliasForTable(this, target, tableGrpName);
    }
    if (sourceTable == null) {
        sourceTable = primaryTable;
    }
    DatastoreIdentifier targetId = rdbmsMgr.getIdentifierFactory().newTableIdentifier(targetAlias);
    SQLTable targetTbl = new SQLTable(this, target, targetId, tableGrpName);
    putSQLTableInGroup(targetTbl, tableGrpName, joinType);
    // Generate the join condition to use
    BooleanExpression joinCondition = getJoinConditionForJoin(sourceTable, sourceMapping, sourceParentMapping, targetTbl, targetMapping, targetParentMapping, discrimValues);
    addJoin(joinType, sourceTable, targetTbl, joinCondition, parentJoin);
    if (unions != null && applyToUnions) {
        // Apply the join to all unions
        Iterator<SelectStatement> unionIter = unions.iterator();
        while (unionIter.hasNext()) {
            SelectStatement stmt = unionIter.next();
            stmt.join(joinType, sourceTable, sourceMapping, sourceParentMapping, target, targetAlias, targetMapping, targetParentMapping, discrimValues, tableGrpName, true, parentJoin);
        }
    }
    return targetTbl;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) HashMap(java.util.HashMap) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier)

Example 14 with BooleanExpression

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

the class UpdateStatement method getSQLText.

public synchronized SQLText getSQLText() {
    if (sql != null) {
        return sql;
    }
    // Generate the SET component of the statement since some need it to formulate the basic UPDATE component
    SQLText setSQL = new SQLText("SET ");
    if (updates != null && updates.length > 0) {
        for (int i = 0; i < updates.length; i++) {
            if (updates[i] != null) {
                if (i != 0) {
                    setSQL.append(",");
                }
                setSQL.append(updates[i].toSQLText());
            }
        }
    }
    sql = rdbmsMgr.getDatastoreAdapter().getUpdateTableStatement(primaryTable, setSQL);
    if (joins != null) {
        // Joins present so convert to "... WHERE EXISTS (SELECT * FROM OTHER_TBL ...)"
        Iterator<SQLJoin> joinIter = joins.iterator();
        // Create sub-statement selecting the first joined table, joining back to the outer statement
        SQLJoin subJoin = joinIter.next();
        SQLStatement subStmt = new SelectStatement(this, rdbmsMgr, subJoin.getTargetTable().getTable(), subJoin.getTargetTable().getAlias(), subJoin.getTargetTable().getGroupName());
        subStmt.whereAnd(subJoin.getCondition(), false);
        if (where != null) {
            // Move the WHERE clause to the sub-statement
            subStmt.whereAnd(where, false);
        }
        // Put any remaining joins into the sub-statement
        while (joinIter.hasNext()) {
            SQLJoin join = joinIter.next();
            subStmt.joins.add(join);
        }
        // Set WHERE clause of outer statement to "EXISTS (sub-statement)"
        BooleanExpression existsExpr = new BooleanSubqueryExpression(this, "EXISTS", subStmt);
        where = existsExpr;
    }
    if (where != null) {
        sql.append(" WHERE ").append(where.toSQLText());
    }
    return sql;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) BooleanSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression)

Example 15 with BooleanExpression

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

the class SQLStatement method join.

/**
 * Method to form a join to the specified table using the provided mappings, with the join condition derived from the source-target mappings.
 * @param joinType Type of join.
 * @param sourceTable SQLTable for the source (null implies primaryTable)
 * @param sourceMapping Mapping in this table to join from
 * @param sourceParentMapping Optional, if this source mapping is a sub mapping (e.g interface impl).
 * @param target Table to join to
 * @param targetAlias Alias for the target table (if known)
 * @param targetMapping Mapping in the other table to join to (also defines the table to join to)
 * @param targetParentMapping Optional, if this source mapping is a sub mapping (e.g interface impl).
 * @param discrimValues Any discriminator values to apply for the joined table (null if not)
 * @param tableGrpName Name of the table group for the target (null implies a new group)
 * @param applyToUnions Whether to apply to any unioned statements (only applies to SELECT statements)
 * @param parentJoin Parent join when this join will be a sub-join (part of "join grouping")
 * @return SQLTable for the target
 */
public SQLTable join(JoinType joinType, SQLTable sourceTable, JavaTypeMapping sourceMapping, JavaTypeMapping sourceParentMapping, Table target, String targetAlias, JavaTypeMapping targetMapping, JavaTypeMapping targetParentMapping, Object[] discrimValues, String tableGrpName, boolean applyToUnions, SQLJoin parentJoin) {
    invalidateStatement();
    // Create the SQLTable to join to.
    if (tables == null) {
        tables = new HashMap();
    }
    if (tableGrpName == null) {
        tableGrpName = "Group" + tableGroups.size();
    }
    if (targetAlias == null) {
        targetAlias = namer.getAliasForTable(this, target, tableGrpName);
    }
    if (sourceTable == null) {
        sourceTable = primaryTable;
    }
    DatastoreIdentifier targetId = rdbmsMgr.getIdentifierFactory().newTableIdentifier(targetAlias);
    SQLTable targetTbl = new SQLTable(this, target, targetId, tableGrpName);
    putSQLTableInGroup(targetTbl, tableGrpName, joinType);
    // Generate the join condition to use
    BooleanExpression joinCondition = getJoinConditionForJoin(sourceTable, sourceMapping, sourceParentMapping, targetTbl, targetMapping, targetParentMapping, discrimValues);
    addJoin(joinType, sourceTable, targetTbl, joinCondition, parentJoin);
    return targetTbl;
}
Also used : BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier)

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