protected static Object getObjectUsingNondurableIdForResult(
      final Result result,
      final AbstractClassMetaData cmd,
      final ExecutionContext ec,
      boolean ignoreCache,
      final int[] fpMembers,
      String tableName,
      StoreManager storeMgr,
      Table table) {
    if (cmd.hasDiscriminatorStrategy()) {
      // Check the class for this discriminator value
      String familyName = HBaseUtils.getFamilyNameForColumn(table.getDiscriminatorColumn());
      String columnName = HBaseUtils.getQualifierNameForColumn(table.getDiscriminatorColumn());
      Object discValue = new String(result.getValue(familyName.getBytes(), columnName.getBytes()));
      if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.CLASS_NAME
          && !cmd.getFullClassName().equals(discValue)) {
        return null;
      } else if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.VALUE_MAP
          && !cmd.getDiscriminatorValue().equals(discValue)) {
        return null;
      }
    }

    final FieldManager fm = new FetchFieldManager(ec, cmd, result, table);
    SCOID id = new SCOID(cmd.getFullClassName());
    Object pc =
        ec.findObject(
            id,
            new FieldValues() {
              // ObjectProvider calls the fetchFields method
              public void fetchFields(ObjectProvider op) {
                op.replaceFields(fpMembers, fm);
              }

              public void fetchNonLoadedFields(ObjectProvider op) {
                op.replaceNonLoadedFields(fpMembers, fm);
              }

              public FetchPlan getFetchPlanForLoading() {
                return null;
              }
            },
            null,
            ignoreCache,
            false);

    if (cmd.isVersioned()) {
      // Set the version on the object
      ObjectProvider op = ec.findObjectProvider(pc);
      Object version = null;
      VersionMetaData vermd = cmd.getVersionMetaDataForClass();
      if (vermd.getFieldName() != null) {
        // Set the version from the field value
        AbstractMemberMetaData verMmd = cmd.getMetaDataForMember(vermd.getFieldName());
        version = op.provideField(verMmd.getAbsoluteFieldNumber());
      } else {
        // Get the surrogate version from the datastore
        version = HBaseUtils.getSurrogateVersionForObject(cmd, result, tableName, storeMgr);
      }
      op.setVersion(version);
    }

    if (result.getRow() != null) {
      ObjectProvider sm = ec.findObjectProvider(pc);
      sm.setAssociatedValue("HBASE_ROW_KEY", result.getRow());
    }

    return pc;
  }
  /**
   * Method to return an expression for Map.containsValue 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}
   * </pre>
   *   <li><b>Map with key stored in value</b>
   *       <pre>
   * SELECT 1 FROM VAL_TABLE A0_SUB INNER JOIN KEY_TBL B0 ON ...
   * WHERE B0.JOIN_OWN_ID = A0.ID AND A0_SUB.ID = {valExpr}
   * </pre>
   *   <li><b>Map of value stored in key</b>
   *       <pre>
   * SELECT 1 FROM VAL_TABLE A0_SUB
   * WHERE A0_SUB.OWN_ID = A0.ID AND A0_SUB.ID = {valExpr}
   * </pre>
   * </ul>
   *
   * and returns a BooleanSubqueryExpression ("EXISTS (subquery)")
   *
   * @param mapExpr Map expression
   * @param valExpr Expression for the value
   * @return Contains expression
   */
  protected SQLExpression containsAsSubquery(MapExpression mapExpr, SQLExpression valExpr) {
    boolean valIsUnbound = (valExpr instanceof UnboundExpression);
    String varName = null;
    if (valIsUnbound) {
      varName = ((UnboundExpression) valExpr).getVariableName();
      NucleusLogger.QUERY.debug(
          "map.containsValue binding unbound variable " + varName + " using SUBQUERY");
      // TODO What if the variable is declared as a subtype, handle this see
      // CollectionContainsMethod
    }

    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    MetaDataManager mmgr = storeMgr.getMetaDataManager();
    AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
    AbstractClassMetaData valCmd = mmd.getMap().getValueClassMetaData(clr, mmgr);
    MapTable joinTbl = (MapTable) storeMgr.getTable(mmd);
    SQLStatement subStmt = null;
    if (mmd.getMap().getMapType() == MapType.MAP_TYPE_JOIN) {
      // JoinTable Map
      if (valCmd == null) {
        // Map<?, Non-PC>
        subStmt = new SQLStatement(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 map 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);

        if (valIsUnbound) {
          // Bind the variable in the QueryGenerator
          valExpr =
              exprFactory.newExpression(
                  subStmt, subStmt.getPrimaryTable(), joinTbl.getValueMapping());
          stmt.getQueryGenerator()
              .bindVariable(varName, null, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
        } else {
          // Add restrict to value
          SQLExpression valIdExpr =
              exprFactory.newExpression(
                  subStmt, subStmt.getPrimaryTable(), joinTbl.getValueMapping());
          subStmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
      } else {
        // Map<?, PC>
        DatastoreClass valTbl = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
        subStmt = new SQLStatement(stmt, storeMgr, valTbl, null, null);
        subStmt.setClassLoaderResolver(clr);
        JavaTypeMapping oneMapping = storeMgr.getMappingManager().getMapping(Integer.class);
        subStmt.select(exprFactory.newLiteral(subStmt, oneMapping, 1), null);

        // Join to join table
        SQLTable joinSqlTbl =
            subStmt.innerJoin(
                subStmt.getPrimaryTable(),
                valTbl.getIdMapping(),
                joinTbl,
                null,
                joinTbl.getValueMapping(),
                null,
                null);

        // Restrict to map owner
        JavaTypeMapping ownerMapping = joinTbl.getOwnerMapping();
        SQLExpression ownerExpr = exprFactory.newExpression(subStmt, joinSqlTbl, ownerMapping);
        SQLExpression ownerIdExpr =
            exprFactory.newExpression(
                stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
        subStmt.whereAnd(ownerExpr.eq(ownerIdExpr), true);

        if (valIsUnbound) {
          // Bind the variable in the QueryGenerator
          valExpr =
              exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valTbl.getIdMapping());
          stmt.getQueryGenerator()
              .bindVariable(varName, valCmd, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
        } else {
          // Add restrict to value
          SQLExpression valIdExpr =
              exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valTbl.getIdMapping());
          subStmt.whereAnd(valIdExpr.eq(valExpr), 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);
      JavaTypeMapping ownerMapping = null;
      if (mmd.getMappedBy() != null) {
        ownerMapping = valTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
      } else {
        ownerMapping = valTbl.getExternalMapping(mmd, MappingConsumer.MAPPING_TYPE_EXTERNAL_FK);
      }

      subStmt = new SQLStatement(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)
      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);

      if (valIsUnbound) {
        // Bind the variable in the QueryGenerator
        valExpr =
            exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valTbl.getIdMapping());
        stmt.getQueryGenerator()
            .bindVariable(varName, valCmd, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
      } else {
        // Add restrict to value
        JavaTypeMapping valMapping = valTbl.getIdMapping();
        SQLExpression valIdExpr =
            exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valMapping);
        subStmt.whereAnd(valIdExpr.eq(valExpr), true);
      }
    } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
      AbstractClassMetaData keyCmd = mmd.getMap().getKeyClassMetaData(clr, mmgr);
      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, MappingConsumer.MAPPING_TYPE_EXTERNAL_FK);
      }

      AbstractMemberMetaData keyValMmd =
          keyCmd.getMetaDataForMember(mmd.getValueMetaData().getMappedBy());
      if (valCmd == null) {
        subStmt = new SQLStatement(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);

        if (valIsUnbound) {
          // Bind the variable in the QueryGenerator
          valExpr =
              exprFactory.newExpression(
                  subStmt, subStmt.getPrimaryTable(), keyTbl.getMemberMapping(keyValMmd));
          stmt.getQueryGenerator()
              .bindVariable(varName, null, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
        } else {
          // Add restrict to value
          JavaTypeMapping valMapping = keyTbl.getMemberMapping(keyValMmd);
          SQLExpression valIdExpr =
              exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valMapping);
          subStmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
      } else {
        DatastoreClass valTbl = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
        subStmt = new SQLStatement(stmt, storeMgr, valTbl, null, null);
        subStmt.setClassLoaderResolver(clr);
        JavaTypeMapping oneMapping = storeMgr.getMappingManager().getMapping(Integer.class);
        subStmt.select(exprFactory.newLiteral(subStmt, oneMapping, 1), null);

        // Join to key table
        SQLTable keySqlTbl =
            subStmt.innerJoin(
                subStmt.getPrimaryTable(),
                valTbl.getIdMapping(),
                keyTbl,
                null,
                keyTbl.getMemberMapping(keyValMmd),
                null,
                null);

        // Restrict to map owner (on key table)
        SQLExpression ownerExpr = exprFactory.newExpression(subStmt, keySqlTbl, ownerMapping);
        SQLExpression ownerIdExpr =
            exprFactory.newExpression(
                stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
        subStmt.whereAnd(ownerExpr.eq(ownerIdExpr), true);

        if (valIsUnbound) {
          // Bind the variable in the QueryGenerator
          valExpr =
              exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valTbl.getIdMapping());
          stmt.getQueryGenerator()
              .bindVariable(varName, valCmd, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
        } else {
          // Add restrict to value
          SQLExpression valIdExpr =
              exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valTbl.getIdMapping());
          subStmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
      }
    }

    return new BooleanSubqueryExpression(stmt, "EXISTS", subStmt);
  }
  protected static Object getObjectUsingDatastoreIdForResult(
      final Result result,
      final AbstractClassMetaData cmd,
      final ExecutionContext ec,
      boolean ignoreCache,
      final int[] fpMembers,
      String tableName,
      StoreManager storeMgr,
      Table table) {
    if (cmd.hasDiscriminatorStrategy()) {
      // Check the class for this discriminator value
      String familyName = HBaseUtils.getFamilyNameForColumn(table.getDiscriminatorColumn());
      String columnName = HBaseUtils.getQualifierNameForColumn(table.getDiscriminatorColumn());
      Object discValue = new String(result.getValue(familyName.getBytes(), columnName.getBytes()));
      if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.CLASS_NAME
          && !cmd.getFullClassName().equals(discValue)) {
        return null;
      } else if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.VALUE_MAP
          && !cmd.getDiscriminatorValue().equals(discValue)) {
        return null;
      }
    }

    String dsidFamilyName = HBaseUtils.getFamilyNameForColumn(table.getDatastoreIdColumn());
    String dsidColumnName = HBaseUtils.getQualifierNameForColumn(table.getDatastoreIdColumn());
    Object id = null;
    try {
      byte[] bytes = result.getValue(dsidFamilyName.getBytes(), dsidColumnName.getBytes());
      if (bytes != null) {
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bis);
        Object key = ois.readObject();
        id =
            ec.getNucleusContext().getIdentityManager().getDatastoreId(cmd.getFullClassName(), key);
        ois.close();
        bis.close();
      } else {
        throw new NucleusException(
            "Retrieved identity for family="
                + dsidFamilyName
                + " column="
                + dsidColumnName
                + " IS NULL");
      }
    } catch (Exception e) {
      throw new NucleusException(e.getMessage(), e);
    }

    final FieldManager fm = new FetchFieldManager(ec, cmd, result, table);
    Object pc =
        ec.findObject(
            id,
            new FieldValues() {
              // ObjectProvider calls the fetchFields method
              public void fetchFields(ObjectProvider op) {
                op.replaceFields(fpMembers, fm);
              }

              public void fetchNonLoadedFields(ObjectProvider op) {
                op.replaceNonLoadedFields(fpMembers, fm);
              }

              public FetchPlan getFetchPlanForLoading() {
                return null;
              }
            },
            null,
            ignoreCache,
            false);

    if (cmd.isVersioned()) {
      // Set the version on the object
      ObjectProvider op = ec.findObjectProvider(pc);
      Object version = null;
      VersionMetaData vermd = cmd.getVersionMetaDataForClass();
      if (vermd.getFieldName() != null) {
        // Set the version from the field value
        AbstractMemberMetaData verMmd = cmd.getMetaDataForMember(vermd.getFieldName());
        version = op.provideField(verMmd.getAbsoluteFieldNumber());
      } else {
        // Get the surrogate version from the datastore
        version = HBaseUtils.getSurrogateVersionForObject(cmd, result, tableName, storeMgr);
      }
      op.setVersion(version);
    }

    if (result.getRow() != null) {
      ObjectProvider sm = ec.findObjectProvider(pc);
      sm.setAssociatedValue("HBASE_ROW_KEY", result.getRow());
    }

    return pc;
  }
  /**
   * Method to return an expression for Map.containsValue using INNER JOIN to the element. This is
   * only for use when there are no "!containsValue" 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 value is contained of not).
   *
   * @param mapExpr Map expression
   * @param valExpr Expression for the value
   * @return Contains expression
   */
  protected SQLExpression containsAsInnerJoin(MapExpression mapExpr, SQLExpression valExpr) {
    boolean valIsUnbound = (valExpr instanceof UnboundExpression);
    String varName = null;
    String valAlias = null;
    if (valIsUnbound) {
      varName = ((UnboundExpression) valExpr).getVariableName();
      NucleusLogger.QUERY.debug(
          "map.containsValue("
              + valExpr
              + ") binding unbound variable "
              + varName
              + " using INNER JOIN");
      // TODO What if the variable is declared as a subtype, handle this see
      // CollectionContainsMethod
    } else if (!stmt.getQueryGenerator().hasExplicitJoins()) {
      JoinType joinType = stmt.getJoinTypeForTable(valExpr.getSQLTable());
      if (joinType == JoinType.CROSS_JOIN) {
        // Value is currently joined via CROSS JOIN, so remove it (and use INNER JOIN below)
        valAlias = stmt.removeCrossJoin(valExpr.getSQLTable());
        valIsUnbound = true;
        NucleusLogger.QUERY.debug(
            "map.containsValue("
                + valExpr
                + ") was previously bound as CROSS JOIN but changing to INNER JOIN");
      }

      // TODO If owner is joined via CROSS JOIN and value is already present then remove CROSS JOIN
      // and join via INNER JOIN
    }

    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    MetaDataManager mmgr = storeMgr.getMetaDataManager();
    AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
    AbstractClassMetaData valCmd = mmd.getMap().getValueClassMetaData(clr, mmgr);
    if (mmd.getMap().getMapType() == MapType.MAP_TYPE_JOIN) {
      // Map formed in join table - add join to join table, then to value table (if present)
      MapTable mapTbl = (MapTable) storeMgr.getTable(mmd);
      SQLTable joinSqlTbl =
          stmt.innerJoin(
              mapExpr.getSQLTable(),
              mapExpr.getSQLTable().getTable().getIdMapping(),
              mapTbl,
              null,
              mapTbl.getOwnerMapping(),
              null,
              null);
      if (valCmd != null) {
        if (valIsUnbound) {
          DatastoreClass valTbl = storeMgr.getDatastoreClass(valCmd.getFullClassName(), clr);
          SQLTable valSqlTbl =
              stmt.innerJoin(
                  joinSqlTbl,
                  mapTbl.getValueMapping(),
                  valTbl,
                  valAlias,
                  valTbl.getIdMapping(),
                  null,
                  null);

          // Bind the variable in the QueryGenerator
          valExpr = exprFactory.newExpression(stmt, valSqlTbl, valSqlTbl.getTable().getIdMapping());
          stmt.getQueryGenerator()
              .bindVariable(varName, valCmd, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
        } else {
          // Add restrict to value
          SQLExpression valIdExpr =
              exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getValueMapping());
          stmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
      } else {
        if (valIsUnbound) {
          // Bind the variable in the QueryGenerator
          valExpr = exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getValueMapping());
          stmt.getQueryGenerator()
              .bindVariable(varName, null, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
        } else {
          // Add restrict to value
          SQLExpression valIdExpr =
              exprFactory.newExpression(stmt, joinSqlTbl, mapTbl.getValueMapping());
          stmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
      }
    } else if (mmd.getMap().getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
      // Map formed in value table - add join to value table
      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, MappingConsumer.MAPPING_TYPE_EXTERNAL_FK);
      }
      SQLTable valSqlTbl =
          stmt.innerJoin(
              mapExpr.getSQLTable(),
              mapExpr.getSQLTable().getTable().getIdMapping(),
              valTbl,
              valAlias,
              ownerMapping,
              null,
              null);

      if (valIsUnbound) {
        // Bind the variable in the QueryGenerator
        valExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping());
        stmt.getQueryGenerator()
            .bindVariable(varName, valCmd, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
      } else {
        // Add restrict to value
        SQLExpression valIdExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping());
        stmt.whereAnd(valIdExpr.eq(valExpr), 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
      AbstractClassMetaData keyCmd = mmd.getMap().getKeyClassMetaData(clr, mmgr);
      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, MappingConsumer.MAPPING_TYPE_EXTERNAL_FK);
      }
      SQLTable keySqlTbl =
          stmt.innerJoin(
              mapExpr.getSQLTable(),
              mapExpr.getSQLTable().getTable().getIdMapping(),
              keyTbl,
              null,
              ownerMapping,
              null,
              null);

      if (valCmd != null) {
        DatastoreClass valTbl = storeMgr.getDatastoreClass(valCmd.getFullClassName(), clr);
        SQLTable valSqlTbl =
            stmt.innerJoin(
                keySqlTbl,
                keyTbl.getMemberMapping(keyValMmd),
                valTbl,
                valAlias,
                valTbl.getIdMapping(),
                null,
                null);

        if (valIsUnbound) {
          // Bind the variable in the QueryGenerator
          valExpr = exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping());
          stmt.getQueryGenerator()
              .bindVariable(varName, valCmd, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
        } else {
          // Add restrict to value
          SQLExpression valIdExpr =
              exprFactory.newExpression(stmt, valSqlTbl, valTbl.getIdMapping());
          stmt.whereAnd(valIdExpr.eq(valExpr), true);
        }
      } else {
        if (valIsUnbound) {
          // Bind the variable in the QueryGenerator
          valExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getMemberMapping(keyValMmd));
          stmt.getQueryGenerator()
              .bindVariable(varName, null, valExpr.getSQLTable(), valExpr.getJavaTypeMapping());
        } else {
          // Add restrict to value
          SQLExpression valIdExpr =
              exprFactory.newExpression(stmt, keySqlTbl, keyTbl.getMemberMapping(keyValMmd));
          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));
  }