/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.internal.expressions;

import java.util.*;

import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.mappings.querykeys.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadQuery;

/**
 * Superclass for any object type expressions.
 */
public abstract class ObjectExpression extends DataExpression {
    protected transient ClassDescriptor descriptor;
    public List<Expression> derivedExpressions;

    /** indicates whether subclasses should be joined */
    protected boolean shouldUseOuterJoinForMultitableInheritance;

    /** Is this query key to be resolved using an outer join or not. Does not apply to attributes. */
    protected boolean shouldUseOuterJoin;

    /** Allow an expression node to be cast to a subclass or implementation class. */
    protected Class castClass;

    /** Defines that this expression has been joined to the source expression. */
    protected Expression joinSource;

    /** Allow for an ON clause to be specified on a join condition. */
    protected Expression onClause;
    
    /** Used to track the index of the OuterJoinExpressionHolder that might be associated to this expression */
    private Integer outerJoinExpIndex = null;

    /** Allow hasBeenAliased to be marked independently from the existence of the tableAliases collection. */
    protected boolean hasBeenAliased = false;

    public ObjectExpression() {
        this.shouldUseOuterJoin = false;
    }

    /**
     * Return an expression that allows you to treat its base as if it were a subclass of the class returned by the base
     * This can only be called on an ExpressionBuilder, the result of expression.get(String), expression.getAllowingNull(String),
     * the result of expression.anyOf("String") or the result of expression.anyOfAllowingNull("String")
     * 
     * downcast uses Expression.type() internally to guarantee the results are of the specified class.
     * <p>Example:
     * <pre><blockquote>
     *     Expression: employee.get("project").as(LargeProject.class).get("budget").equal(1000)
     *     Java: ((LargeProject)employee.getProjects().get(0)).getBudget() == 1000
     *     SQL: LPROJ.PROJ_ID (+)= PROJ.PROJ_ID AND L_PROJ.BUDGET = 1000 AND PROJ.TYPE = "L"
     * </blockquote></pre>
     */
    @Override
    public Expression treat(Class castClass){
        //to be used on expressionBuilders
        QueryKeyExpression clonedExpression = new TreatAsExpression(castClass, this);
        clonedExpression.shouldQueryToManyRelationship = false;
        clonedExpression.hasQueryKey = false;
        clonedExpression.hasMapping = false;

        this.addDerivedExpression(clonedExpression);
        return clonedExpression;
    }

    /**
     * INTERNAL:
     * Return if the expression is equal to the other.
     * This is used to allow dynamic expression's SQL to be cached.
     */
    @Override
    public boolean equals(Object expression) {
        if (this == expression) {
            return true;
        }
        if (!super.equals(expression)) {
            return false;
        }
        if ((this.onClause != null) || (((ObjectExpression)expression).onClause != null)) {
            return false;
        }
        return this.shouldUseOuterJoin == ((ObjectExpression)expression).shouldUseOuterJoin;
    }

    /**
     * INTERNAL:
     * Add the expression as a derived child of this expression.
     * i.e. e.get("name"), "name" is a derived child of "e".
     */
    public synchronized void addDerivedExpression(Expression addThis) {
        if (this.derivedExpressions == null) {
            this.derivedExpressions = new ArrayList();
        }
        this.derivedExpressions.add(addThis);
    }

    /**
     * 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(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);
                }
            }
        }

        return criteria;
    }

    /**
     * INTERNAL:
     * Used in case outer joins should be printed in FROM clause.
     * Each of the additional tables mapped to expressions that joins it.
     */
    public Map additionalExpressionCriteriaMap() {
        if (getDescriptor() == null) {
            return null;
        }

        HashMap tablesJoinExpressions = null;
        if(isUsingOuterJoinForMultitableInheritance()) {
            tablesJoinExpressions = new HashMap();
            List childrenTables = getDescriptor().getInheritancePolicy().getChildrenTables();
            for( int i=0; i < childrenTables.size(); i++) {
                DatabaseTable table = (DatabaseTable)childrenTables.get(i);
                Expression joinExpression = getDescriptor().getInheritancePolicy().getChildrenTablesJoinExpressions().get(table);
                if (getBaseExpression() != null){
                    joinExpression = getBaseExpression().twist(joinExpression, this);
                } else {
                    joinExpression = twist(joinExpression, this);
                }
                tablesJoinExpressions.put(table, joinExpression);
            }
        }
        
        return tablesJoinExpressions;
    }

    /**
     * INTERNAL:
     * Assign aliases to any tables which I own. Start with t(initialValue),
     * and return the new value of  the counter , i.e. if initialValue is one
     * and I have tables ADDRESS and EMPLOYEE I will assign them t1 and t2 respectively, and return 3.
     */
    public int assignTableAliasesStartingAt(int initialValue) {
        //This differs from the Expression implementation only in that it must set the hasBeenAliased flag when done.
        int returnVal = super.assignTableAliasesStartingAt(initialValue);
        this.hasBeenAliased = true;
        return returnVal;
    }

    /**
     * PUBLIC:
     * Return an expression representing traversal of a 1:many or many:many relationship.
     * This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria.
     * <p>Example:
     * <pre><blockquote>
     *     Expression: employee.anyOf("managedEmployees").get("firstName").equal("Bob")
     *     Java: no direct equivalent
     *     SQL: SELECT DISTINCT ... WHERE (t2.MGR_ID = t1.ID) AND (t2.F_NAME = 'Bob')
     * </pre></blockquote>
     * @parameter shouldJoinBeIndependent indicates whether a new expression should be created.
     */
    @Override
    public Expression anyOf(String attributeName, boolean shouldJoinBeIndependent) {
        QueryKeyExpression queryKey;
        if (shouldJoinBeIndependent) {
            queryKey = newDerivedExpressionNamed(attributeName);
        } else {
            queryKey = derivedExpressionNamed(attributeName);
        }
        queryKey.doQueryToManyRelationship();
        return queryKey;
    }
    
    /**
     * ADVANCED:
     * Return an expression representing traversal of a 1:many or many:many relationship.
     * This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria.
     * <p>Example:
     * <pre><blockquote>
     *     Expression: employee.anyOf("managedEmployees").get("firstName").equal("Bob")
     *     Java: no direct equivalent
     *     SQL: SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')
     * </pre></blockquote>
     * @parameter shouldJoinBeIndependent indicates whether a new expression should be created.
     */
    @Override
    public Expression anyOfAllowingNone(String attributeName, boolean shouldJoinBeIndependent) {
        QueryKeyExpression queryKey;
        if (shouldJoinBeIndependent) {
            queryKey = newDerivedExpressionNamed(attributeName);
        } else {
            queryKey = derivedExpressionNamed(attributeName);
        }
        queryKey.doUseOuterJoin();
        queryKey.doQueryToManyRelationship();
        return queryKey;
    }
    
    /**
     * INTERNAL
     * Return true if it uses a cast class and query is downcasting. It will
     * look into inheritance hierarchy of the root descriptor.
     */
    public boolean isDowncast(ClassDescriptor rootDescriptor, AbstractSession session) {
        if (castClass == null){
            return false;
        }
        
        if (rootDescriptor.getJavaClass() == castClass){
            return false;
        }

        ClassDescriptor castDescriptor = session.getClassDescriptor(castClass);
        
        if (castDescriptor == null){
            throw QueryException.couldNotFindCastDescriptor(castClass, getBaseExpression());
        }
        if (castDescriptor.getInheritancePolicy() == null){
            throw QueryException.castMustUseInheritance(getBaseExpression());
        }
        ClassDescriptor parentDescriptor = castDescriptor.getInheritancePolicy().getParentDescriptor();
        while (parentDescriptor != null){
            if (parentDescriptor == rootDescriptor){
                return true;
            }
            parentDescriptor = parentDescriptor.getInheritancePolicy().getParentDescriptor();
        }
        
        throw QueryException.couldNotFindCastDescriptor(castClass, getBaseExpression());
    }

    /**
     * INTERNAL
     * Return true if treat was used on this expression
     */
    public boolean isTreatUsed() {
        if  (this.hasDerivedExpressions() )
            for (Expression exp: this.derivedExpressions) {
                if (exp.isTreatExpression()) {
                    return true;
            }
        }
        return false;
    }

    /**
     * INTERNAL
     * Return the descriptor which contains this query key, look in the inheritance hierarchy 
     * of rootDescriptor for the descriptor.
     */
    public ClassDescriptor convertToCastDescriptor(ClassDescriptor rootDescriptor, AbstractSession session) {
        if (castClass == null || rootDescriptor == null || rootDescriptor.getJavaClass() == castClass) {
            return rootDescriptor;
        }

        ClassDescriptor castDescriptor = session.getClassDescriptor(castClass);
        
        if (castDescriptor == null){
            throw QueryException.couldNotFindCastDescriptor(castClass, getBaseExpression());
        }
        if (!castDescriptor.hasInheritance()){
            throw QueryException.castMustUseInheritance(getBaseExpression());
        }
        ClassDescriptor parentDescriptor = castDescriptor.getInheritancePolicy().getParentDescriptor();
        while (parentDescriptor != null){
            if (parentDescriptor == rootDescriptor){
                return castDescriptor;
            }
            parentDescriptor = parentDescriptor.getInheritancePolicy().getParentDescriptor();
        }

        ClassDescriptor childDescriptor = rootDescriptor;
        while (childDescriptor != null){
            if (childDescriptor == castDescriptor){
                return rootDescriptor;
            }
            childDescriptor = childDescriptor.getInheritancePolicy().getParentDescriptor();
        }

        throw QueryException.couldNotFindCastDescriptor(castClass, getBaseExpression());
    }
    
    public List<Expression> copyDerivedExpressions(Map alreadyDone) {
        if (this.derivedExpressions == null) {
            return null;
        }
        List<Expression> derivedExpressionsCopy;
        synchronized(this) {
            derivedExpressionsCopy = new ArrayList(this.derivedExpressions);
        }
        List<Expression> result = new ArrayList(derivedExpressionsCopy.size());
        for (Expression exp : derivedExpressionsCopy) {
            result.add(exp.copiedVersionFrom(alreadyDone));
        }
        return result;
    }

    public QueryKeyExpression derivedExpressionNamed(String attributeName) {
        QueryKeyExpression existing = existingDerivedExpressionNamed(attributeName);
        if (existing != null) {
            return existing;
        }
        return newDerivedExpressionNamed(attributeName);

    }

    public Expression derivedManualExpressionNamed(String attributeName, ClassDescriptor aDescriptor) {
        Expression existing = existingDerivedExpressionNamed(attributeName);
        if (existing != null) {
            return existing;
        }
        return newManualDerivedExpressionNamed(attributeName, aDescriptor);

    }

    public void doNotUseOuterJoin() {
        shouldUseOuterJoin = false;
    }

    public void doUseOuterJoin() {
        shouldUseOuterJoin = true;
    }

    public QueryKeyExpression existingDerivedExpressionNamed(String attributeName) {
        if (this.derivedExpressions == null) {
            return null;
        }
        List<Expression> derivedExpressionsCopy;
        synchronized(this) {
            derivedExpressionsCopy = new ArrayList(this.derivedExpressions);
        }
        for (Expression derivedExpression : derivedExpressionsCopy) {
            QueryKeyExpression exp = (QueryKeyExpression)derivedExpression;
            if (exp.getName().equals(attributeName)) {
                return exp;
            }
        }
        return null;
    }

    /**
     * Return the expression from the attribute dervied from this expression.
     */
    @Override
    public Expression get(String attributeName) {
        ObjectExpression result = derivedExpressionNamed(attributeName);
        result.doNotUseOuterJoin();
        return result;
    }

    /**
     * Defines a join between this expression and the target expression based on the ON clause.
     */
    @Override
    public Expression leftJoin(Expression target, Expression onClause) {
        join(target, onClause);
        ((ObjectExpression)target).doUseOuterJoin();
        return this;
    }

    /**
     * Defines a join between this expression and the target expression based on the ON clause.
     */
    @Override
    public Expression join(Expression target, Expression onClause) {
        if (target instanceof ObjectExpression) {
            ((ObjectExpression)target).setJoinSource(this);
            ((ObjectExpression)target).setOnClause(onClause);
        } else {
            throw new IllegalArgumentException();
        }
        return this;
    }

    @Override
    public Expression getAllowingNull(String attributeName) {
        ObjectExpression exp = existingDerivedExpressionNamed(attributeName);

        // The same (aliased) table cannot participate in a normal join and an outer join.
        // To help enforce this, if the node already exists 
        if (exp != null) {
            return exp;
        }
        ObjectExpression result = derivedExpressionNamed(attributeName);
        result.doUseOuterJoin();
        return result;
    }
    
    public Class getCastClass() {
        return castClass;
    }
    
    /**
     * PUBLIC:
     * Return an expression that wraps the inheritance type field in an expression.
     * <p>Example:
     * <pre><blockquote>
     *  builder.getClassForInheritance().equal(SmallProject.class);
     * </blockquote></pre>
     */
    @Override
    public Expression type() {
        return new ClassTypeExpression(this);
    }

    @Override
    public ClassDescriptor getDescriptor() {
        if (isAttribute()) {
            return null;
        }
        if (descriptor == null) {
            // Look first for query keys, then mappings. Ultimately we should have query keys
            // for everything and can dispense with the mapping part.
            ForeignReferenceQueryKey queryKey = (ForeignReferenceQueryKey)getQueryKeyOrNull();
            if (queryKey != null) {
                descriptor = convertToCastDescriptor(getSession().getDescriptor(queryKey.getReferenceClass()), getSession());
                return descriptor;
            }
            if (getMapping() == null) {
                throw QueryException.invalidQueryKeyInExpression(this);
            }

            // We assume this is either a foreign reference or an aggregate mapping
            descriptor = getMapping().getReferenceDescriptor();
            if (getMapping().isVariableOneToOneMapping()) {
                throw QueryException.cannotQueryAcrossAVariableOneToOneMapping(getMapping(), descriptor);
            }
            descriptor = convertToCastDescriptor(descriptor, getSession());
        }
        return descriptor;

    }

    /**
     * INTERNAL: Not to be confused with the public getField(String)
     * This returns a collection of all fields associated with this object. Really
     * only applies to query keys representing an object or to expression builders.
     */
    @Override
    public Vector getFields() {
        if (getDescriptor() == null) {
            DatabaseMapping mapping = getMapping();
            if (mapping != null) {
                return mapping.getSelectFields();
            }
            return new NonSynchronizedVector(0);
        }
        if (descriptor.hasInheritance() && descriptor.getInheritancePolicy().shouldReadSubclasses()
                && (!descriptor.getInheritancePolicy().hasMultipleTableChild()) || shouldUseOuterJoinForMultitableInheritance()) {
            // return all fields because we can.
            return descriptor.getAllFields();
        } else {
            return descriptor.getFields();
        }
    }

    /**
     * INTERNAL:
     */
    @Override
    public List<DatabaseField> getSelectionFields(ReadQuery query) {
        if (getDescriptor() == null) {
            DatabaseMapping mapping = getMapping();
            if (mapping != null) {
                return mapping.getSelectFields();
            }
            return new ArrayList<DatabaseField>(0);
        }
        if (descriptor.hasInheritance() && descriptor.getInheritancePolicy().shouldReadSubclasses()
                && (!descriptor.getInheritancePolicy().hasMultipleTableChild()) || shouldUseOuterJoinForMultitableInheritance()) {
            // return all fields because we can.
            if (query != null && query.isObjectLevelReadQuery()) {
                return descriptor.getAllSelectionFields((ObjectLevelReadQuery)query);
            } else {
                return descriptor.getAllSelectionFields();
            }
        } else {
            if (query != null && query.isObjectLevelReadQuery()) {
                return descriptor.getSelectionFields((ObjectLevelReadQuery)query);
            } else {
                return descriptor.getSelectionFields();
            }
        }
    }

    /**
     * INTERNAL:
     * Returns the first field from each of the owned tables, used for
     * fine-grained pessimistic locking.
     */
    protected Vector getForUpdateOfFields() {
        Vector allFields = getFields();
        int expected = getTableAliases().size();
        Vector firstFields = new Vector(expected);
        DatabaseTable lastTable = null;
        DatabaseField field = null;
        int i = 0;

        // The following loop takes O(n*m) time.  n=# of fields. m=#tables.
        // However, in the m=1 case this will take one pass only.
        // Also assuming that fields are generally sorted by table, this will
        // take O(n) time.
        // An even faster way may be to go getDescriptor().getAdditionalPrimaryKeyFields.
        while ((i < allFields.size()) && (firstFields.size() < expected)) {
            field = (DatabaseField)allFields.elementAt(i++);
            if ((lastTable == null) || !field.getTable().equals(lastTable)) {
                lastTable = field.getTable();
                int j = 0;
                while (j < firstFields.size()) {
                    if (lastTable.equals(((DatabaseField)firstFields.elementAt(j)).getTable())) {
                        break;
                    }
                    j++;
                }
                if (j == firstFields.size()) {
                    firstFields.addElement(field);
                }
            }
        }
        return firstFields;
    }

    public Expression getManualQueryKey(String attributeName, ClassDescriptor aDescriptor) {
        return derivedManualExpressionNamed(attributeName, aDescriptor);
    }

    /**
     * Return any tables in addition to the descriptor's tables, such as the mappings join table.
     */
    public List<DatabaseTable> getAdditionalTables() {
        return null;
    }
    
    /**
     * Return any tables that are defined by this expression (and not its base).
     */
    @Override
    public List<DatabaseTable> getOwnedTables() {
        ClassDescriptor descriptor = getDescriptor();
        List<DatabaseTable> tables = null;
        if (descriptor == null) {
            List additionalTables = getAdditionalTables();
            if (additionalTables == null) {
                return null;
            } else {
                return new ArrayList(additionalTables);
            }
        } else if (descriptor.isAggregateDescriptor()) {
            return null;
        } else if ((descriptor.getHistoryPolicy() != null) && (getAsOfClause().getValue() != null)) {
            tables = descriptor.getHistoryPolicy().getHistoricalTables();
        } else if (isUsingOuterJoinForMultitableInheritance()) {
            tables = descriptor.getInheritancePolicy().getAllTables();
        } else {
            tables = descriptor.getTables();
        }
        List additionalTables = getAdditionalTables();
        if (additionalTables != null) {
            tables = new Vector(tables);
            Helper.addAllUniqueToList(tables, additionalTables);
            return tables;
        }
        return tables;
    }

    public boolean hasBeenAliased() {
        return hasBeenAliased;
    }

    /**
     * INTERNAL:
     */
    public void clearAliases() {
        hasBeenAliased = false;
        super.clearAliases();
    }

    protected boolean hasDerivedExpressions() {
        return derivedExpressions != null;
    }

    @Override
    public boolean isObjectExpression() {
        return true;
    }

    /**
     * INTERNAL:
     * indicates whether additional expressions for multitable inheritance should be used and are available
     */
    public boolean isUsingOuterJoinForMultitableInheritance() {
        return shouldUseOuterJoinForMultitableInheritance() && 
                getDescriptor() != null && getDescriptor().hasInheritance() &&
                getDescriptor().getInheritancePolicy().hasMultipleTableChild() &&
                getDescriptor().getInheritancePolicy().shouldReadSubclasses();
    }
    
    public QueryKeyExpression newDerivedExpressionNamed(String attributeName) {
        QueryKeyExpression result = new QueryKeyExpression(attributeName, this);
        addDerivedExpression(result);
        return result;

    }

    public Expression newManualDerivedExpressionNamed(String attributeName, ClassDescriptor aDescriptor) {
        QueryKeyExpression result = new ManualQueryKeyExpression(attributeName, this, aDescriptor);
        addDerivedExpression(result);
        return result;

    }

    /**
     * INTERNAL:
     * Used for cloning.
     */
    @Override
    protected void postCopyIn(Map alreadyDone) {
        super.postCopyIn(alreadyDone);
        this.derivedExpressions = copyDerivedExpressions(alreadyDone);
        if (this.onClause != null) {
            this.onClause = this.onClause.copiedVersionFrom(alreadyDone);
        }
        if (this.joinSource != null) {
            this.joinSource = this.joinSource.copiedVersionFrom(alreadyDone);
        }
    }

    /**
     * Return null by default, only QueryKeyExpression can have a relation table.
     */
    public DatabaseTable getRelationTable() {
        return null;
    }

    /**
     * Return false by default, only possible for QueryKeyExpression.
     */
    public boolean isDirectCollection() {
        return false;
    }

    /**
     * INTERNAL:
     * The method was added to circumvent derivedFields and derivedTables being
     * protected.
     * @see org.eclipse.persistence.expressions.ExpressionBuilder#registerIn(Map alreadyDone)
     * @bug  2637484 INVALID QUERY KEY EXCEPTION THROWN USING BATCH READS AND PARALLEL EXPRESSIONS
     */
    public void postCopyIn(Map alreadyDone, List<Expression> oldDerivedFields, List<Expression> oldDerivedTables) {
        if (oldDerivedFields != null) {
            if (this.derivedFields == null) {
                this.derivedFields = copyCollection(oldDerivedFields, alreadyDone);
            } else {
                this.derivedFields.addAll(copyCollection(oldDerivedFields, alreadyDone));
            }
        }
        if (oldDerivedTables != null) {
            if (this.derivedTables == null) {
                this.derivedTables = copyCollection(oldDerivedTables, alreadyDone);
            } else {
                this.derivedTables.addAll(copyCollection(oldDerivedTables, alreadyDone));
            }
        }
    }
    
    public Expression getOnClause() {
        return onClause;
    }

    public void setOnClause(Expression onClause) {
        this.onClause = onClause;
    }
    
    public void setCastClass(Class castClass) {
        this.castClass = castClass;
    }
    
    /**
     * INTERNAL:
     * set the flag indicating whether subclasses should be joined
     */
    public void setShouldUseOuterJoinForMultitableInheritance(boolean shouldUseOuterJoinForMultitableInheritance) {
        this.shouldUseOuterJoinForMultitableInheritance = shouldUseOuterJoinForMultitableInheritance;
    }

    public boolean shouldUseOuterJoin() {
        return shouldUseOuterJoin;
    }

    public boolean shouldUseOuterJoinForMultitableInheritance() {
        return shouldUseOuterJoinForMultitableInheritance;
    }
    
    /**
     * INTERNAL:
     * writes the first field from each of the owned tables, used for
     * fine-grained pessimistic locking.
     */
    protected void writeForUpdateOfFields(ExpressionSQLPrinter printer, SQLSelectStatement statement) {
        for (Iterator iterator = getForUpdateOfFields().iterator(); iterator.hasNext();) {
            DatabaseField field = (DatabaseField)iterator.next();
            if (printer.getPlatform().shouldPrintAliasForUpdate()) {
                writeAlias(printer, field, statement);
            } else {
                writeField(printer, field, statement);                
            }
        }
    }

    public Expression getJoinSource() {
        return joinSource;
    }

    public void setJoinSource(Expression joinSource) {
        this.joinSource = joinSource;
    }

    public Integer getOuterJoinExpIndex() {
        return outerJoinExpIndex;
    }

    public void setOuterJoinExpIndex(Integer outerJoinExpIndex) {
        this.outerJoinExpIndex = outerJoinExpIndex;
    }

}
