/**
 * END USER LICENSE AGREEMENT (“EULA”)
 *
 * READ THIS AGREEMENT CAREFULLY (date: 9/13/2011):
 * http://www.akiban.com/licensing/20110913
 *
 * BY INSTALLING OR USING ALL OR ANY PORTION OF THE SOFTWARE, YOU ARE ACCEPTING
 * ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU AGREE THAT THIS
 * AGREEMENT IS ENFORCEABLE LIKE ANY WRITTEN AGREEMENT SIGNED BY YOU.
 *
 * IF YOU HAVE PAID A LICENSE FEE FOR USE OF THE SOFTWARE AND DO NOT AGREE TO
 * THESE TERMS, YOU MAY RETURN THE SOFTWARE FOR A FULL REFUND PROVIDED YOU (A) DO
 * NOT USE THE SOFTWARE AND (B) RETURN THE SOFTWARE WITHIN THIRTY (30) DAYS OF
 * YOUR INITIAL PURCHASE.
 *
 * IF YOU WISH TO USE THE SOFTWARE AS AN EMPLOYEE, CONTRACTOR, OR AGENT OF A
 * CORPORATION, PARTNERSHIP OR SIMILAR ENTITY, THEN YOU MUST BE AUTHORIZED TO SIGN
 * FOR AND BIND THE ENTITY IN ORDER TO ACCEPT THE TERMS OF THIS AGREEMENT. THE
 * LICENSES GRANTED UNDER THIS AGREEMENT ARE EXPRESSLY CONDITIONED UPON ACCEPTANCE
 * BY SUCH AUTHORIZED PERSONNEL.
 *
 * IF YOU HAVE ENTERED INTO A SEPARATE WRITTEN LICENSE AGREEMENT WITH AKIBAN FOR
 * USE OF THE SOFTWARE, THE TERMS AND CONDITIONS OF SUCH OTHER AGREEMENT SHALL
 * PREVAIL OVER ANY CONFLICTING TERMS OR CONDITIONS IN THIS AGREEMENT.
 */

package com.akiban.sql.optimizer;

import com.akiban.sql.compiler.TypeComputer;

import com.akiban.sql.parser.*;

import com.akiban.sql.StandardException;
import com.akiban.sql.types.DataTypeDescriptor;

/** Calculate types from schema information. */
public class AISTypeComputer extends TypeComputer
{
    public AISTypeComputer() {
    }
    
    @Override
    protected DataTypeDescriptor computeType(ValueNode node) throws StandardException {
        switch (node.getNodeType()) {
        case NodeTypes.COLUMN_REFERENCE:
            return columnReference((ColumnReference)node);
        default:
            return super.computeType(node);
        }
    }

    protected DataTypeDescriptor columnReference(ColumnReference node) 
            throws StandardException {
        ColumnBinding columnBinding = (ColumnBinding)node.getUserData();
        assert (columnBinding != null) : "column is not bound yet";
        return columnBinding.getType();
    }

}

@@ -1431,16 +1431,144 @@
 iptor;%0A%0A
+import com.akiban.ais.model.Column;%0Aimport com.akiban.ais.model.UserTable;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.List;%0A%0A
 /** Calc
@@ -2318,10 +2318,2223 @@
 %0A    %7D%0A%0A
+    @Override%0A    protected void insertNode(InsertNode node) throws StandardException %7B%0A        TableName tableName = node.getTargetTableName();%0A        UserTable table = (UserTable)tableName.getUserData();%0A        if (table == null) return;%0A        ResultSetNode source = node.getResultSetNode();%0A        int ncols = source.getResultColumns().size();%0A        ResultColumnList targetColumns = node.getTargetColumnList();%0A        List%3CColumn%3E columns;%0A        if (targetColumns != null) %7B%0A            if (ncols %3E targetColumns.size())%0A                ncols = targetColumns.size();%0A            columns = new ArrayList%3CColumn%3E(ncols);%0A            for (int i = 0; i %3C ncols; i++) %7B%0A                ColumnBinding cb = (ColumnBinding)%0A                    targetColumns.get(i).getReference().getUserData();%0A                columns.add((cb == null) ? null : cb.getColumn());%0A            %7D%0A        %7D%0A        else %7B%0A            List%3CColumn%3E allColumns = table.getColumns();%0A            if (ncols %3E allColumns.size())%0A                ncols = allColumns.size();%0A            columns = new ArrayList%3CColumn%3E(ncols);%0A            for (int i = 0; i %3C ncols; i++) %7B%0A                columns.add(allColumns.get(i));%0A            %7D%0A        %7D%0A        for (int i = 0; i %3C ncols; i++) %7B%0A            Column column = columns.get(i);%0A            if (column == null) continue;%0A            pushType(source, i, ColumnBinding.getType(column, false));%0A        %7D%0A    %7D%0A%0A    protected void pushType(ResultSetNode result, int i, DataTypeDescriptor type)%0A            throws StandardException %7B%0A        ResultColumn column = result.getResultColumns().get(i);%0A        if (column.getType() == null) %7B%0A            column.setType(type); // Parameters and NULL.%0A            ValueNode expr = column.getExpression();%0A            if (expr.getType() == null) %7B%0A                expr.setType(type);%0A            %7D%0A        %7D%0A        else %7B%0A            // TODO: Could also add casts here to make types consistent.%0A        %7D%0A        if (result.getNodeType() == NodeTypes.UNION_NODE) %7B%0A            UnionNode union = (UnionNode)result;%0A            pushType(union.getLeftResultSet(), i, type);%0A            pushType(union.getRightResultSet(), i, type);%0A        %7D%0A    %7D%0A%0A
 %7D%0A

Use column types to set unknown types for INSERT.