/* This file is part of VoltDB.
 * Copyright (C) 2008-2013 VoltDB Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * 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 VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.voltdb.plannodes;

import java.util.ArrayList;
import java.util.List;

import org.json_voltpatches.JSONArray;
import org.json_voltpatches.JSONException;
import org.json_voltpatches.JSONObject;
import org.json_voltpatches.JSONStringer;
import org.voltdb.catalog.Cluster;
import org.voltdb.catalog.Database;
import org.voltdb.compiler.DatabaseEstimates;
import org.voltdb.compiler.ScalarValueHints;
import org.voltdb.expressions.AbstractExpression;
import org.voltdb.types.PlanNodeType;

/**
 * Used for SQL-IN that are accelerated with indexes.
 * A MaterializedScanPlanNode is created from the list part
 * of the SQL-IN-LIST. It is inner-joined with NLIJ to another
 * table to make the SQL-IN fast.
 *
 */
public class MaterializedScanPlanNode extends AbstractPlanNode {

    protected List<AbstractExpression> m_tableData = new ArrayList<AbstractExpression>();

    public enum Members {
        TABLE_DATA;
    }

    public MaterializedScanPlanNode() {
        super();
    }

    @Override
    public PlanNodeType getPlanNodeType() {
        return PlanNodeType.MATERIALIZEDSCAN;
    }

    public void setTableData(List<AbstractExpression> rows) {
        m_tableData.clear();
        m_tableData.addAll(rows);
    }

    public List<AbstractExpression> getTableData() {
        List<AbstractExpression> retval = new ArrayList<AbstractExpression>();
        retval.addAll(m_tableData);
        return retval;
    }

    /**
     * Accessor for flag marking the plan as guaranteeing an identical result/effect
     * when "replayed" against the same database state, such as during replication or CL recovery.
     * @return false
     */
    @Override
    public boolean isOrderDeterministic() {
        return true;
    }

    @Override
    public void computeCostEstimates(long childOutputTupleCountEstimate, Cluster cluster, Database db, DatabaseEstimates estimates, ScalarValueHints[] paramHints) {
        // assume constant cost. Most of the cost of the SQL-IN will be measured by the NLIJ that is always paired with this element
        m_estimatedProcessedTupleCount = 1;
        m_estimatedOutputTupleCount = 1;
    }

    @Override
    protected String explainPlanForNode(String indent) {
        return "MATERIALIZED SCAN of SQL-IN-LIST";
    }

    @Override
    public void resolveColumnIndexes() {
        // MaterializedScanPlanNodes have no children
        assert(m_children.size() == 0);
    }

    @Override
    public void toJSONString(JSONStringer stringer) throws JSONException {
        super.toJSONString(stringer);

        stringer.key(Members.TABLE_DATA.name());
        stringer.array();
        for (int i = 0; i < m_tableData.size(); i++) {
            stringer.object();
            AbstractExpression ae = m_tableData.get(i);
            assert(ae != null);
            ae.toJSONString(stringer);
            stringer.endObject();
        }
    }

    @Override
    protected void loadFromJSONObject(JSONObject obj, Database db) throws JSONException {
        helpLoadFromJSONObject(obj, db);

        assert(!obj.isNull(Members.TABLE_DATA.name()));

        //load table data
        JSONArray jarray = null;
        jarray = obj.getJSONArray(Members.TABLE_DATA.name());
        for (int i = 0; i < jarray.length(); i++) {
            AbstractExpression ae = AbstractExpression.fromJSONObject(obj, db);
            m_tableData.add(ae);
        }
    }
}

@@ -768,99 +768,8 @@
 s;%0A%0A
-import java.util.ArrayList;%0Aimport java.util.List;%0A%0Aimport org.json_voltpatches.JSONArray;%0A
 impo
@@ -1097,24 +1097,77 @@
 Expression;%0A
+import org.voltdb.expressions.VectorValueExpression;%0A
 import org.v
@@ -1495,21 +1495,16 @@
 otected 
-List%3C
 Abstract
@@ -1517,59 +1517,18 @@
 sion
-%3E
  m_
-tableData = new ArrayList%3CAbstractExpression%3E()
+rowData
 ;%0A%0A 
@@ -1777,23 +1777,16 @@
  set
-TableData(List%3C
+RowData(
 Abst
@@ -1803,14 +1803,16 @@
 sion
-%3E
  row
-s
+Data
 ) %7B%0A
@@ -1823,61 +1823,85 @@
     
-m_tableData.clear();%0A        m_tableData.addAll(rows)
+assert(rowData instanceof VectorValueExpression);%0A        m_rowData = rowData
 ;%0A  
@@ -1916,21 +1916,16 @@
  public 
-List%3C
 Abstract
@@ -1934,17 +1934,16 @@
 pression
-%3E
  getTabl
@@ -1964,136 +1964,24 @@
     
-List%3CAbstractExpression%3E retval = new ArrayList%3CAbstractExpression%3E();%0A        retval.addAll(m_tableData);%0A        return retval
+return m_rowData
 ;%0A  
@@ -3179,180 +3179,42 @@
 ger.
-array();%0A        for (int i = 0; i %3C m_tableData.size(); i++) %7B%0A            stringer.object();%0A            AbstractExpression ae = m_tableData.get(i);%0A            assert(ae
+object();%0A        assert(m_rowData
  != 
@@ -3232,14 +3232,17 @@
     
-    ae
+m_rowData
 .toJ
@@ -3262,20 +3262,16 @@
 inger);%0A
-    
         
@@ -3292,26 +3292,16 @@
 ject();%0A
-        %7D%0A
     %7D%0A%0A 
@@ -3501,25 +3501,24 @@
 me()));%0A
-%0A
         
 //load t
@@ -3513,73 +3513,29 @@
     
-//load table data%0A        JSONArray jarray = null;%0A        jarray
+JSONObject rowDataObj
  = o
@@ -3548,13 +3548,14 @@
 JSON
-Array
+Object
 (Mem
@@ -3591,174 +3591,70 @@
     
-for (int i = 0; i %3C jarray.length(); i++) %7B%0A            AbstractExpression ae = AbstractExpression.fromJSONObject(obj, db);%0A            m_tableData.add(ae);%0A        %7D
+m_rowData = AbstractExpression.fromJSONObject(rowDataObj, db);
 %0A   

Change the list of expressions to a single vector expression.