예제 #1
0
  protected Expression processPropertyTracedownTooneOptimized(
      Attribute<?, ?> attr, Expression builder, List<Parameter> parameters) {
    ConditionQuery subQuery = getTraceDownQuery();

    Expression finalExp = null;
    for (PropertyCondition subPc : subQuery.getConditions()) {
      if (subPc.isReturnSimpleExpression()) {
        Expression subExp = subPc.processProperty(builder.get(getProp()), parameters);
        if (finalExp == null) {
          finalExp = subExp;
        } else {
          finalExp = finalExp.and(subExp);
        }
      } else {
        // low-performance query since an extra layer of exists added
        // but this is the only way to make it work.
        // this situation is rare. So we may do not need to optimize it
        Expression subBuilder = new ExpressionBuilder();
        Expression subExp = subPc.processProperty(subBuilder, parameters);
        ReportQuery childQuery = formRelationReportQuery(attr, subBuilder);
        childQuery.retrievePrimaryKeys();
        childQuery.setSelectionCriteria(subBuilder.equal(builder.get(getProp())).and(subExp));
        if (finalExp == null) {
          finalExp = builder.exists(childQuery);
        } else {
          finalExp = finalExp.and(builder.exists(childQuery));
        }
      }
    }
    return finalExp;
  }
  public void getOrderLargerThan() {
    EntityManager em = createEntityManager();

    ExpressionBuilder builder1 = new ExpressionBuilder(Order.class);
    ExpressionBuilder builder2 = new ExpressionBuilder(Order.class);
    Expression o1Quantity = builder1.get("quantity");
    Expression o2Quantity = builder2.get("quantity");
    Expression quantityComparison = o1Quantity.greaterThan(o2Quantity);
    Expression o2CustomerName = builder2.get("customer").get("name");
    Expression nameComparison = o2CustomerName.equal("Jane Smith");
    Expression whereClause = quantityComparison.and(nameComparison);

    ReadAllQuery raq = new ReadAllQuery();
    raq.setSelectionCriteria(whereClause);
    raq.setReferenceClass(Order.class);
    raq.useDistinct();
    List expectedResult = (List) getServerSession().executeQuery(raq);

    String ejbqlString =
        "SELECT DISTINCT o1 FROM OrderBean o1, OrderBean o2 WHERE o1.quantity > o2.quantity AND"
            + " o2.customer.name = 'Jane Smith' ";
    List result = em.createQuery(ejbqlString).getResultList();
    // only 1 order
    Assert.assertEquals(
        "Get order larger than test failed: data validation error", result.size(), 1);
    Assert.assertTrue(
        "Get order larger than test failed", comparer.compareObjects(expectedResult, result));
  }
  public void findEmployeeWithWorkPhone2258812() {
    EntityManager em = createEntityManager();
    ExpressionBuilder builder = new ExpressionBuilder();
    Expression whereClause1 = builder.anyOf("phoneNumbers").get("type").equal("Work");
    Expression whereClause2 = builder.anyOf("phoneNumbers").get("number").equal("2258812");

    ReadAllQuery raq = new ReadAllQuery(Employee.class);
    raq.setSelectionCriteria(whereClause1.and(whereClause2));
    if (usesSOP() && getServerSession().getPlatform().isOracle()) {
      // distinct is incompatible with blob in selection clause on Oracle
    } else {
      raq.useDistinct();
    }

    List expectedResult = (List) getServerSession().executeQuery(raq);

    String ejbqlString;
    if (usesSOP() && getServerSession().getPlatform().isOracle()) {
      // distinct is incompatible with blob in selection clause on Oracle
      ejbqlString =
          "SELECT e FROM Employee e JOIN e.phoneNumbers p "
              + "WHERE p.type = 'Work' AND p.number = '2258812' ";
    } else {
      ejbqlString =
          "SELECT DISTINCT e FROM Employee e JOIN e.phoneNumbers p "
              + "WHERE p.type = 'Work' AND p.number = '2258812' ";
    }
    List result = em.createQuery(ejbqlString).getResultList();
    // 8 employees
    Assert.assertEquals(
        "Find employee with 2258812 number test failed: data validation error", result.size(), 8);
    Assert.assertTrue(
        "Find employee with 2258812 number test failed",
        comparer.compareObjects(expectedResult, result));
  }
 /**
  * INTERNAL: this returns a single expression to represent the join from the main table to all
  * child descriptor tables Only if outer joins should be printed in the where clause
  *
  * @return Expression
  */
 public Expression getTreatCriteria() {
   if (getDescriptor() == null) {
     return null;
   }
   // need to build this using just the multiple tables on this descriptor not included in the
   // parent's join expression
   Expression criteria = null;
   if (getSession().getPlatform().shouldPrintOuterJoinInWhereClause()) {
     Vector tables = getDescriptor().getTables(); // This child's tables
     ClassDescriptor parentDescriptor = this.typeExpressionBase.getDescriptor();
     int tablesSize = tables.size();
     if (parentDescriptor.hasInheritance()
         && parentDescriptor.getInheritancePolicy().hasMultipleTableChild()) {
       // look up the joins from the parent descriptor to our tables.
       for (int i = 0; i < tablesSize; i++) {
         DatabaseTable table = (DatabaseTable) tables.elementAt(i);
         Expression joinExpression =
             parentDescriptor.getInheritancePolicy().getChildrenTablesJoinExpressions().get(table);
         // Some of our tables might be the in our parent as well, so ignore the lack of a
         // joinExpression
         if (joinExpression != null) {
           joinExpression = this.baseExpression.twist(joinExpression, this);
           if (shouldUseOuterJoin()) {
             joinExpression = joinExpression.convertToUseOuterJoin();
           }
           criteria = joinExpression.and(criteria);
         }
       }
     }
   }
   return criteria;
 }
  /**
   * INTERNAL: Return the expression to join the main table of this node to any auxiliary tables.
   */
  public Expression additionalExpressionCriteria() {
    if (getDescriptor() == null) {
      return null;
    }

    Expression criteria = getDescriptor().getQueryManager().getAdditionalJoinExpression();
    if (criteria != null) {
      criteria = getBaseExpression().twist(criteria, this);
      if (shouldUseOuterJoin() && getSession().getPlatform().shouldPrintOuterJoinInWhereClause()) {
        criteria.convertToUseOuterJoin();
      }
    }
    if (getSession().getPlatform().shouldPrintOuterJoinInWhereClause()) {
      if (isUsingOuterJoinForMultitableInheritance()) {
        Expression childrenCriteria =
            getDescriptor().getInheritancePolicy().getChildrenJoinExpression();
        childrenCriteria = getBaseExpression().twist(childrenCriteria, this);
        childrenCriteria.convertToUseOuterJoin();
        if (criteria == null) {
          criteria = childrenCriteria;
        } else {
          criteria = criteria.and(childrenCriteria);
        }
      }
    }
    if ((getDescriptor() != null) && (getDescriptor().getHistoryPolicy() != null)) {
      Expression historyCriteria =
          getDescriptor().getHistoryPolicy().additionalHistoryExpression(this);
      if (criteria != null) {
        criteria = criteria.and(historyCriteria);
      } else {
        criteria = historyCriteria;
      }
    }
    return criteria;
  }
 public void setup() {
   super.setup();
   ExpressionBuilder employees = new ExpressionBuilder();
   expression = employees.get("firstName").equal("Charles");
   expression = expression.and(employees.get("lastName").equal("Chanley"));
   // ensure our employee is in one of the distributed caches
   DistributedServer server =
       (DistributedServer) DistributedServersModel.getDistributedServers().get(0);
   Object result = server.getDistributedSession().readObject(Employee.class, expression);
   ((Employee) result).getManagedEmployees();
   ((Employee) result).getPhoneNumbers();
   ((Employee) result).getAddress();
   ((Employee) result).getManager();
   ((Employee) result).getProjects();
   ((Employee) result).getResponsibilitiesList();
 }
  public void testCountExpression() {
    EntityManager em = createEntityManager();

    ReportQuery query = new ReportQuery(Employee.class, new ExpressionBuilder());
    Expression whereClause1 =
        query.getExpressionBuilder().get("address").get("province").equal("QUE");
    Expression whereClause2 =
        query.getExpressionBuilder().get("address").get("city").equal("Montreal");
    query.setSelectionCriteria(whereClause1.and(whereClause2));
    query.addCount(
        "areaCodeCount",
        query.getExpressionBuilder().anyOf("phoneNumbers").get("areaCode"),
        Long.class);
    query.returnSingleResult();
    Long expectedResult =
        (Long) ((ReportQueryResult) getServerSession().executeQuery(query)).get("areaCodeCount");

    String ejbqlString =
        "SELECT COUNT(p.areaCode) FROM Employee e JOIN e.phoneNumbers p JOIN e.address a "
            + " WHERE a.province='QUE' AND a.city='Montreal'";
    Long result = (Long) em.createQuery(ejbqlString).getSingleResult();

    String alternateEjbqlString =
        "SELECT COUNT(p) FROM Employee e JOIN e.phoneNumbers p JOIN e.address a "
            + " WHERE a.province='QUE' AND a.city='Montreal' AND p.areaCode IS NOT NULL";
    Long alternateResult = (Long) em.createQuery(alternateEjbqlString).getSingleResult();

    Assert.assertTrue(
        "Count expression test failed: data validation error, ReportQuery returned 0",
        expectedResult.intValue() > 0);
    Assert.assertTrue(
        "Count expression test failed: data validation error, first JPQL returned 0",
        result.intValue() > 0);
    Assert.assertTrue(
        "Count expression test failed: data validation error, second JPQL returned 0",
        alternateResult.intValue() > 0);
    Assert.assertTrue(
        "Count expression test failed: two equivalent ejb queries return different results",
        alternateResult.equals(result));
    Assert.assertEquals("Count expression test failed", expectedResult, result);
  }
예제 #8
0
  protected Expression processPropertyTracedownToManyNone(
      Attribute<?, ?> attr, Expression builder, List<Parameter> parameters) {
    ConditionQuery subQuery = getTraceDownQuery();
    // subQuery.setPrefix(getQuery().getPrefix()+parameters.size()+"_");
    Expression subBuilder = new ExpressionBuilder();
    List<Expression> childExps = new ArrayList<Expression>(3);
    for (PropertyCondition subPc : subQuery.getConditions()) {
      Expression subExp = subPc.processProperty(subBuilder, parameters);
      childExps.add(subExp);
    }
    if (childExps.isEmpty()) {
      throw new InvalidQueryException("No expression from subquery.");
    }
    Expression finalExp = childExps.get(0);

    for (int i = 1; i < childExps.size(); i++) {
      finalExp = finalExp.and(childExps.get(i));
    }

    return builder.noneOf(getProp(), finalExp);
  }
  /**
   * INTERNAL: Selection criteria is created with source foreign keys and target keys. This criteria
   * is then used to read target records from the table.
   */
  public void initializeSelectionCriteria(AbstractSession session) {
    Expression selectionCriteria = null;
    Expression expression;

    ExpressionBuilder expBuilder = new ExpressionBuilder();

    Iterator sourceKeysEnum = getSourceToTargetQueryKeyNames().keySet().iterator();

    while (sourceKeysEnum.hasNext()) {
      DatabaseField sourceKey = (DatabaseField) sourceKeysEnum.next();
      String target = (String) this.getSourceToTargetQueryKeyNames().get(sourceKey);
      expression = expBuilder.getParameter(sourceKey).equal(expBuilder.get(target));

      if (selectionCriteria == null) {
        selectionCriteria = expression;
      } else {
        selectionCriteria = expression.and(selectionCriteria);
      }
    }

    setSelectionCriteria(selectionCriteria);
  }
예제 #10
0
  protected Expression processPropertyTracedownToManySomeOptimized(
      Attribute<?, ?> attr, Expression builder, List<Parameter> parameters) {
    ConditionQuery subQuery = getTraceDownQuery();
    // subQuery.setPrefix(getQuery().getPrefix()+parameters.size()+"_");
    Expression prefixExp = builder.anyOf(getProp());

    List<Expression> complexExps = new ArrayList<Expression>();

    for (PropertyCondition subPc : subQuery.getConditions()) {
      Expression subExp = subPc.processProperty(prefixExp, parameters);
      complexExps.add(subExp);
    }
    Expression finalExp = null;
    if (complexExps.isEmpty()) {
      throw new InvalidQueryException("No expression from subquery.");
    }
    finalExp = complexExps.get(0);
    for (int i = 1; i < complexExps.size(); i++) {
      finalExp = finalExp.and(complexExps.get(i));
    }
    return finalExp;
  }
  public void testComplexDeleteExpression() {
    if (isOnServer()) {
      // Not work on server.
      return;
    }
    if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
      getServerSession()
          .logMessage(
              "Test testComplexDeleteExpression skipped for this platform, "
                  + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
      return;
    }

    JpaEntityManager em = (org.eclipse.persistence.jpa.JpaEntityManager) createEntityManager();
    try {
      beginTransaction(em);
      String orderString = "DELETE FROM OrderBean o WHERE o.customer.name ='Karen McDonald' ";
      em.createQuery(orderString).executeUpdate();
      orderString = "DELETE FROM OrderBean o WHERE o.billedCustomer.name ='Karen McDonald' ";
      em.createQuery(orderString).executeUpdate();
      String ejbqlString =
          "DELETE FROM Customer c WHERE c.name='Karen McDonald' AND c.orders IS EMPTY";
      int result = em.createQuery(ejbqlString).executeUpdate();
      Assert.assertEquals(
          "Complex Delete Expression test failed: customer to delete not found", 1, result);
      em.flush();

      ReadAllQuery raq = new ReadAllQuery(Customer.class, new ExpressionBuilder());
      Expression whereClause1 = raq.getExpressionBuilder().get("name").equal("Karen McDonald");
      Expression whereClause2 = raq.getExpressionBuilder().isEmpty("orders");
      raq.setSelectionCriteria(whereClause1.and(whereClause2));
      List customerFound = (List) em.getActiveSession().executeQuery(raq);
      Assert.assertEquals("Complex Delete Expression test failed", 0, customerFound.size());
    } finally {
      rollbackTransaction(em);
    }
  }
  /**
   * INTERNAL: For CR#2456 if this is part of an objExp.equal(objExp), do not need to add additional
   * expressions to normalizer both times, and the foreign key join replaces the equal expression.
   */
  public Expression normalize(ExpressionNormalizer normalizer, Vector foreignKeyJoinPointer) {
    if (hasBeenNormalized()) {
      return this;
    }
    super.normalize(normalizer);

    setHasBeenNormalized(true);
    if ((getMapping() != null) && getMapping().isDirectToXMLTypeMapping()) {
      normalizer.getStatement().setRequiresAliases(true);
    }

    // Check if any joins need to be added.
    if (isAttribute()) {
      return this;
    }

    // If the mapping is 'ref' or 'structure', no join needed.
    if ((getMapping() != null)
        && (getMapping().isReferenceMapping() || getMapping().isStructureMapping())) {
      normalizer.getStatement().setRequiresAliases(true);
      return this;
    }

    // Compute if a distinct is required during normalization.
    if (shouldQueryToManyRelationship()
        && (!normalizer.getStatement().isDistinctComputed())
        && (!normalizer.getStatement().isAggregateSelect())) {
      normalizer.getStatement().useDistinct();
    }

    // Turn off DISTINCT if nestedTableMapping is used (not supported by Oracle 8.1.5).
    if ((getMapping() != null) && getMapping().isNestedTableMapping()) {
      // There are two types of nested tables, one used by clients, one used by mappings, do nothing
      // in the mapping case.
      if (!shouldQueryToManyRelationship()) {
        return this;
      }
      normalizer.getStatement().dontUseDistinct();
    }

    Expression mappingExpression = mappingCriteria();
    if (mappingExpression != null) {
      mappingExpression = mappingExpression.normalize(normalizer);
    }
    if (mappingExpression != null) {
      // If the join was an outer join we must not add the join criteria to the where clause,
      // if the platform prints the join in the from clause.
      if (shouldUseOuterJoin() && (getSession().getPlatform().isInformixOuterJoin())) {
        normalizer.getStatement().getOuterJoinExpressions().addElement(this);
        normalizer.getStatement().getOuterJoinedMappingCriteria().addElement(mappingExpression);
        normalizer.addAdditionalExpression(mappingExpression.and(additionalExpressionCriteria()));
        return this;
      } else if ((shouldUseOuterJoin() || isUsingOuterJoinForMultitableInheritance())
          && (!getSession().getPlatform().shouldPrintOuterJoinInWhereClause())) {
        if (shouldUseOuterJoin()) {
          normalizer.getStatement().getOuterJoinExpressions().addElement(this);
          normalizer.getStatement().getOuterJoinedMappingCriteria().addElement(mappingExpression);
          normalizer
              .getStatement()
              .getOuterJoinedAdditionalJoinCriteria()
              .addElement(additionalExpressionCriteriaMap());
          normalizer.getStatement().getDescriptorsForMultitableInheritanceOnly().add(null);
          return this;
        } else {
          if (isUsingOuterJoinForMultitableInheritance()) {
            normalizer.getStatement().getOuterJoinExpressions().addElement(null);
            normalizer.getStatement().getOuterJoinedMappingCriteria().addElement(null);
            normalizer
                .getStatement()
                .getOuterJoinedAdditionalJoinCriteria()
                .addElement(additionalExpressionCriteriaMap());
            normalizer
                .getStatement()
                .getDescriptorsForMultitableInheritanceOnly()
                .add(getMapping().getReferenceDescriptor());
            // fall through to the main case
          }
        }
      }

      // This must be added even if outer. Actually it should be converted to use a right outer
      // join, but that gets complex
      // so we do not support this current which is a limitation in some cases.
      if (foreignKeyJoinPointer != null) {
        // If this expression is right side of an objExp.equal(objExp), one
        // need not add additionalExpressionCriteria twice.
        // Also the join will replace the original objExp.equal(objExp).
        // For CR#2456.
        foreignKeyJoinPointer.add(mappingExpression);
      } else {
        normalizer.addAdditionalExpression(mappingExpression.and(additionalExpressionCriteria()));
      }
    }

    // For bug 2900974 special code for DirectCollectionMappings moved to printSQL.
    return this;
  }
  public void testGroupByHavingExpression() {
    EntityManager em = createEntityManager();
    boolean testPass = true;

    ReadAllQuery raq = new ReadAllQuery(Employee.class, new ExpressionBuilder());
    Expression whereClause1 = raq.getExpressionBuilder().get("firstName").equal("Bob");
    Expression whereClause2 = raq.getExpressionBuilder().get("lastName").equal("Smith");
    Expression whereClause3 = raq.getExpressionBuilder().get("firstName").equal("John");
    Expression whereClause4 = raq.getExpressionBuilder().get("lastName").equal("Way");

    raq.setSelectionCriteria((whereClause1.and(whereClause2)).or(whereClause3.and(whereClause4)));
    List employees = (List) getServerSession().executeQuery(raq);
    int firstManagerId = ((Employee) employees.get(0)).getId();
    int secondManagerId = ((Employee) employees.get(1)).getId();
    int expectedEmployeesManaged =
        ((Employee) employees.get(0)).getManagedEmployees().size()
            + ((Employee) employees.get(1)).getManagedEmployees().size();
    Vector managerVector = new Vector();
    managerVector.add(firstManagerId);
    managerVector.add(secondManagerId);
    ReportQuery query = new ReportQuery(Employee.class, new ExpressionBuilder());
    query.returnWithoutReportQueryResult();
    query.addGrouping(query.getExpressionBuilder().get("manager").get("id"));
    query.setHavingExpression(
        query.getExpressionBuilder().get("manager").get("id").in(managerVector));
    query.addAttribute("managerId", query.getExpressionBuilder().get("manager").get("id"));
    query.addAverage("salary", Double.class);
    query.addCount("id", Long.class);

    List expectedResult = (List) getServerSession().executeQuery(query);

    String ejbqlString =
        "SELECT e.manager.id, avg(e.salary), count(e) FROM Employee e"
            + " GROUP BY e.manager.id HAVING e.manager.id IN ("
            + firstManagerId
            + ","
            + secondManagerId
            + ")";

    List result = em.createQuery(ejbqlString).getResultList();
    int employeesManaged = 0;
    Iterator expectedResultIterator = expectedResult.iterator();
    Iterator resultIterator = result.iterator();
    if (expectedResult.size() == result.size()) {
      while (resultIterator.hasNext()) {
        Object objectArray[] = (Object[]) expectedResultIterator.next();
        Object otherObjectArray[] = (Object[]) resultIterator.next();
        testPass = testPass && objectArray[0].equals(otherObjectArray[0]);
        testPass = testPass && objectArray[1].equals(otherObjectArray[1]);
        testPass = testPass && objectArray[2].equals(otherObjectArray[2]);
        employeesManaged = ((Long) objectArray[2]).intValue() + employeesManaged;
      }
    } else {
      testPass = false;
    }

    Assert.assertEquals(
        "GroupBy Having expression test failed: data validation error",
        employeesManaged,
        expectedEmployeesManaged);
    Assert.assertTrue("GroupBy Having expression test failed", testPass);
  }
  public Expression normalize(
      ExpressionNormalizer normalizer, Expression base, List<Expression> foreignKeyJoinPointer) {
    // need to determine what type this is, as it may need to change the expression its based off
    // slightly
    if (this.hasBeenNormalized) {
      return this;
    }
    this.hasBeenNormalized = true;

    Expression typeExpression = getTypeClause();
    typeExpression.normalize(normalizer);

    if (this.baseExpression != null) { // should never be null
      // First normalize the base.
      setBaseExpression(this.baseExpression.normalize(normalizer));
      if (getAsOfClause() == null) {
        asOf(this.baseExpression.getAsOfClause());
      }
    }

    // This class has no validation but we should still make the method call for consistency
    // bug # 2956674
    // validation is moved into normalize to ensure that expressions are valid before we attempt to
    // work with them
    validateNode();
    // the following is based on QueryKey.normalize

    SQLSelectStatement statement = normalizer.getStatement();
    // no longer directly normalize the typeExpressionBase, or find a way to use it
    this.typeExpressionBase = (ObjectExpression) this.typeExpressionBase.normalize(normalizer);

    // Normalize the ON clause if present.  Need to use rebuild, not twist as parameters are real
    // parameters.
    if (this.onClause != null) { // not sure this is needed/valid
      this.onClause = this.onClause.normalize(normalizer);
    }

    ClassDescriptor parentDescriptor = this.typeExpressionBase.getDescriptor();
    boolean isSTI = getOwnedSubTables().isEmpty();
    // only really valid if it has inheritance, but better this code than skipping it into the joins

    if (isSTI) {
      if (foreignKeyJoinPointer != null) {
        // If this expression is right side of an objExp.equal(objExp), one
        // need not add additionalExpressionCriteria twice.
        // Also the join will replace the original objExp.equal(objExp).
        // For CR#2456.
        foreignKeyJoinPointer.add(typeExpression.and(this.onClause));
      } else {
        // this just and's in the entire expression to the normalizer's expression.
        // Need to use this for TYPE and none-outerjoin components
        normalizer.addAdditionalLocalExpression(typeExpression.and(this.onClause));
      }
      return this;
    }

    // if shouldPrintOuterJoinInWhereClause is true, this is this child's tables joined together in
    // one expression
    Expression treatJoinTableExpressions = getTreatCriteria();

    boolean parentUsingOuterJoinForMultitableInheritance =
        typeExpressionBase.isUsingOuterJoinForMultitableInheritance();

    if (treatJoinTableExpressions != null) {
      treatJoinTableExpressions = treatJoinTableExpressions.normalize(normalizer);
    }
    Integer postition = typeExpressionBase.getOuterJoinExpIndex();
    if (postition != null) {
      if (parentUsingOuterJoinForMultitableInheritance) {
        // outer join was done, so our class' tables would have been included
        return this;
      }

      if (getSession().getPlatform().isInformixOuterJoin()) {
        normalizer.addAdditionalLocalExpression(
            typeExpression.and(additionalTreatExpressionCriteria()).and(this.onClause));
        return this;
      } else if (((!getSession().getPlatform().shouldPrintOuterJoinInWhereClause()))
          || (!getSession().getPlatform().shouldPrintInnerJoinInWhereClause())) {

        // Adds the left joins from treat to the base QKE joins.
        Map<DatabaseTable, Expression> map =
            statement
                .getOuterJoinExpressionsHolders()
                .get(postition)
                .outerJoinedAdditionalJoinCriteria;
        if (map != null) {
          map.putAll(additionalTreatExpressionCriteriaMap());
        } else {
          statement
                  .getOuterJoinExpressionsHolders()
                  .get(postition)
                  .outerJoinedAdditionalJoinCriteria =
              additionalTreatExpressionCriteriaMap();
        }
        return this;
      }
    } else if (!getSession().getPlatform().shouldPrintOuterJoinInWhereClause()
        || (!getSession().getPlatform().shouldPrintInnerJoinInWhereClause())) {
      // the base is not using an outer join, so we add a new one for this class' tables.
      Map additionalExpMap = additionalTreatExpressionCriteriaMap();
      if (additionalExpMap != null && !additionalExpMap.isEmpty()) {
        statement.addOuterJoinExpressionsHolders(additionalExpMap, parentDescriptor);
      }
    }
    typeExpression = typeExpression.normalize(normalizer);

    if (foreignKeyJoinPointer != null) {
      // If this expression is right side of an objExp.equal(objExp), one
      // need not add additionalExpressionCriteria twice.
      // Also the join will replace the original objExp.equal(objExp).
      // For CR#2456.
      foreignKeyJoinPointer.add(typeExpression.and(this.onClause));
    } else {
      // this just and's in the entire expression to the normalizer's expression.  Need to use this
      // for TYPE and non-outerjoin components
      normalizer.addAdditionalLocalExpression(
          typeExpression.and(additionalTreatExpressionCriteria()).and(this.onClause));
    }
    return this;
  }