Package org.voltdb.plannodes

Source Code of org.voltdb.plannodes.AggregatePlanNode

/* 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 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.ExpressionType;
import org.voltdb.types.PlanNodeType;

/**
*
*/
public class AggregatePlanNode extends AbstractPlanNode {

    public enum Members {
        AGGREGATE_COLUMNS,
        AGGREGATE_TYPE,
        AGGREGATE_NAME,
        AGGREGATE_GUID,
        AGGREGATE_OUTPUT_COLUMN,
        GROUPBY_COLUMNS;
    }

    // NOTE: I'm not really keen on how this is all laid out, but it's just
    //     good enough for what we need in TPC-C for now...
    private List<ExpressionType> m_aggregateTypes = new ArrayList<ExpressionType>();

    // a list of column offsets/indexes not plan column guids.
    private List<Integer> m_aggregateOutputColumns = new ArrayList<Integer>();
    // a list of the names of the columns that are being aggregated
    private List<String> m_aggregateColumnNames = new ArrayList<String>();
    // a list of the GUIDs for the columns that are being aggregated
    private List<Integer> m_aggregateColumnGuids = new ArrayList<Integer>();

    private List<Integer> m_groupByColumns = new ArrayList<Integer>();
    private List<Integer> m_groupByColumnGuids = new ArrayList<Integer>();
    private List<String> m_groupByColumnNames = new ArrayList<String>();

    public AggregatePlanNode(PlannerContext context, Integer id) {
        super(context, id);
    }
   
    @Override
    public Object clone(boolean clone_children, boolean clone_inline) throws CloneNotSupportedException {
        AggregatePlanNode clone = (AggregatePlanNode)super.clone(clone_children, clone_inline);
       
        clone.m_aggregateTypes = new ArrayList<ExpressionType>(this.m_aggregateTypes);
        clone.m_aggregateOutputColumns = new ArrayList<Integer>(this.m_aggregateOutputColumns);
        clone.m_aggregateColumnNames = new ArrayList<String>(this.m_aggregateColumnNames);
        clone.m_aggregateColumnGuids = new ArrayList<Integer>(this.m_aggregateColumnGuids);
        clone.m_groupByColumns = new ArrayList<Integer>(this.m_groupByColumns);
        clone.m_groupByColumnGuids = new ArrayList<Integer>(this.m_groupByColumnGuids);
        clone.m_groupByColumnNames = new ArrayList<String>(this.m_groupByColumnNames);
       
        return (clone);
    }

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

    @Override
    public void validate() throws Exception {
        super.validate();
        //
        // We need to have an aggregate type and column
        // We're not checking that it's a valid ExpressionType because this plannode is a temporary hack
        //
        if (m_aggregateTypes.size() != m_aggregateColumnNames.size() ||
            m_aggregateColumnNames.size() != m_aggregateOutputColumns.size())
        {
            throw new Exception("ERROR: Mismatched number of aggregate expression column attributes for PlanNode '" + this + "'");
        } else if (m_aggregateTypes.isEmpty()|| m_aggregateTypes.contains(ExpressionType.INVALID)) {
            throw new Exception("ERROR: Invalid Aggregate ExpressionType or No Aggregate Expression types for PlanNode '" + this + "'");
        } else if (m_aggregateColumnNames.isEmpty()) {
            throw new Exception("ERROR: No Aggregate Columns for PlanNode '" + this + "'");
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    protected ArrayList<Integer> createOutputColumns(Database db, ArrayList<Integer> input) {
        // columns are created during plan node construction
        assert(m_outputColumns.size() > 0);
        return (ArrayList<Integer>)m_outputColumns.clone();
    }

    public void appendOutputColumn(PlanColumn colInfo) {
        m_outputColumns.add(colInfo.guid());
    }
    /**
     * @return The list of output column indexes that each aggregate outputs to
     */
    public List<Integer> getAggregateOutputColumns() {
        return m_aggregateOutputColumns;
    }

    /**
     * @return The type of aggregation for each aggregate column
     */
    public List<ExpressionType> getAggregateTypes() {
        return m_aggregateTypes;
    }
    /**
     * @param aggregate_types
     */
    public void setAggregateTypes(List<ExpressionType> aggregate_types) {
        m_aggregateTypes = aggregate_types;
    }

    /**
     * @return the aggregate column GUIDs (aggregated input col GUID)
     */
    public List<Integer> getAggregateColumnGuids() {
        return m_aggregateColumnGuids;
    }
    /**
     * @param aggregate_column_guids
     */
    public void setAggregateColumnGuids(List<Integer> aggregate_column_guids) {
        m_aggregateColumnGuids = aggregate_column_guids;
    }

    /**
     * @return the aggregate_column_name
     */
    public List<String> getAggregateColumnNames() {
        return m_aggregateColumnNames;
    }
    /**
     * @param aggregate_column_names
     */
    public void setAggregateColumnNames(List<String> aggregate_column_names) {
        m_aggregateColumnNames = aggregate_column_names;
    }

    /**
     * @return Names of the input column that maps to the output column.
     */
    public List<String> getOutputColumnInputAliasNames() {
        return m_aggregateColumnNames;
    }

    /**
     * @return the groupby_columns
     */
    public List<Integer> getGroupByColumnOffsets() {
        return m_groupByColumns;
    }
   
    /**
     * GroupBy PlanColumn GUIDs
     * @return
     */
    public List<Integer> getGroupByColumnGuids() {
        return m_groupByColumnGuids;
    }

    public void appendGroupByColumn(PlanColumn colInfo) {
        m_groupByColumnGuids.add(colInfo.guid());
    }

    /**
     * @return the groupby_column_names
     */
    public List<String> getGroupByColumnNames() {
        return m_groupByColumnNames;
    }
    /**
     * @param groupby_column_names
     */
    public void setGroupByColumnNames(List<String> groupby_column_names) {
        m_groupByColumnNames = groupby_column_names;
    }

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

        stringer.key("AGGREGATE_COLUMNS");
        stringer.array();
        for (int ii = 0; ii < m_aggregateTypes.size(); ii++) {
            stringer.object();
            stringer.key(Members.AGGREGATE_TYPE.name()).value(m_aggregateTypes.get(ii).name());
            stringer.key(Members.AGGREGATE_NAME.name()).value(m_aggregateColumnNames.get(ii));
            stringer.key(Members.AGGREGATE_GUID.name()).value(m_aggregateColumnGuids.get(ii));
            stringer.key(Members.AGGREGATE_OUTPUT_COLUMN.name()).value(m_aggregateOutputColumns.get(ii));
            stringer.endObject();
        }
        stringer.endArray();

        if (!m_groupByColumnGuids.isEmpty())
        {  
            stringer.key(Members.GROUPBY_COLUMNS.name()).array();
            for (int i = 0; i < m_groupByColumnGuids.size(); i++) {
                PlanColumn column = m_context.get(m_groupByColumnGuids.get(i));
                column.toJSONString(stringer);
            }
            stringer.endArray();
        }
    }
   
    @Override
    protected void loadFromJSONObject(JSONObject obj, Database db) throws JSONException {
        JSONArray aggregateColumns = obj.getJSONArray(Members.AGGREGATE_COLUMNS.name());
        for (int ii = 0; ii < aggregateColumns.length(); ii++) {
            JSONObject aggregateColumn = aggregateColumns.getJSONObject(ii);
            m_aggregateTypes.add(ExpressionType.valueOf(aggregateColumn.getString(Members.AGGREGATE_TYPE.name())));
            m_aggregateColumnNames.add(aggregateColumn.getString(Members.AGGREGATE_NAME.name()));
            m_aggregateColumnGuids.add(aggregateColumn.getInt(Members.AGGREGATE_GUID.name()));
            m_aggregateOutputColumns.add(aggregateColumn.getInt(Members.AGGREGATE_OUTPUT_COLUMN.name()));
        }
       
        try {
            JSONArray groupbyColumnGuids = obj.getJSONArray(Members.GROUPBY_COLUMNS.name());
            for (int ii = 0; ii < groupbyColumnGuids.length(); ii++) {
                JSONObject jsonObject = groupbyColumnGuids.getJSONObject(ii);
                PlanColumn column = PlanColumn.fromJSONObject(jsonObject, db);
                m_groupByColumnGuids.add(column.guid());
            }
        } catch (JSONException e) {
            //okay not to be there.
        }
    }
}
TOP

Related Classes of org.voltdb.plannodes.AggregatePlanNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.