/* This file is part of VoltDB.
* Copyright (C) 2008-2014 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 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.TupleValueExpression;
import org.voltdb.types.PlanNodeType;
public class SendPlanNode extends AbstractPlanNode {
public SendPlanNode() {
super();
}
@Override
public PlanNodeType getPlanNodeType() {
return PlanNodeType.SEND;
}
@Override
public void resolveColumnIndexes()
{
// Need to order and resolve indexes of output columns
assert(m_children.size() == 1);
m_children.get(0).resolveColumnIndexes();
NodeSchema input_schema = m_children.get(0).getOutputSchema();
assert (input_schema.equals(m_outputSchema));
for (SchemaColumn col : m_outputSchema.getColumns())
{
// At this point, they'd better all be TVEs.
assert(col.getExpression() instanceof TupleValueExpression);
TupleValueExpression tve = (TupleValueExpression)col.getExpression();
int index = tve.resolveColumnIndexesUsingSchema(input_schema);
tve.setColumnIndex(index);
}
m_outputSchema.sortByTveIndex();
}
@Override
public void computeCostEstimates(long childOutputTupleCountEstimate, Cluster cluster, Database db, DatabaseEstimates estimates, ScalarValueHints[] paramHints) {
assert(estimates != null);
// Recursively compute and collect stats from the child node, but don't add any costs for this Send node.
// Let the parent "RecievePlanNode" account for any (theoretical) cost differences due to how much data
// different plans must distribute as intermediate results.
// Don't bother accounting for how much data is sent as the FINAL result -- when there is no RecivePlanNode --
// that cost is constant for a given query, so it would be a wash when comparing any two plans for that query.
m_estimatedOutputTupleCount = childOutputTupleCountEstimate;
m_estimatedProcessedTupleCount = 0;
}
@Override
public void toJSONString(JSONStringer stringer) throws JSONException {
super.toJSONString(stringer);
}
@Override
protected String explainPlanForNode(String indent) {
if (m_parents.size() == 0)
return "RETURN RESULTS TO STORED PROCEDURE";
else
return "SEND PARTITION RESULTS TO COORDINATOR";
}
@Override
public void loadFromJSONObject( JSONObject jobj, Database db ) throws JSONException {
helpLoadFromJSONObject(jobj, db);
}
@Override
public String getUpdatedTable() {
assert(m_children.size() == 1);
AbstractPlanNode child = m_children.get(0);
return child.getUpdatedTable();
}
}