/* This file is part of VoltDB. * Copyright (C) 2008-2017 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.Database; import org.voltdb.expressions.AbstractExpression; import org.voltdb.expressions.ParameterValueExpression; import org.voltdb.expressions.TupleValueExpression; import org.voltdb.types.PlanNodeType; public class TupleScanPlanNode extends AbstractScanPlanNode { public enum Members { PARAM_IDX; } private List<AbstractExpression> m_columnList = new ArrayList<AbstractExpression>(); public TupleScanPlanNode() { super(); m_isSubQuery = true; m_hasSignificantOutputSchema = true; } /* * @param * @param */ public TupleScanPlanNode(String subqueryName, List<AbstractExpression> columnExprs) { super(subqueryName, subqueryName); m_isSubQuery = true; m_hasSignificantOutputSchema = true; // copy columns for (AbstractExpression columnExpr : columnExprs) { m_columnList.add(columnExpr.clone()); } } @Override public PlanNodeType getPlanNodeType() { return PlanNodeType.TUPLESCAN; } @Override public void generateOutputSchema(Database db) { if (m_tableSchema == null) { m_tableSchema = new NodeSchema(); int columnIdx = 1; for (AbstractExpression colExpr : m_columnList) { assert(colExpr instanceof ParameterValueExpression); ParameterValueExpression pve = (ParameterValueExpression) colExpr; // must produce a tuple value expression for this column. String columnName = "C" + Integer.toString(columnIdx); TupleValueExpression tve = new TupleValueExpression( m_targetTableName, m_targetTableAlias, columnName, columnName, pve, columnIdx); m_tableSchema.addColumn( m_targetTableName, m_targetTableAlias, columnName, columnName, tve); ++columnIdx; } m_outputSchema = m_tableSchema; m_hasSignificantOutputSchema = true; } } @Override public void resolveColumnIndexes() { // output columns for (SchemaColumn col : m_outputSchema.getColumns()) { AbstractExpression colExpr = col.getExpression(); // At this point, they'd better all be TVEs. assert(colExpr instanceof TupleValueExpression); TupleValueExpression tve = (TupleValueExpression) colExpr; tve.setColumnIndexUsingSchema(m_tableSchema); } m_outputSchema.sortByTveIndex(); } @Override public String explainPlanForNode(String indent) { String result = "("; String connector = ""; for (AbstractExpression arg : m_columnList) { result += connector + arg.explain(indent); connector = ", "; } result += ")"; return result; } @Override public void toJSONString(JSONStringer stringer) throws JSONException { super.toJSONString(stringer); // Output the correlated parameter ids stringer.key(Members.PARAM_IDX.name()).array(); for (AbstractExpression colExpr : m_columnList) { assert(colExpr instanceof ParameterValueExpression); ParameterValueExpression pve = (ParameterValueExpression) colExpr; stringer.value(pve.getParameterIndex()); } stringer.endArray(); } @Override public void loadFromJSONObject( JSONObject jobj, Database db ) throws JSONException { super.loadFromJSONObject(jobj, db); if (jobj.has(Members.PARAM_IDX.name())) { JSONArray paramIdxArray = jobj.getJSONArray(Members.PARAM_IDX.name()); int paramSize = paramIdxArray.length(); assert(m_outputSchema != null && paramSize == m_outputSchema.size()); for (int i = 0; i < paramSize; ++i) { int paramIdx = paramIdxArray.getInt(i); ParameterValueExpression pve = new ParameterValueExpression(); pve.setParameterIndex(paramIdx); AbstractExpression expr = m_outputSchema.getColumns().get(i).getExpression(); pve.setValueSize(expr.getValueSize()); pve.setValueType(expr.getValueType()); m_columnList.add(pve); } } } }