/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* VoltDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VoltDB 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 General Public License for more details.
*
* You should have received a copy of the GNU 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 java.util.Vector;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.voltdb.catalog.Database;
import org.voltdb.planner.PlanColumn;
import org.voltdb.planner.PlannerContext;
import org.voltdb.types.PlanNodeType;
import org.voltdb.types.SortDirectionType;
/**
*
*/
public class OrderByPlanNode extends AbstractPlanNode {
public enum Members {
SORT_COLUMNS,
COLUMN_NAME,
COLUMN_GUID,
SORT_DIRECTION;
}
/**
* Sort Columns Indexes
* The column index in the table that we should sort on
*/
private List<Integer> m_sortColumns = new ArrayList<Integer>();
private List<Integer> m_sortColumnGuids = new ArrayList<Integer>();
private List<String> m_sortColumnNames = new ArrayList<String>();
private List<SortDirectionType> m_sortDirections = new Vector<SortDirectionType>();
/**
* @param id
*/
public OrderByPlanNode(PlannerContext context, Integer id) {
super(context, id);
}
@Override
public Object clone(boolean clone_children, boolean clone_inline) throws CloneNotSupportedException {
OrderByPlanNode clone = (OrderByPlanNode)super.clone(clone_children, clone_inline);
clone.m_sortColumns = new ArrayList<Integer>(this.m_sortColumns);
clone.m_sortColumnGuids = new ArrayList<Integer>(this.m_sortColumnGuids);
clone.m_sortColumnNames = new ArrayList<String>(this.m_sortColumnNames);
clone.m_sortDirections = new ArrayList<SortDirectionType>(this.m_sortDirections);
return (clone);
}
@Override
public PlanNodeType getPlanNodeType() {
return PlanNodeType.ORDERBY;
}
@Override
public void validate() throws Exception {
super.validate();
// Make sure that they have the same # of columns and directions
if (m_sortColumns.size() != m_sortDirections.size()) {
throw new Exception("ERROR: PlanNode '" + toString() + "' has " +
"'" + m_sortColumns.size() + "' sort columns but " +
"'" + m_sortDirections.size() + "' sort directions");
}
// Make sure that none of the items are null
for (int ctr = 0, cnt = m_sortColumns.size(); ctr < cnt; ctr++) {
if (m_sortColumns.get(ctr) == null) {
throw new Exception("ERROR: PlanNode '" + toString() + "' has a null " +
"sort column index at position " + ctr);
} else if (m_sortDirections.get(ctr) == null) {
throw new Exception("ERROR: PlanNode '" + toString() + "' has a null " +
"sort direction at position " + ctr);
}
}
}
/**
* @return the sort_columns
*/
public List<Integer> getSortColumns() {
return m_sortColumns;
}
/**
* @return the sort_column_guids
*/
public List<Integer> getSortColumnGuids() {
return m_sortColumnGuids;
}
/**
* @return the sort_column_names
*/
public List<String> getSortColumnNames() {
return m_sortColumnNames;
}
/**
* @return the sort_directions
*/
public List<SortDirectionType> getSortDirections() {
return m_sortDirections;
}
@Override
public void toJSONString(JSONStringer stringer) throws JSONException {
super.toJSONString(stringer);
assert (m_sortColumnNames.size() == m_sortDirections.size());
stringer.key(Members.SORT_COLUMNS.name()).array();
for (int ii = 0; ii < m_sortColumnNames.size(); ii++) {
stringer.object();
stringer.key(Members.COLUMN_NAME.name()).value(m_sortColumnNames.get(ii));
stringer.key(Members.COLUMN_GUID.name()).value(m_sortColumnGuids.get(ii));
stringer.key(Members.SORT_DIRECTION.name()).value(m_sortDirections.get(ii).toString());
stringer.endObject();
}
stringer.endArray();
}
@Override
protected void loadFromJSONObject(JSONObject obj, Database db) throws JSONException {
JSONArray sortColumns = obj.getJSONArray(Members.SORT_COLUMNS.name());
for (int ii = 0; ii < sortColumns.length(); ii++) {
JSONObject sortColumn = sortColumns.getJSONObject(ii);
m_sortColumnNames.add(sortColumn.getString(Members.COLUMN_NAME.name()));
m_sortColumnGuids.add(sortColumn.getInt(Members.COLUMN_GUID.name()));
m_sortDirections.add(SortDirectionType.valueOf(sortColumn.getString(Members.SORT_DIRECTION.name())));
}
}
/** adds a plan column to the list of output columns **/
public void appendOutputColumn(PlanColumn column)
{
m_outputColumns.add(column.guid());
}
/** adds a sort column to the list of output columns **/
public void appendSortColumn(PlanColumn column)
{
m_sortColumnGuids.add(column.guid());
}
/** clears the list of output columns **/
public void clearOutputColumn()
{
m_outputColumns.clear();
}
/** clears the list of sort column GUIDS **/
public void clearSortColumn()
{
m_sortColumnGuids.clear();
}
}