/**
 * Copyright (C) 2011 Akiban Technologies Inc.
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 */

package com.akiban.sql.optimizer.plan;

import com.akiban.server.error.InvalidOperationException;

import java.util.Set;

/** A join to an actual table. */
public class TableSource extends BaseJoinable implements ColumnSource
{
    private TableNode table;
    private TableGroup group;
    private TableGroupJoin parentJoin;
    private boolean required;
    private Set<ColumnExpression> columnsUsed;

    public TableSource(TableNode table, boolean required) {
        this.table = table;
        table.addUse(this);
        this.required = required;
    }

    public TableNode getTable() {
        return table;
    }

    public TableGroup getGroup() {
        return group;
    }
    public void setGroup(TableGroup group) {
        this.group = group;
        group.getTables().add(this);
    }

    public TableGroupJoin getParentJoin() {
        return parentJoin;
    }
    public void setParentJoin(TableGroupJoin parentJoin) {
        this.parentJoin = parentJoin;
        this.group = parentJoin.getGroup();
    }

    public TableSource getParentTable() {
        if (parentJoin == null)
            return null;
        else
            return parentJoin.getParent();
    }

    public boolean isRequired() {
        return required;
    }
    public boolean isOptional() {
        return !required;
    }
    public void setRequired(boolean required) {
        this.required = required;
    }

    public Set<ColumnExpression> getColumnsUsed() {
        return columnsUsed;
    }
    public void setColumnsUsed(Set<ColumnExpression> columnsUsed) {
        this.columnsUsed = columnsUsed;
    }

    @Override
    public String getName() {
        return table.getTable().getName().toString();
    }

    @Override
    public boolean isTable() {
        return true;
    }

    @Override
    public boolean accept(PlanVisitor v) {
        return v.visit(this);
    }
    
    @Override
    public String summaryString() {
        StringBuilder str = new StringBuilder(super.summaryString());
        str.append("(");
        str.append(table.toString());
        if (parentJoin != null) {
            str.append(" - ");
            str.append(parentJoin);
        }
        else if (group != null) {
            str.append(" - ");
            str.append(group);
        }
        str.append(")");
        return str.toString();
    }

    @Override
    protected boolean maintainInDuplicateMap() {
        return true;
    }

    @Override
    protected void deepCopy(DuplicateMap map) {
        super.deepCopy(map);
        table = map.duplicate(table);
        table.addUse(this);
        if (columnsUsed != null)
            columnsUsed = duplicateSet(columnsUsed, map);
    }

}

@@ -1009,55 +1009,8 @@
 red;
-%0A    private Set%3CColumnExpression%3E columnsUsed;
 %0A%0A  
@@ -2018,209 +2018,8 @@
  %7D%0A%0A
-    public Set%3CColumnExpression%3E getColumnsUsed() %7B%0A        return columnsUsed;%0A    %7D%0A    public void setColumnsUsed(Set%3CColumnExpression%3E columnsUsed) %7B%0A        this.columnsUsed = columnsUsed;%0A    %7D%0A%0A
     
@@ -2973,16 +2973,16 @@
 table);%0A
+
         
@@ -3005,99 +3005,8 @@
 s);%0A
-        if (columnsUsed != null)%0A            columnsUsed = duplicateSet(columnsUsed, map);%0A
     

Remove unused field until I'm sure it's needed.