Search in sources :

Example 76 with SQLExpressionFactory

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

the class UnionStatementGenerator method getSQLStatementForCandidateViaJoin.

/**
 * Convenience method to return the SQLStatement for a particular class selecting a join table.
 * Returns a SQLStatement with primaryTable of the "joinTable", and which joins to the table of the class.
 * @param className The class name to generate the statement for
 * @return The SQLStatement
 */
protected SelectStatement getSQLStatementForCandidateViaJoin(String className) {
    DatastoreClass table = storeMgr.getDatastoreClass(className, clr);
    if (table == null) {
        // TODO Cater for use of single subclass-table
        throw new NucleusException("We do not currently support a UNION statement for class=" + className + " since it has no table of its own");
    }
    // Start from an SQL SELECT of the join table
    SelectStatement stmt = new SelectStatement(parentStmt, storeMgr, joinTable, joinTableAlias, candidateTableGroupName);
    stmt.setClassLoaderResolver(clr);
    stmt.setCandidateClassName(className);
    // INNER/LEFT OUTER JOIN from the join table to the root candidate table
    // If we allow nulls we do a left outer join here, otherwise an inner join
    SQLTable candidateSQLTable = null;
    if (candidateTable != null) {
        // We have a root candidate table, so join to that
        JavaTypeMapping candidateIdMapping = candidateTable.getIdMapping();
        if (hasOption(OPTION_ALLOW_NULLS)) {
            // Put element table in same table group since all relates to the elements
            candidateSQLTable = 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
            candidateSQLTable = stmt.join(JoinType.INNER_JOIN, null, joinElementMapping, candidateTable, null, candidateIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
        }
        // Join the root candidate table to this particular candidate table
        if (table != candidateTable) {
            // INNER JOIN from the root candidate table to this candidates table
            stmt.join(JoinType.INNER_JOIN, candidateSQLTable, candidateIdMapping, table, null, table.getIdMapping(), null, stmt.getPrimaryTable().getGroupName(), true);
        }
    } else {
        // No root candidate table, so join direct to this candidate
        JavaTypeMapping candidateIdMapping = table.getIdMapping();
        if (hasOption(OPTION_ALLOW_NULLS)) {
            // Put element table in same table group since all relates to the elements
            candidateSQLTable = stmt.join(JoinType.LEFT_OUTER_JOIN, null, joinElementMapping, table, null, candidateIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
        } else {
            // Put element table in same table group since all relates to the elements
            candidateSQLTable = stmt.join(JoinType.INNER_JOIN, null, joinElementMapping, table, null, candidateIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
        }
    }
    // Add any discriminator restriction in the table for the specified class
    // Caters for the case where we have more than 1 class stored in this table
    SQLExpressionFactory factory = storeMgr.getSQLExpressionFactory();
    JavaTypeMapping discriminatorMapping = table.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, false);
    DiscriminatorMetaData discriminatorMetaData = table.getDiscriminatorMetaData();
    if (discriminatorMapping != null && discriminatorMetaData.getStrategy() != DiscriminatorStrategy.NONE) {
        // Restrict to valid discriminator value where we have a discriminator specified on this table
        BooleanExpression discExpr = SQLStatementHelper.getExpressionForDiscriminatorForClass(stmt, className, discriminatorMetaData, discriminatorMapping, stmt.getPrimaryTable(), clr);
        stmt.whereAnd(discExpr, false);
    }
    // Eliminate any subclasses (catered for in separate UNION statement)
    Iterator<String> subIter = storeMgr.getSubClassesForClass(className, false, clr).iterator();
    while (subIter.hasNext()) {
        String subclassName = subIter.next();
        DatastoreClass[] subclassTables = null;
        DatastoreClass subclassTable = storeMgr.getDatastoreClass(subclassName, clr);
        if (subclassTable == null) {
            AbstractClassMetaData targetSubCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(subclassName, clr);
            AbstractClassMetaData[] targetSubCmds = storeMgr.getClassesManagingTableForClass(targetSubCmd, clr);
            subclassTables = new DatastoreClass[targetSubCmds.length];
            for (int i = 0; i < targetSubCmds.length; i++) {
                subclassTables[i] = storeMgr.getDatastoreClass(targetSubCmds[i].getFullClassName(), clr);
            }
        } else {
            subclassTables = new DatastoreClass[1];
            subclassTables[0] = subclassTable;
        }
        for (int i = 0; i < subclassTables.length; i++) {
            if (subclassTables[i] != table) {
                // Subclass of our class is stored in different table to the candidate so exclude it
                // Adds FROM clause of "LEFT OUTER JOIN {subTable} ON ..."
                // and WHERE clause of "{subTable}.ID = NULL"
                JavaTypeMapping subclassIdMapping = subclassTables[i].getIdMapping();
                SQLTable sqlTableSubclass = stmt.join(JoinType.LEFT_OUTER_JOIN, null, joinElementMapping, subclassTables[i], null, subclassIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
                SQLExpression subclassIdExpr = factory.newExpression(stmt, sqlTableSubclass, subclassIdMapping);
                SQLExpression nullExpr = new NullLiteral(stmt, null, null, null);
                stmt.whereAnd(subclassIdExpr.eq(nullExpr), false);
            }
        }
    }
    if (hasOption(OPTION_SELECT_DN_TYPE)) {
        // Add SELECT of dummy metadata for this class ("'mydomain.MyClass' AS DN_TYPE")
        addTypeSelectForClass(stmt, className);
    }
    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) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) NullLiteral(org.datanucleus.store.rdbms.sql.expression.NullLiteral)

Example 77 with SQLExpressionFactory

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

the class JoinMapStore method getSQLStatementForGet.

/**
 * Method to return an SQLStatement for retrieving the value for a key.
 * Selects the join table and optionally joins to the value table if it has its own table.
 * @param ownerOP ObjectProvider for the owning object
 * @return The SQLStatement
 */
protected SelectStatement getSQLStatementForGet(ObjectProvider ownerOP) {
    SelectStatement sqlStmt = null;
    ExecutionContext ec = ownerOP.getExecutionContext();
    final ClassLoaderResolver clr = ownerOP.getExecutionContext().getClassLoaderResolver();
    Class valueCls = clr.classForName(this.valueType);
    if (valuesAreEmbedded || valuesAreSerialised) {
        // Value is stored in join table
        sqlStmt = new SelectStatement(storeMgr, mapTable, null, null);
        sqlStmt.setClassLoaderResolver(clr);
        sqlStmt.select(sqlStmt.getPrimaryTable(), valueMapping, null);
    } else {
        // Value is stored in own table
        getMappingDef = new StatementClassMapping();
        if (!valueCmd.getFullClassName().equals(valueCls.getName())) {
            valueCls = clr.classForName(valueCmd.getFullClassName());
        }
        UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null, mapTable, null, valueMapping);
        stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
        getMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
        sqlStmt = stmtGen.getStatement(ec);
        // Select the value field(s)
        SQLTable valueSqlTbl = sqlStmt.getTable(valueTable, sqlStmt.getPrimaryTable().getGroupName());
        if (valueSqlTbl == null) {
            // Root value candidate has no table, so try to find a value candidate with a table that exists in this statement
            Collection<String> valueSubclassNames = storeMgr.getSubClassesForClass(valueType, true, clr);
            if (valueSubclassNames != null && !valueSubclassNames.isEmpty()) {
                for (String valueSubclassName : valueSubclassNames) {
                    DatastoreClass valueTbl = storeMgr.getDatastoreClass(valueSubclassName, clr);
                    if (valueTbl != null) {
                        valueSqlTbl = sqlStmt.getTable(valueTbl, sqlStmt.getPrimaryTable().getGroupName());
                        if (valueSqlTbl != null) {
                            break;
                        }
                    }
                }
            }
        }
        SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, getMappingDef, ec.getFetchPlan(), valueSqlTbl, valueCmd, ec.getFetchPlan().getMaxFetchDepth());
    }
    // Apply condition on owner field to filter by owner
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), ownerMapping);
    SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
    SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
    sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
    // Apply condition on key
    if (keyMapping instanceof SerialisedMapping) {
        // if the keyMapping contains a BLOB column (or any other column not supported by the database
        // as primary key), uses like instead of the operator OP_EQ (=)
        // in future do not check if the keyMapping is of ObjectMapping, but use the database
        // adapter to check the data types not supported as primary key
        // if object mapping (BLOB) use like
        SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
        SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
        sqlStmt.whereAnd(new org.datanucleus.store.rdbms.sql.expression.BooleanExpression(keyExpr, Expression.OP_LIKE, keyVal), true);
    } else {
        SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
        SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
        sqlStmt.whereAnd(keyExpr.eq(keyVal), true);
    }
    // Input parameter(s) - owner, key
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    StatementMappingIndex keyIdx = new StatementMappingIndex(keyMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < ownerPositions.length; k++) {
                ownerPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(ownerPositions);
            int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < keyPositions.length; k++) {
                keyPositions[k] = inputParamNum++;
            }
            keyIdx.addParameterOccurrence(keyPositions);
        }
    } else {
        int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < ownerPositions.length; k++) {
            ownerPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(ownerPositions);
        int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < keyPositions.length; k++) {
            keyPositions[k] = inputParamNum++;
        }
        keyIdx.addParameterOccurrence(keyPositions);
    }
    getMappingParams = new StatementParameterMapping();
    getMappingParams.addMappingForParameter("owner", ownerIdx);
    getMappingParams.addMappingForParameter("key", keyIdx);
    return sqlStmt;
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) UnionStatementGenerator(org.datanucleus.store.rdbms.sql.UnionStatementGenerator) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) ExecutionContext(org.datanucleus.ExecutionContext) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) SerialisedMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedMapping) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 78 with SQLExpressionFactory

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

the class OracleBlobRDBMSMapping method updateBlobColumn.

/**
 * Convenience method to update the contents of a BLOB column.
 * Oracle requires that a BLOB is initialised with EMPTY_BLOB() and then you retrieve
 * the column and update its BLOB value. Performs a statement
 * <pre>
 * SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE
 * </pre>
 * and then updates the Blob value returned.
 * @param op ObjectProvider of the object
 * @param table Table storing the BLOB column
 * @param mapping Datastore mapping for the BLOB column
 * @param bytes The bytes to store in the BLOB
 * @throws NucleusObjectNotFoundException thrown if an object isnt found
 * @throws NucleusDataStoreException thrown if an error occurs in datastore communication
 */
@SuppressWarnings("deprecation")
public static void updateBlobColumn(ObjectProvider op, Table table, DatastoreMapping mapping, byte[] bytes) {
    ExecutionContext ec = op.getExecutionContext();
    RDBMSStoreManager storeMgr = table.getStoreManager();
    // Don't support join tables yet
    DatastoreClass classTable = (DatastoreClass) table;
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    // Generate "SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE" statement
    SelectStatement sqlStmt = new SelectStatement(storeMgr, table, null, null);
    sqlStmt.setClassLoaderResolver(ec.getClassLoaderResolver());
    sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
    SQLTable blobSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), mapping.getJavaTypeMapping());
    sqlStmt.select(blobSqlTbl, mapping.getColumn(), null);
    StatementClassMapping mappingDefinition = new StatementClassMapping();
    AbstractClassMetaData cmd = op.getClassMetaData();
    int inputParamNum = 1;
    if (cmd.getIdentityType() == IdentityType.DATASTORE) {
        // Datastore identity value for input
        JavaTypeMapping datastoreIdMapping = classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
        SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), datastoreIdMapping);
        SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, datastoreIdMapping, null, "ID");
        sqlStmt.whereAnd(expr.eq(val), true);
        StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
        if (datastoreIdx == null) {
            datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
            mappingDefinition.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
        }
        datastoreIdx.addParameterOccurrence(new int[] { inputParamNum });
    } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
        // Application identity value(s) for input
        int[] pkNums = cmd.getPKMemberPositions();
        for (int i = 0; i < pkNums.length; i++) {
            AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[i]);
            JavaTypeMapping pkMapping = classTable.getMemberMapping(mmd);
            SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), pkMapping);
            SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, pkMapping, null, "PK" + i);
            sqlStmt.whereAnd(expr.eq(val), true);
            StatementMappingIndex pkIdx = mappingDefinition.getMappingForMemberPosition(pkNums[i]);
            if (pkIdx == null) {
                pkIdx = new StatementMappingIndex(pkMapping);
                mappingDefinition.addMappingForMember(pkNums[i], pkIdx);
            }
            int[] inputParams = new int[pkMapping.getNumberOfDatastoreMappings()];
            for (int j = 0; j < pkMapping.getNumberOfDatastoreMappings(); j++) {
                inputParams[j] = inputParamNum++;
            }
            pkIdx.addParameterOccurrence(inputParams);
        }
    }
    String textStmt = sqlStmt.getSQLText().toSQL();
    if (op.isEmbedded()) {
        // This mapping is embedded, so navigate back to the real owner since that is the "id" in the table
        ObjectProvider[] embeddedOwners = ec.getOwnersForEmbeddedObjectProvider(op);
        if (embeddedOwners != null) {
            // Just use the first owner
            // TODO Should check if the owner is stored in this table
            op = embeddedOwners[0];
        }
    }
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        SQLController sqlControl = storeMgr.getSQLController();
        try {
            PreparedStatement ps = sqlControl.getStatementForQuery(mconn, textStmt);
            try {
                // Provide the primary key field(s) to the JDBC statement
                if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                    StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
                    for (int i = 0; i < datastoreIdx.getNumberOfParameterOccurrences(); i++) {
                        classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, datastoreIdx.getParameterPositionsForOccurrence(i), op.getInternalObjectId());
                    }
                } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                    op.provideFields(cmd.getPKMemberPositions(), new ParameterSetter(op, ps, mappingDefinition));
                }
                ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, textStmt, ps);
                try {
                    if (!rs.next()) {
                        throw new NucleusObjectNotFoundException("No such database row", op.getInternalObjectId());
                    }
                    DatastoreAdapter dba = storeMgr.getDatastoreAdapter();
                    int jdbcMajorVersion = dba.getDriverMajorVersion();
                    if (dba.getDatastoreDriverName().equalsIgnoreCase(OracleAdapter.OJDBC_DRIVER_NAME) && jdbcMajorVersion < 10) {
                        // Oracle JDBC drivers version 9 and below use some sh*tty Oracle-specific BLOB type
                        // we have to cast to that, face west, pray whilst saying ommmmmmmmmmm
                        oracle.sql.BLOB blob = null;
                        if (jdbcMajorVersion <= 8) {
                            OracleResultSet ors = (OracleResultSet) rs;
                            blob = ors.getBLOB(1);
                        } else {
                            blob = (oracle.sql.BLOB) rs.getBlob(1);
                        }
                        if (blob != null) {
                            // Deprecated but what can you do
                            blob.putBytes(1, bytes);
                        }
                    } else {
                        // Oracle JDBC drivers 10 and above supposedly use the JDBC standard class for Blobs
                        java.sql.Blob blob = rs.getBlob(1);
                        if (blob != null) {
                            blob.setBytes(1, bytes);
                        }
                    }
                } finally {
                    rs.close();
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException e) {
        throw new NucleusDataStoreException("Update of BLOB value failed: " + textStmt, e);
    }
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) OracleResultSet(oracle.jdbc.driver.OracleResultSet) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLException(java.sql.SQLException) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) ParameterSetter(org.datanucleus.store.rdbms.fieldmanager.ParameterSetter) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) SQLController(org.datanucleus.store.rdbms.SQLController) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) ResultSet(java.sql.ResultSet) OracleResultSet(oracle.jdbc.driver.OracleResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) PreparedStatement(java.sql.PreparedStatement) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) ExecutionContext(org.datanucleus.ExecutionContext) ObjectProvider(org.datanucleus.state.ObjectProvider) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) Blob(java.sql.Blob) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 79 with SQLExpressionFactory

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

the class MapContainsEntryMethod method containsAsSubquery.

/**
 * Method to return an expression for Map.containsEntry using a subquery "EXISTS".
 * This is for use when there are "!contains" or "OR" operations in the filter.
 * Creates the following SQL,
 * <ul>
 * <li><b>Map using join table</b>
 * <pre>
 * SELECT 1 FROM JOIN_TBL A0_SUB
 * WHERE A0_SUB.JOIN_OWN_ID = A0.ID
 * AND A0_SUB.JOIN_VAL_ID = {valExpr}
 * AND Ao_SUB.JOIN_KEY_ID = {keyExpr}
 * </pre>
 * </li>
 * <li><b>Map with key stored in value</b>
 * <pre>
 * SELECT 1 FROM VAL_TABLE A0_SUB
 * WHERE B0.JOIN_OWN_ID = A0.ID
 * AND A0_SUB.ID = {valExpr}
 * AND A0_SUB.KEY_ID = {keyExpr}
 * </pre>
 * </li>
 * <li><b>Map of value stored in key</b>
 * <pre>
 * SELECT 1 FROM KEY_TABLE A0_SUB
 * WHERE A0_SUB.OWN_ID = A0.ID
 * AND A0_SUB.VAL_ID = {valExpr}
 * AND A0_SUB.ID = {keyExpr}
 * </pre>
 * </li>
 * </ul>
 * and returns a BooleanSubqueryExpression ("EXISTS (subquery)")
 * @param stmt SQLStatement
 * @param mapExpr Map expression
 * @param keyExpr Expression for the key
 * @param valExpr Expression for the value
 * @return Contains expression
 */
protected SQLExpression containsAsSubquery(SQLStatement stmt, MapExpression mapExpr, SQLExpression keyExpr, SQLExpression valExpr) {
    boolean keyIsUnbound = (keyExpr instanceof UnboundExpression);
    String keyVarName = null;
    if (keyIsUnbound) {
        keyVarName = ((UnboundExpression) keyExpr).getVariableName();
        NucleusLogger.QUERY.debug(">> Map.containsEntry binding unbound variable " + keyVarName + " using SUBQUERY");
    // TODO What if the variable is declared as a subtype, handle this see CollectionContainsMethod
    }
    boolean valIsUnbound = (valExpr instanceof UnboundExpression);
    String valVarName = null;
    if (valIsUnbound) {
        valVarName = ((UnboundExpression) valExpr).getVariableName();
        NucleusLogger.QUERY.debug(">> Map.containsEntry binding unbound variable " + valVarName + " using SUBQUERY");
    // TODO What if the variable is declared as a subtype, handle this see CollectionContainsMethod
    }
    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
    AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
    AbstractClassMetaData keyCmd = mmd.getMap().getKeyClassMetaData(clr);
    AbstractClassMetaData valCmd = mmd.getMap().getValueClassMetaData(clr);
    MapTable joinTbl = (MapTable) storeMgr.getTable(mmd);
    SelectStatement subStmt = null;
    if (mmd.getMap().getMapType() == MapType.MAP_TYPE_JOIN) {
        // JoinTable Map
        subStmt = new SelectStatement(stmt, storeMgr, joinTbl, null, null);
        subStmt.setClassLoaderResolver(clr);
        JavaTypeMapping oneMapping = storeMgr.getMappingManager().getMapping(Integer.class);
        subStmt.select(exprFactory.newLiteral(subStmt, oneMapping, 1), null);
        // Restrict to collection owner
        JavaTypeMapping ownerMapping = ((JoinTable) joinTbl).getOwnerMapping();
        SQLExpression ownerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
        SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
        subStmt.whereAnd(ownerExpr.eq(ownerIdExpr), true);
        SQLExpression valIdExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), joinTbl.getValueMapping());
        if (valIsUnbound) {
            // Bind the variable in the QueryGenerator
            stmt.getQueryGenerator().bindVariable(valVarName, valCmd, valIdExpr.getSQLTable(), valIdExpr.getJavaTypeMapping());
        } else {
            // Add restrict to value TODO Add join to valueTbl if present
            subStmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
        SQLExpression keyIdExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), joinTbl.getKeyMapping());
        if (keyIsUnbound) {
            // Bind the variable in the QueryGenerator
            stmt.getQueryGenerator().bindVariable(keyVarName, keyCmd, keyIdExpr.getSQLTable(), keyIdExpr.getJavaTypeMapping());
        } else {
            // Add restrict to key TODO Add join to keyTbl if present
            subStmt.whereAnd(keyIdExpr.eq(keyExpr), true);
        }
    } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
        // Key stored in value table
        DatastoreClass valTbl = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
        AbstractMemberMetaData valKeyMmd = valCmd.getMetaDataForMember(mmd.getKeyMetaData().getMappedBy());
        subStmt = new SelectStatement(stmt, storeMgr, valTbl, null, null);
        subStmt.setClassLoaderResolver(clr);
        JavaTypeMapping oneMapping = storeMgr.getMappingManager().getMapping(Integer.class);
        subStmt.select(exprFactory.newLiteral(subStmt, oneMapping, 1), null);
        // Restrict to map owner (on value table)
        JavaTypeMapping ownerMapping = null;
        if (mmd.getMappedBy() != null) {
            ownerMapping = valTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = valTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        SQLExpression ownerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
        SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
        subStmt.whereAnd(ownerExpr.eq(ownerIdExpr), true);
        SQLExpression valIdExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valTbl.getIdMapping());
        if (valIsUnbound) {
            // Bind the variable in the QueryGenerator
            stmt.getQueryGenerator().bindVariable(valVarName, valCmd, valIdExpr.getSQLTable(), valIdExpr.getJavaTypeMapping());
        } else {
            // Add restrict to value
            subStmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
        SQLExpression keyIdExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valTbl.getMemberMapping(valKeyMmd));
        if (keyIsUnbound) {
            // Bind the variable in the QueryGenerator
            stmt.getQueryGenerator().bindVariable(keyVarName, keyCmd, keyIdExpr.getSQLTable(), keyIdExpr.getJavaTypeMapping());
        } else {
            // Add restrict to key TODO Add join to keyTbl if present
            subStmt.whereAnd(keyIdExpr.eq(keyExpr), true);
        }
    } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
        DatastoreClass keyTbl = storeMgr.getDatastoreClass(mmd.getMap().getKeyType(), clr);
        JavaTypeMapping ownerMapping = null;
        if (mmd.getMappedBy() != null) {
            ownerMapping = keyTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = keyTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        AbstractMemberMetaData keyValMmd = keyCmd.getMetaDataForMember(mmd.getValueMetaData().getMappedBy());
        subStmt = new SelectStatement(stmt, storeMgr, keyTbl, null, null);
        subStmt.setClassLoaderResolver(clr);
        JavaTypeMapping oneMapping = storeMgr.getMappingManager().getMapping(Integer.class);
        subStmt.select(exprFactory.newLiteral(subStmt, oneMapping, 1), null);
        // Restrict to map owner (on key table)
        SQLExpression ownerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
        SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
        subStmt.whereAnd(ownerExpr.eq(ownerIdExpr), true);
        SQLExpression valIdExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), keyTbl.getMemberMapping(keyValMmd));
        if (valIsUnbound) {
            // Bind the variable in the QueryGenerator
            stmt.getQueryGenerator().bindVariable(valVarName, valCmd, valIdExpr.getSQLTable(), valIdExpr.getJavaTypeMapping());
        } else {
            // Add restrict to value TODO Add join to valTbl if present
            subStmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
        JavaTypeMapping keyMapping = keyTbl.getIdMapping();
        SQLExpression keyIdExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), keyMapping);
        if (keyIsUnbound) {
            // Bind the variable in the QueryGenerator
            stmt.getQueryGenerator().bindVariable(keyVarName, keyCmd, keyIdExpr.getSQLTable(), keyIdExpr.getJavaTypeMapping());
        } else {
            // Add restrict to key
            subStmt.whereAnd(keyIdExpr.eq(keyExpr), true);
        }
    }
    return new BooleanSubqueryExpression(stmt, "EXISTS", subStmt);
}
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) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) MapTable(org.datanucleus.store.rdbms.table.MapTable) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) BooleanSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) JoinTable(org.datanucleus.store.rdbms.table.JoinTable)

Example 80 with SQLExpressionFactory

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

the class MapContainsEntryMethod method containsAsInnerJoin.

/**
 * Method to return an expression for Map.containsEntry using INNER JOIN to the element.
 * This is only for use when there are no "!containsEntry" and no "OR" operations.
 * Creates SQL by adding INNER JOIN to the join table (where it exists), and also to the value table
 * adding an AND condition on the value (with value of the valueExpr).
 * Returns a BooleanExpression "TRUE" (since the INNER JOIN will guarantee if the entry is
 * contained of not).
 * @param stmt SQLStatement
 * @param mapExpr Map expression
 * @param keyExpr Expression for the key
 * @param valExpr Expression for the value
 * @return Contains expression
 */
protected SQLExpression containsAsInnerJoin(SQLStatement stmt, MapExpression mapExpr, SQLExpression keyExpr, SQLExpression valExpr) {
    boolean keyIsUnbound = (keyExpr instanceof UnboundExpression);
    String keyVarName = null;
    if (keyIsUnbound) {
        keyVarName = ((UnboundExpression) keyExpr).getVariableName();
        NucleusLogger.QUERY.debug(">> Map.containsEntry binding unbound variable " + keyVarName + " using INNER JOIN");
    // TODO What if the variable is declared as a subtype, handle this see CollectionContainsMethod
    }
    boolean valIsUnbound = (valExpr instanceof UnboundExpression);
    String valVarName = null;
    if (valIsUnbound) {
        valVarName = ((UnboundExpression) valExpr).getVariableName();
        NucleusLogger.QUERY.debug(">> Map.containsEntry binding unbound variable " + valVarName + " using INNER JOIN");
    // TODO What if the variable is declared as a subtype, handle this see CollectionContainsMethod
    }
    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
    AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
    AbstractClassMetaData keyCmd = mmd.getMap().getKeyClassMetaData(clr);
    AbstractClassMetaData valCmd = mmd.getMap().getValueClassMetaData(clr);
    if (mmd.getMap().getMapType() == MapType.MAP_TYPE_JOIN) {
        // Map formed in join table - add join to join table, then to key/value tables (if present)
        MapTable mapTbl = (MapTable) storeMgr.getTable(mmd);
        SQLTable joinSqlTbl = stmt.join(JoinType.INNER_JOIN, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), mapTbl, null, mapTbl.getOwnerMapping(), null, null);
        if (valCmd != null) {
            DatastoreClass valTbl = storeMgr.getDatastoreClass(valCmd.getFullClassName(), clr);
            SQLTable valSqlTbl = stmt.join(JoinType.INNER_JOIN, joinSqlTbl, mapTbl.getValueMapping(), valTbl, null, valTbl.getIdMapping(), null, null);
            SQLExpression valIdExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping());
            if (valIsUnbound) {
                // Bind the variable in the QueryGenerator
                stmt.getQueryGenerator().bindVariable(valVarName, valCmd, valIdExpr.getSQLTable(), valIdExpr.getJavaTypeMapping());
            } else {
                // Add restrict to value
                stmt.whereAnd(valIdExpr.eq(valExpr), true);
            }
        } else {
            SQLExpression valIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getValueMapping());
            if (valIsUnbound) {
                // Bind the variable in the QueryGenerator
                stmt.getQueryGenerator().bindVariable(valVarName, null, valIdExpr.getSQLTable(), valIdExpr.getJavaTypeMapping());
            } else {
                // Add restrict to value
                stmt.whereAnd(valIdExpr.eq(valExpr), true);
            }
        }
        if (keyCmd != null) {
            DatastoreClass keyTbl = storeMgr.getDatastoreClass(keyCmd.getFullClassName(), clr);
            SQLTable keySqlTbl = stmt.join(JoinType.INNER_JOIN, joinSqlTbl, mapTbl.getKeyMapping(), keyTbl, null, keyTbl.getIdMapping(), null, null);
            SQLExpression keyIdExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getIdMapping());
            if (keyIsUnbound) {
                // Bind the variable in the QueryGenerator
                stmt.getQueryGenerator().bindVariable(keyVarName, keyCmd, keyIdExpr.getSQLTable(), keyIdExpr.getJavaTypeMapping());
            } else {
                // Add restrict to key
                stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
            }
        } else {
            SQLExpression keyIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getKeyMapping());
            if (keyIsUnbound) {
                // Bind the variable in the QueryGenerator
                stmt.getQueryGenerator().bindVariable(keyVarName, null, keyIdExpr.getSQLTable(), keyIdExpr.getJavaTypeMapping());
            } else {
                // Add restrict to key
                stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
            }
        }
    } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
        // Map formed in value table - add join to value table, then to key table (if present)
        DatastoreClass valTbl = storeMgr.getDatastoreClass(valCmd.getFullClassName(), clr);
        JavaTypeMapping ownerMapping = null;
        if (mmd.getMappedBy() != null) {
            ownerMapping = valTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = valTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        SQLTable valSqlTbl = stmt.join(JoinType.INNER_JOIN, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), valTbl, null, ownerMapping, null, null);
        SQLExpression valIdExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping());
        if (valIsUnbound) {
            // Bind the variable in the QueryGenerator
            stmt.getQueryGenerator().bindVariable(valVarName, valCmd, valIdExpr.getSQLTable(), valIdExpr.getJavaTypeMapping());
        } else {
            // Add restrict to value
            stmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
        if (keyCmd != null) {
            // Add inner join to key table
            AbstractMemberMetaData valKeyMmd = valCmd.getMetaDataForMember(mmd.getKeyMetaData().getMappedBy());
            DatastoreClass keyTbl = storeMgr.getDatastoreClass(keyCmd.getFullClassName(), clr);
            SQLTable keySqlTbl = stmt.join(JoinType.INNER_JOIN, valSqlTbl, valTbl.getMemberMapping(valKeyMmd), keyTbl, null, keyTbl.getIdMapping(), null, null);
            SQLExpression keyIdExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getIdMapping());
            if (keyIsUnbound) {
                // Bind the variable in the QueryGenerator
                stmt.getQueryGenerator().bindVariable(keyVarName, keyCmd, keyIdExpr.getSQLTable(), keyIdExpr.getJavaTypeMapping());
            } else {
                // Add restriction to key
                stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
            }
        } else {
            AbstractMemberMetaData valKeyMmd = valCmd.getMetaDataForMember(mmd.getKeyMetaData().getMappedBy());
            SQLExpression keyIdExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getMemberMapping(valKeyMmd));
            if (keyIsUnbound) {
                // Bind the variable in the QueryGenerator
                stmt.getQueryGenerator().bindVariable(keyVarName, keyCmd, keyIdExpr.getSQLTable(), keyIdExpr.getJavaTypeMapping());
            } else {
                // Add restriction to key
                stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
            }
        }
    } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
        // Map formed in key table - add join to key table then to value table (if present)
        DatastoreClass keyTbl = storeMgr.getDatastoreClass(keyCmd.getFullClassName(), clr);
        AbstractMemberMetaData keyValMmd = keyCmd.getMetaDataForMember(mmd.getValueMetaData().getMappedBy());
        JavaTypeMapping ownerMapping = null;
        if (mmd.getMappedBy() != null) {
            ownerMapping = keyTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = keyTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        SQLTable keySqlTbl = stmt.join(JoinType.INNER_JOIN, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), keyTbl, null, ownerMapping, null, null);
        SQLExpression keyIdExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getIdMapping());
        if (keyIsUnbound) {
            // Bind the variable in the QueryGenerator
            stmt.getQueryGenerator().bindVariable(keyVarName, keyCmd, keyIdExpr.getSQLTable(), keyIdExpr.getJavaTypeMapping());
        } else {
            // Add restrict to key
            stmt.whereAnd(keyIdExpr.eq(keyExpr), true);
        }
        if (valCmd != null) {
            // Add inner join to value table
            DatastoreClass valTbl = storeMgr.getDatastoreClass(valCmd.getFullClassName(), clr);
            SQLTable valSqlTbl = stmt.join(JoinType.INNER_JOIN, keySqlTbl, keyTbl.getMemberMapping(keyValMmd), valTbl, null, valTbl.getIdMapping(), null, null);
            SQLExpression valIdExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping());
            if (valIsUnbound) {
                // Bind the variable in the QueryGenerator
                stmt.getQueryGenerator().bindVariable(valVarName, valCmd, valIdExpr.getSQLTable(), valIdExpr.getJavaTypeMapping());
            } else {
                // Add restrict to value
                stmt.whereAnd(valIdExpr.eq(valExpr), true);
            }
        } else {
            SQLExpression valIdExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getMemberMapping(keyValMmd));
            if (valIsUnbound) {
                // Bind the variable in the QueryGenerator
                stmt.getQueryGenerator().bindVariable(valVarName, null, valIdExpr.getSQLTable(), valIdExpr.getJavaTypeMapping());
            } else {
                // Add restrict to value
                stmt.whereAnd(valIdExpr.eq(valExpr), true);
            }
        }
    }
    JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
    return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, true));
}
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) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) MapTable(org.datanucleus.store.rdbms.table.MapTable) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)111 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)98 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)81 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)49 NucleusException (org.datanucleus.exceptions.NucleusException)42 NumericExpression (org.datanucleus.store.rdbms.sql.expression.NumericExpression)40 ArrayList (java.util.ArrayList)39 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)38 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)35 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)31 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)30 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)28 StringExpression (org.datanucleus.store.rdbms.sql.expression.StringExpression)23 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)22 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)20 IntegerLiteral (org.datanucleus.store.rdbms.sql.expression.IntegerLiteral)20 NullLiteral (org.datanucleus.store.rdbms.sql.expression.NullLiteral)19 SQLLiteral (org.datanucleus.store.rdbms.sql.expression.SQLLiteral)17 BigInteger (java.math.BigInteger)16 StringLiteral (org.datanucleus.store.rdbms.sql.expression.StringLiteral)16