Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

generate a different plan (table count executor) that returns tuple c…

…ount
  • Loading branch information...
commit 3710fac37cbb1c76864973a79ddd01c0c8948b7a 1 parent b057453
Xin Jia authored
2  build.py
View
@@ -225,6 +225,7 @@
executorutil.cpp
indexscanexecutor.cpp
indexcountexecutor.cpp
+ tablecountexecutor.cpp
insertexecutor.cpp
limitexecutor.cpp
materializeexecutor.cpp
@@ -256,6 +257,7 @@
distinctnode.cpp
indexscannode.cpp
indexcountnode.cpp
+ tablecountnode.cpp
insertnode.cpp
limitnode.cpp
materializenode.cpp
5 src/ee/common/types.cpp
View
@@ -302,6 +302,9 @@ string planNodeToString(PlanNodeType type)
case PLAN_NODE_TYPE_INDEXCOUNT: {
return "INDEXCOUNT";
}
+ case PLAN_NODE_TYPE_TABLECOUNT: {
+ return "TABLECOUNT";
+ }
case PLAN_NODE_TYPE_NESTLOOP: {
return "NESTLOOP";
}
@@ -364,6 +367,8 @@ PlanNodeType stringToPlanNode(string str )
return PLAN_NODE_TYPE_INDEXSCAN;
} else if (str == "INDEXCOUNT") {
return PLAN_NODE_TYPE_INDEXCOUNT;
+ } else if (str == "TABLECOUNT") {
+ return PLAN_NODE_TYPE_TABLECOUNT;
} else if (str == "NESTLOOP") {
return PLAN_NODE_TYPE_NESTLOOP;
} else if (str == "NESTLOOPINDEX") {
2  src/ee/common/types.h
View
@@ -159,7 +159,7 @@ enum PlanNodeType {
PLAN_NODE_TYPE_INDEXSCAN = 11,
// special counting index
PLAN_NODE_TYPE_INDEXCOUNT = 12,
-
+ PLAN_NODE_TYPE_TABLECOUNT = 13,
//
// Join Nodes
//
1  src/ee/executors/executors.h
View
@@ -54,6 +54,7 @@
#include "executors/distinctexecutor.h"
#include "executors/indexscanexecutor.h"
#include "executors/indexcountexecutor.h"
+#include "executors/tablecountexecutor.h"
#include "executors/insertexecutor.h"
#include "executors/limitexecutor.h"
#include "executors/materializeexecutor.h"
1  src/ee/executors/executorutil.cpp
View
@@ -62,6 +62,7 @@ AbstractExecutor* getNewExecutor(VoltDBEngine *engine,
case PLAN_NODE_TYPE_DISTINCT: return new DistinctExecutor(engine, abstract_node);
case PLAN_NODE_TYPE_INDEXSCAN: return new IndexScanExecutor(engine, abstract_node);
case PLAN_NODE_TYPE_INDEXCOUNT: return new IndexCountExecutor(engine, abstract_node);
+ case PLAN_NODE_TYPE_TABLECOUNT: return new TableCountExecutor(engine, abstract_node);
case PLAN_NODE_TYPE_INSERT: return new InsertExecutor(engine, abstract_node);
case PLAN_NODE_TYPE_LIMIT: return new LimitExecutor(engine, abstract_node);
case PLAN_NODE_TYPE_MATERIALIZE: return new MaterializeExecutor(engine, abstract_node);
95 src/ee/executors/tablecountexecutor.cpp
View
@@ -0,0 +1,95 @@
+/* This file is part of VoltDB.
+ * Copyright (C) 2008-2012 VoltDB Inc.
+ *
+ * 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/>.
+ */
+
+#include <iostream>
+#include "tablecountexecutor.h"
+#include "common/debuglog.h"
+#include "common/common.h"
+#include "common/tabletuple.h"
+#include "common/FatalException.hpp"
+#include "common/ValueFactory.hpp"
+#include "expressions/abstractexpression.h"
+#include "plannodes/tablecountnode.h"
+#include "storage/table.h"
+#include "storage/temptable.h"
+#include "storage/tablefactory.h"
+#include "storage/tableiterator.h"
+
+using namespace voltdb;
+
+bool TableCountExecutor::p_init(AbstractPlanNode* abstract_node,
+ TempTableLimits* limits)
+{
+ VOLT_TRACE("init Table Count Executor");
+
+ TableCountPlanNode* node = dynamic_cast<TableCountPlanNode*>(abstract_node);
+ assert(node);
+ assert(node->getTargetTable());
+
+ TupleSchema* schema = node->generateTupleSchema(true);
+ int column_count = static_cast<int>(node->getOutputSchema().size());
+ assert(column_count == 1);
+
+ std::string* column_names = new std::string[column_count];
+ column_names[0] = node->getOutputSchema()[0]->getColumnName();
+
+ node->setOutputTable(TableFactory::getTempTable(node->databaseId(),
+ node->getTargetTable()->name(),
+ schema,
+ column_names,
+ limits));
+ delete[] column_names;
+ return true;
+}
+
+bool TableCountExecutor::p_execute(const NValueArray &params) {
+ TableCountPlanNode* node = dynamic_cast<TableCountPlanNode*>(m_abstractNode);
+ assert(node);
+ Table* output_table = node->getOutputTable();
+ assert(output_table);
+ assert ((int)output_table->columnCount() == 1);
+
+ Table* target_table = dynamic_cast<Table*>(node->getTargetTable());
+ assert(target_table);
+ VOLT_TRACE("Table Count table :\n %s",
+ target_table->debug().c_str());
+ VOLT_DEBUG("Table Count table : %s which has %d active, %d"
+ " allocated, %d used tuples",
+ target_table->name().c_str(),
+ (int)target_table->activeTupleCount(),
+ (int)target_table->allocatedTupleCount(),
+ (int)target_table->usedTupleCount());
+
+ assert (node->getPredicate() == NULL);
+
+ TableIterator iterator = target_table->iterator();
+ TableTuple& tmptup = output_table->tempTuple();
+ tmptup.setNValue(0, ValueFactory::getBigIntValue( iterator.getSize() ));
+ output_table->insertTuple(tmptup);
+
+
+ //printf("Table count answer: %d", iterator.getSize());
+ //printf("\n%s\n", output_table->debug().c_str());
+ VOLT_TRACE("\n%s\n", output_table->debug().c_str());
+ VOLT_DEBUG("Finished Table Counting");
+
+ return true;
+}
+
+TableCountExecutor::~TableCountExecutor() {
+}
+
41 src/ee/executors/tablecountexecutor.h
View
@@ -0,0 +1,41 @@
+/* This file is part of VoltDB.
+ * Copyright (C) 2008-2012 VoltDB Inc.
+ *
+ * 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/>.
+ */
+
+
+#ifndef HSTORETABLECOUNTEXECUTOR_H
+#define HSTORETABLECOUNTEXECUTOR_H
+
+#include "common/common.h"
+#include "common/valuevector.h"
+#include "executors/abstractexecutor.h"
+
+namespace voltdb
+{
+ class TableCountExecutor : public AbstractExecutor {
+ public:
+ TableCountExecutor(VoltDBEngine *engine, AbstractPlanNode* abstract_node)
+ : AbstractExecutor(engine, abstract_node)
+ {}
+ ~TableCountExecutor();
+ protected:
+ bool p_init(AbstractPlanNode* abstract_node,
+ TempTableLimits* limits);
+ bool p_execute(const NValueArray& params);
+ };
+}
+
+#endif
1  src/ee/plannodes/nodes.h
View
@@ -54,6 +54,7 @@
#include "plannodes/distinctnode.h"
#include "plannodes/indexscannode.h"
#include "plannodes/indexcountnode.h"
+#include "plannodes/tablecountnode.h"
#include "plannodes/insertnode.h"
#include "plannodes/limitnode.h"
#include "plannodes/materializenode.h"
12 src/ee/plannodes/plannodeutil.cpp
View
@@ -75,6 +75,12 @@ voltdb::AbstractPlanNode* getEmptyPlanNode(voltdb::PlanNodeType type) {
ret = new voltdb::IndexCountPlanNode();
break;
// ------------------------------------------------------------------
+ // TableCount
+ // ------------------------------------------------------------------
+ case (voltdb::PLAN_NODE_TYPE_TABLECOUNT):
+ ret = new voltdb::TableCountPlanNode();
+ break;
+ // ------------------------------------------------------------------
// NestLoop
// ------------------------------------------------------------------
case (voltdb::PLAN_NODE_TYPE_NESTLOOP):
@@ -193,6 +199,12 @@ std::string getTypeName(voltdb::PlanNodeType type) {
ret = "INDEXCOUNT";
break;
// ------------------------------------------------------------------
+ // TableScan
+ // ------------------------------------------------------------------
+ case (voltdb::PLAN_NODE_TYPE_TABLECOUNT):
+ ret = "TABLECOUNT";
+ break;
+ // ------------------------------------------------------------------
// NestLoop
// ------------------------------------------------------------------
case (voltdb::PLAN_NODE_TYPE_NESTLOOP):
37 src/ee/plannodes/tablecountnode.cpp
View
@@ -0,0 +1,37 @@
+/* This file is part of VoltDB.
+ * Copyright (C) 2008-2012 VoltDB Inc.
+ *
+ * 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/>.
+ */
+
+#include <sstream>
+#include "tablecountnode.h"
+#include "common/common.h"
+#include "expressions/abstractexpression.h"
+#include "storage/table.h"
+
+namespace voltdb {
+
+TableCountPlanNode::~TableCountPlanNode() {
+}
+
+std::string TableCountPlanNode::debugInfo(const std::string &spacer) const {
+ std::ostringstream buffer;
+ buffer << this->AbstractScanPlanNode::debugInfo(spacer);
+ assert(m_predicate == NULL);
+ buffer << spacer << "TABLE COUNT Expression: <NULL>";
+ return (buffer.str());
+}
+
+}
49 src/ee/plannodes/tablecountnode.h
View
@@ -0,0 +1,49 @@
+/* This file is part of VoltDB.
+ * Copyright (C) 2008-2012 VoltDB Inc.
+ *
+ * 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/>.
+ */
+
+#ifndef HSTORETABLECOUNTNODE_H
+#define HSTORETABLECOUNTNODE_H
+
+#include "common/common.h"
+#include "abstractscannode.h"
+
+namespace voltdb {
+
+class AbstractExpression;
+
+/**
+ *
+ */
+class TableCountPlanNode : public AbstractScanPlanNode {
+ public:
+ TableCountPlanNode(CatalogId id) : AbstractScanPlanNode(id) {
+ // Do nothing
+ }
+ TableCountPlanNode() : AbstractScanPlanNode() {
+ // Do nothing
+ }
+
+ ~TableCountPlanNode();
+
+ virtual PlanNodeType getPlanNodeType() const { return (PLAN_NODE_TYPE_TABLECOUNT); }
+
+ std::string debugInfo(const std::string &spacer) const;
+};
+
+}
+
+#endif
6 src/ee/storage/tableiterator.h
View
@@ -83,6 +83,7 @@ class TableIterator : public TupleIterator {
bool next(TableTuple &out);
bool hasNext();
int getLocation() const;
+ uint32_t getSize() const;
private:
// Get an iterator via table->iterator()
@@ -259,11 +260,14 @@ inline bool TableIterator::tempNext(TableTuple &out) {
return false;
}
-
inline int TableIterator::getLocation() const {
return m_location;
}
+inline uint32_t TableIterator::getSize() const {
+ return m_activeTuples;
+}
+
}
#endif
16 src/frontend/org/voltdb/planner/microoptimizations/ReplaceWithIndexCounter.java
View
@@ -31,6 +31,8 @@
import org.voltdb.plannodes.AggregatePlanNode;
import org.voltdb.plannodes.IndexCountPlanNode;
import org.voltdb.plannodes.IndexScanPlanNode;
+import org.voltdb.plannodes.SeqScanPlanNode;
+import org.voltdb.plannodes.TableCountPlanNode;
import org.voltdb.types.ExpressionType;
import org.voltdb.utils.CatalogUtil;
@@ -81,6 +83,20 @@ AbstractPlanNode recursivelyApply(AbstractPlanNode plan) {
return plan;
AbstractPlanNode child = plan.getChild(0);
+ if (child instanceof SeqScanPlanNode) {
+ // What else should I check if it is a query like:
+ // "Select Count(*) from Table"
+ SeqScanPlanNode ssp = (SeqScanPlanNode)child;
+ if (ssp.getPredicate() == null) {
+ assert(plan.getParent(0) != null);
+ TableCountPlanNode tcp = new TableCountPlanNode(
+ ssp, (AggregatePlanNode) plan);
+
+ plan.removeFromGraph();
+ child.removeFromGraph();
+ return tcp ;
+ }
+ }
if ((child instanceof IndexScanPlanNode) == false)
return plan;
63 src/frontend/org/voltdb/plannodes/TableCountPlanNode.java
View
@@ -0,0 +1,63 @@
+/* This file is part of VoltDB.
+ * Copyright (C) 2008-2012 VoltDB Inc.
+ *
+ * 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 org.voltdb.catalog.Cluster;
+import org.voltdb.catalog.Database;
+import org.voltdb.compiler.DatabaseEstimates;
+import org.voltdb.compiler.ScalarValueHints;
+import org.voltdb.planner.PlanStatistics;
+import org.voltdb.types.PlanNodeType;
+
+public class TableCountPlanNode extends AbstractScanPlanNode {
+
+ public TableCountPlanNode(SeqScanPlanNode ssp, AggregatePlanNode apn) {
+ super();
+ m_outputSchema = apn.getOutputSchema().clone();
+ m_estimatedOutputTupleCount = 1;
+ m_targetTableAlias = ssp.getTargetTableAlias();
+ m_targetTableName = ssp.getTargetTableName();
+ m_tableSchema = ssp.getTableSchema();
+ }
+
+ @Override
+ public PlanNodeType getPlanNodeType() {
+ return PlanNodeType.TABLECOUNT;
+ }
+
+ @Override
+ public void generateOutputSchema(Database db){}
+
+ @Override
+ public void resolveColumnIndexes(){}
+
+ @Override
+ public boolean computeEstimatesRecursively(PlanStatistics stats, Cluster cluster, Database db, DatabaseEstimates estimates, ScalarValueHints[] paramHints) {
+// Table target = db.getTables().getIgnoreCase(m_targetTableName);
+// assert(target != null);
+// DatabaseEstimates.TableEstimates tableEstimates = estimates.getEstimatesForTable(target.getTypeName());
+// stats.incrementStatistic(0, StatsField.TUPLES_READ, tableEstimates.maxTuples);
+ m_estimatedOutputTupleCount = 1;
+ return true;
+ }
+
+ @Override
+ protected String explainPlanForNode(String indent) {
+ return "TABLE COUNT of \"" + m_targetTableName + "\"";
+ }
+}
2  src/frontend/org/voltdb/types/PlanNodeType.java
View
@@ -38,6 +38,7 @@
import org.voltdb.plannodes.ReceivePlanNode;
import org.voltdb.plannodes.SendPlanNode;
import org.voltdb.plannodes.SeqScanPlanNode;
+import org.voltdb.plannodes.TableCountPlanNode;
import org.voltdb.plannodes.UnionPlanNode;
import org.voltdb.plannodes.UpdatePlanNode;
@@ -53,6 +54,7 @@
SEQSCAN (10, SeqScanPlanNode.class),
INDEXSCAN (11, IndexScanPlanNode.class),
INDEXCOUNT (12, IndexCountPlanNode.class),
+ TABLECOUNT (13, TableCountPlanNode.class),
//
// Join Nodes
111 tests/frontend/org/voltdb/regressionsuites/TestTableCountSuite.java
View
@@ -0,0 +1,111 @@
+/* This file is part of VoltDB.
+ * Copyright (C) 2008-2012 VoltDB Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.voltdb.regressionsuites;
+
+import junit.framework.Test;
+
+import org.voltdb.BackendTarget;
+import org.voltdb.VoltTable;
+import org.voltdb.client.Client;
+import org.voltdb.compiler.VoltProjectBuilder;
+import org.voltdb_testprocs.regressionsuites.sqlfeatureprocs.BatchedMultiPartitionTest;
+public class TestTableCountSuite extends RegressionSuite {
+
+ // procedures used by these tests
+ static final Class<?>[] PROCEDURES = {
+ };
+
+ /**
+ * Constructor needed for JUnit. Should just pass on parameters to superclass.
+ * @param name The name of the method to test. This is just passed to the superclass.
+ */
+ public TestTableCountSuite(String name) {
+ super(name);
+ }
+
+ public void testOneColumnUniqueIndex() throws Exception {
+ Client client = getClient();
+
+ client.callProcedure("TU1.insert", 1, 1);
+ client.callProcedure("TU1.insert", 2, 2);
+ client.callProcedure("TU1.insert", 3, 3);
+ client.callProcedure("TU1.insert", 6, 6);
+ client.callProcedure("TU1.insert", 8, 8);
+
+ VoltTable table;
+
+ table = client.callProcedure("@AdHoc","SELECT COUNT(*) FROM TU1").getResults()[0];
+ assertTrue(table.getRowCount() == 1);
+ assertTrue(table.advanceRow());
+ assertEquals(5, table.getLong(0));
+ }
+
+ /**
+ * Build a list of the tests that will be run when TestTPCCSuite gets run by JUnit.
+ * Use helper classes that are part of the RegressionSuite framework.
+ * This particular class runs all tests on the the local JNI backend with both
+ * one and two partition configurations, as well as on the hsql backend.
+ *
+ * @return The TestSuite containing all the tests to be run.
+ */
+ static public Test suite() {
+ VoltServerConfig config = null;
+
+ // the suite made here will all be using the tests from this class
+ MultiConfigSuiteBuilder builder = new MultiConfigSuiteBuilder(TestTableCountSuite.class);
+
+ // build up a project builder for the workload
+ VoltProjectBuilder project = new VoltProjectBuilder();
+ project.addSchema(BatchedMultiPartitionTest.class.getResource("sqlindex-ddl.sql"));
+ project.addProcedures(PROCEDURES);
+ project.addPartitionInfo("TU1", "ID");
+ project.addPartitionInfo("TU2", "UNAME");
+ project.addPartitionInfo("TU3", "TEL");
+ project.addPartitionInfo("TU4", "UNAME");
+ project.addPartitionInfo("TM1", "ID");
+ project.addPartitionInfo("TM2", "UNAME");
+
+ boolean success;
+
+ /////////////////////////////////////////////////////////////
+ // CONFIG #1: 1 Local Site/Partitions running on JNI backend
+ /////////////////////////////////////////////////////////////
+
+ // get a server config for the native backend with one sites/partitions
+ config = new LocalCluster("sqlCountingIndex-onesite.jar", 1, 1, 0, BackendTarget.NATIVE_EE_JNI);
+
+ // build the jarfile
+ success = config.compile(project);
+ assert(success);
+
+ // add this config to the set of tests to run
+ builder.addServerConfig(config);
+
+ return builder;
+ }
+
+ public static void main(String args[]) {
+ org.junit.runner.JUnitCore.runClasses(TestIndexCountSuite.class);
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.