/** * 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 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; }