You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ji...@apache.org on 2017/09/15 17:17:12 UTC
incubator-quickstep git commit: Quickstep for GRAIL.
Repository: incubator-quickstep
Updated Branches:
refs/heads/trace [created] c29587a1a
Quickstep for GRAIL.
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/c29587a1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/c29587a1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/c29587a1
Branch: refs/heads/trace
Commit: c29587a1a04d07209a5e5f014b05da7521825552
Parents: d85f7a9
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Sat Sep 2 23:06:37 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Thu Sep 14 13:12:19 2017 -0500
----------------------------------------------------------------------
api/python/ancestor.py | 42 +++++
api/python/ancestor.txt | 16 ++
api/python/descendant.py | 42 +++++
api/python/example.py | 11 ++
api/python/path.py | 106 +++++++++++
api/python/plan.txt | 7 +
api/python/quickstep.py | 25 +++
api/python/quickstep.pyc | Bin 0 -> 1514 bytes
catalog/CatalogRelationStatistics.hpp | 9 +
cli/CommandExecutor.cpp | 182 ++++++++++++++-----
cli/Constants.hpp | 1 +
.../aggregation/AggregateFunctionMax.cpp | 4 +-
.../aggregation/AggregateFunctionMin.cpp | 4 +-
query_optimizer/ExecutionGenerator.cpp | 1 -
query_optimizer/resolver/Resolver.cpp | 9 +-
storage/AggregationOperationState.cpp | 3 +-
16 files changed, 410 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/api/python/ancestor.py
----------------------------------------------------------------------
diff --git a/api/python/ancestor.py b/api/python/ancestor.py
new file mode 100644
index 0000000..3318ab9
--- /dev/null
+++ b/api/python/ancestor.py
@@ -0,0 +1,42 @@
+import time
+from quickstep import Quickstep
+
+qs = Quickstep('./quickstep_client')
+
+vertices = [1299454, 31623412, 31739916, 31593563]
+
+# Truncate old tables.
+qs.execute('DROP TABLE cur; DROP TABLE next; DROP TABLE answer;')
+qs.execute('CREATE TABLE cur(id INT); CREATE TABLE next(id INT); CREATE TABLE answer(id INT);')
+
+# Initialize work table.
+init_stmts = ''
+for v in vertices:
+ init_stmts += 'INSERT INTO cur VALUES(' + str(v) + '); '
+qs.execute(init_stmts)
+qs.execute('INSERT INTO answer SELECT id FROM cur;')
+
+# Loop body
+loop_stmts = ''
+loop_stmts += 'DROP TABLE next; CREATE TABLE next(id int); '
+loop_stmts += 'INSERT INTO next SELECT edge.src FROM cur, edge ' + \
+ 'WHERE cur.id = edge.dst GROUP BY edge.src; '
+loop_stmts += 'DROP TABLE cur; CREATE TABLE cur(id int); '
+loop_stmts += 'INSERT INTO cur SELECT id FROM next WHERE id NOT IN (SELECT id FROM answer); '
+loop_stmts += 'INSERT INTO answer SELECT id FROM cur; '
+
+for i in range(50):
+ print '--\nIteration ' + str(i) + ':'
+ start = time.time()
+ qs.execute(loop_stmts)
+ end = time.time()
+
+ # We may skip this information for performance.
+ num_vertices = qs.execute('COPY SELECT COUNT(*) FROM answer TO stdout;')
+ print 'Size of graph: ' + num_vertices.rstrip()
+ print 'Time elapsed: ' + str(end - start)
+
+ num_workset = qs.execute('COPY SELECT COUNT(*) FROM cur TO stdout;').rstrip()
+ if num_workset == '0':
+ break
+
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/api/python/ancestor.txt
----------------------------------------------------------------------
diff --git a/api/python/ancestor.txt b/api/python/ancestor.txt
new file mode 100644
index 0000000..8d15955
--- /dev/null
+++ b/api/python/ancestor.txt
@@ -0,0 +1,16 @@
+CREATE TABLE r(parent VARCHAR(64), child VARCHAR(64));
+
+INSERT INTO r VALUES('bill', 'mary');
+INSERT INTO r VALUES('mary', 'john');
+...
+...
+...
+
+
+CREATE TABLE s(ancestor VARCHAR(64), offspring VARCHAR(64));
+
+=> ancestor
+
+ancestor('biil', 'mary')
+ancestor('mary', 'john')
+ancestor('bill', 'john')
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/api/python/descendant.py
----------------------------------------------------------------------
diff --git a/api/python/descendant.py b/api/python/descendant.py
new file mode 100644
index 0000000..8bdf09f
--- /dev/null
+++ b/api/python/descendant.py
@@ -0,0 +1,42 @@
+import time
+from quickstep import Quickstep
+
+qs = Quickstep('./quickstep_client')
+
+vertices = [1299454, 31623412, 31739916, 31593563]
+
+# Truncate old tables.
+qs.execute('DROP TABLE cur; DROP TABLE next; DROP TABLE answer;')
+qs.execute('CREATE TABLE cur(id INT); CREATE TABLE next(id INT); CREATE TABLE answer(id INT);')
+
+# Initialize work table.
+init_stmts = ''
+for v in vertices:
+ init_stmts += 'INSERT INTO cur VALUES(' + str(v) + '); '
+qs.execute(init_stmts)
+qs.execute('INSERT INTO answer SELECT id FROM cur;')
+
+# Loop body
+loop_stmts = ''
+loop_stmts += 'DROP TABLE next; CREATE TABLE next(id int); '
+loop_stmts += 'INSERT INTO next SELECT edge.dst FROM cur, edge ' + \
+ 'WHERE cur.id = edge.src GROUP BY edge.dst; '
+loop_stmts += 'DROP TABLE cur; CREATE TABLE cur(id int); '
+loop_stmts += 'INSERT INTO cur SELECT id FROM next WHERE id NOT IN (SELECT id FROM answer); '
+loop_stmts += 'INSERT INTO answer SELECT id FROM cur; '
+
+for i in range(100):
+ print '--\nIteration ' + str(i) + ':'
+ start = time.time()
+ qs.execute(loop_stmts)
+ end = time.time()
+
+ # We may skip this information for performance.
+ num_vertices = qs.execute('COPY SELECT COUNT(*) FROM answer TO stdout;')
+ print 'Size of graph: ' + num_vertices.rstrip()
+ print 'Time elapsed: ' + str(end - start)
+
+ num_workset = qs.execute('COPY SELECT COUNT(*) FROM cur TO stdout;').rstrip()
+ if num_workset == '0':
+ break
+
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/api/python/example.py
----------------------------------------------------------------------
diff --git a/api/python/example.py b/api/python/example.py
new file mode 100644
index 0000000..a9be4fd
--- /dev/null
+++ b/api/python/example.py
@@ -0,0 +1,11 @@
+from quickstep import Quickstep
+
+qs = Quickstep('/Users/jianqiao/Desktop/incubator-quickstep/build/Debug/quickstep_client')
+
+print 'Executing "SELECT * FROM r" ...'
+print '--'
+print qs.execute('SELECT * FROM r')
+
+print 'Executing "COPY SELECT * FROM r TO stdout WITH (FORMAT CSV, HEADER FALSE)" ...'
+print '--'
+print qs.execute('COPY SELECT * FROM r TO stdout WITH (FORMAT CSV, HEADER FALSE)')
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/api/python/path.py
----------------------------------------------------------------------
diff --git a/api/python/path.py b/api/python/path.py
new file mode 100644
index 0000000..524ef7d
--- /dev/null
+++ b/api/python/path.py
@@ -0,0 +1,106 @@
+import time
+from quickstep import Quickstep
+
+qs = Quickstep('./quickstep_client')
+
+src_vertices = [981856, 981899, 981913, 1255431, 1255572, 1255586]
+dst_vertices = [1299454, 31623412, 31739916, 31593563]
+
+max_depth = 10
+
+# First generate the backward lineage subgraph within the specified max depth.
+
+print "Prepare tables ..."
+
+# Truncate old tables.
+qs.execute('DROP TABLE cur; DROP TABLE next;')
+qs.execute('CREATE TABLE cur(id INT); CREATE TABLE next(id INT);')
+qs.execute('DROP TABLE answer; CREATE TABLE answer(id INT);')
+
+# Create subgraph edges table.
+qs.execute('DROP TABLE sg_conn;')
+qs.execute('CREATE TABLE sg_conn(src INT, dst INT, depth INT);')
+
+# Initialize work table.
+init_stmts = ''
+for v in dst_vertices:
+ init_stmts += 'INSERT INTO cur VALUES(' + str(v) + '); '
+qs.execute(init_stmts)
+qs.execute('INSERT INTO answer SELECT id FROM cur;')
+
+print "Generating backward lineage subgraph ..."
+
+# Loop body.
+loop_stmts = ''
+loop_stmts += 'INSERT INTO sg_conn SELECT e.src, e.dst, $depth ' + \
+ 'FROM cur, conn e WHERE cur.id = e.dst; '
+loop_stmts += 'DROP TABLE next; CREATE TABLE next(id int); '
+loop_stmts += 'INSERT INTO next SELECT e.src FROM cur, conn e ' + \
+ 'WHERE cur.id = e.dst GROUP BY e.src; '
+loop_stmts += 'DROP TABLE cur; CREATE TABLE cur(id int); '
+loop_stmts += 'INSERT INTO cur SELECT id FROM next WHERE id NOT IN (SELECT id FROM answer); '
+loop_stmts += 'INSERT INTO answer SELECT id FROM cur;'
+
+for i in range(max_depth):
+ print '--\nIteration ' + str(i + 1) + ':'
+ start = time.time()
+ qs.execute(loop_stmts.replace('$depth', str(i+1)))
+ end = time.time()
+
+ # We may skip this information for performance.
+ num_vertices = qs.execute('COPY SELECT COUNT(*) FROM answer TO stdout;')
+ print 'Size of graph: ' + num_vertices.rstrip()
+ print 'Time elapsed: ' + str(end - start)
+
+ num_workset = qs.execute('COPY SELECT COUNT(*) FROM cur TO stdout;').rstrip()
+ if num_workset == '0':
+ break
+
+# Then generate forward lineage sub-subgraph given sg_conn.
+
+print "Analyzing sg_conn table ..."
+qs.execute('\\analyze sg_conn\n')
+
+# Truncate old tables.
+qs.execute('DROP TABLE cur; DROP TABLE next;')
+qs.execute('CREATE TABLE cur(id INT); CREATE TABLE next(id INT);')
+
+# Initialize work table.
+init_stmts = ''
+for v in src_vertices:
+ init_stmts += 'INSERT INTO next VALUES(' + str(v) + '); '
+qs.execute(init_stmts)
+qs.execute('INSERT INTO cur SELECT id FROM answer WHERE id IN (SELECT id FROM next);')
+
+qs.execute('DROP TABLE answer; CREATE TABLE answer(id INT);')
+qs.execute('INSERT INTO answer SELECT id FROM cur;')
+
+print "Generating forward lineage sub-subgraph ..."
+
+# Loop body.
+loop_stmts = ''
+loop_stmts += 'DROP TABLE next; CREATE TABLE next(id int); '
+loop_stmts += 'INSERT INTO next SELECT e.dst FROM cur, sg_conn e ' + \
+ 'WHERE cur.id = e.src ' + \
+ 'AND e.depth + $depth <= ' + str(max_depth) + ' GROUP BY e.dst; '
+loop_stmts += 'DROP TABLE cur; CREATE TABLE cur(id int); '
+loop_stmts += 'INSERT INTO cur SELECT id FROM next WHERE id NOT IN (SELECT id FROM answer); '
+loop_stmts += 'INSERT INTO answer SELECT id FROM cur;'
+
+for i in range(max_depth):
+ print '--\nIteration ' + str(i + 1) + ':'
+ start = time.time()
+ qs.execute(loop_stmts.replace('$depth', str(i)))
+ end = time.time()
+
+ # We may skip this information for performance.
+ num_vertices = qs.execute('COPY SELECT COUNT(*) FROM answer TO stdout;')
+ print 'Size of graph: ' + num_vertices.rstrip()
+ print 'Time elapsed: ' + str(end - start)
+
+ num_workset = qs.execute('COPY SELECT COUNT(*) FROM cur TO stdout;').rstrip()
+ if num_workset == '0':
+ break
+
+print "Done."
+
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/api/python/plan.txt
----------------------------------------------------------------------
diff --git a/api/python/plan.txt b/api/python/plan.txt
new file mode 100644
index 0000000..8cc87f8
--- /dev/null
+++ b/api/python/plan.txt
@@ -0,0 +1,7 @@
+1. Given filtering condition, select all the vertices.
+2. Given filtering condition, select all the edges (together with the vertices).
+3. List vertices and edges, support navigation.
+4. Visualize vertices and edges (as a subgraph).
+5. Navigation: expand neigbours (1 hop, 2 hops).
+6. Session management, temporary tables.
+7.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/api/python/quickstep.py
----------------------------------------------------------------------
diff --git a/api/python/quickstep.py b/api/python/quickstep.py
new file mode 100644
index 0000000..4dbca8d
--- /dev/null
+++ b/api/python/quickstep.py
@@ -0,0 +1,25 @@
+from subprocess import Popen, PIPE, STDOUT
+
+class Quickstep(object):
+ def __init__(self, client_path, server_ip = None, server_port = None):
+ self.client_path = client_path
+ self.server_ip = server_ip
+ self.server_port = server_port
+
+ def __addSemicolon__(self, query):
+ return query + ('' if query.endswith(';') else ';')
+
+ def execute(self, query):
+ # query = self.__addSemicolon__(query)
+
+ cmd = self.client_path
+ if self.server_ip is not None:
+ cmd += ' -cli_network_ip=' + self.server_ip
+ if self.server_port is not None:
+ cmd += ' -cli_network_port=' + self.server_port
+
+ client_process = Popen([cmd], stdout=PIPE, stdin=PIPE, stderr=PIPE)
+ out, err = client_process.communicate(input = query)
+
+ # Currently we ignore the stderr stream and just return stdout's data.
+ return out
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/api/python/quickstep.pyc
----------------------------------------------------------------------
diff --git a/api/python/quickstep.pyc b/api/python/quickstep.pyc
new file mode 100644
index 0000000..9208aca
Binary files /dev/null and b/api/python/quickstep.pyc differ
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/catalog/CatalogRelationStatistics.hpp
----------------------------------------------------------------------
diff --git a/catalog/CatalogRelationStatistics.hpp b/catalog/CatalogRelationStatistics.hpp
index df95231..55fc747 100644
--- a/catalog/CatalogRelationStatistics.hpp
+++ b/catalog/CatalogRelationStatistics.hpp
@@ -68,6 +68,15 @@ class CatalogRelationStatistics {
serialization::CatalogRelationStatistics getProto() const;
/**
+ * @brief Clear all statistics.
+ */
+ void clear() {
+ num_tuples_ = kNullValue;
+ column_stats_.clear();
+ is_exact_ = true;
+ }
+
+ /**
* @brief Check whether the statistics are exact for the relation.
*
* return True if the statistics are exact for the relation, false otherwise.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/cli/CommandExecutor.cpp
----------------------------------------------------------------------
diff --git a/cli/CommandExecutor.cpp b/cli/CommandExecutor.cpp
index 6a84672..fb0dd4c 100644
--- a/cli/CommandExecutor.cpp
+++ b/cli/CommandExecutor.cpp
@@ -201,9 +201,28 @@ void ExecuteAnalyze(const PtrVector<ParseString> &arguments,
CatalogRelationStatistics *mutable_stat =
mutable_relation->getStatisticsMutable();
+ mutable_stat->clear();
+
const std::string rel_name = EscapeQuotes(relation.getName(), '"');
- // Get the number of distinct values for each column.
+ // Get the number of tuples for the relation.
+ std::string query_string = "SELECT COUNT(*) FROM \"";
+ query_string.append(rel_name);
+ query_string.append("\";");
+
+ TypedValue num_tuples =
+ ExecuteQueryForSingleResult(main_thread_client_id,
+ foreman_client_id,
+ query_string,
+ bus,
+ storage_manager,
+ query_processor,
+ parser_wrapper.get());
+
+ DCHECK_EQ(TypeID::kLong, num_tuples.getTypeID());
+ mutable_stat->setNumTuples(num_tuples.getLiteral<std::int64_t>());
+
+ // Get the min/max values for each column.
for (const CatalogAttribute &attribute : relation) {
const std::string attr_name = EscapeQuotes(attribute.getName(), '"');
const Type &attr_type = attribute.getType();
@@ -211,24 +230,15 @@ void ExecuteAnalyze(const PtrVector<ParseString> &arguments,
AggregateFunctionMin::Instance().canApplyToTypes({&attr_type});
bool is_max_applicable =
AggregateFunctionMax::Instance().canApplyToTypes({&attr_type});
+ if (!is_min_applicable || !is_max_applicable) {
+ continue;
+ }
- // NOTE(jianqiao): Note that the relation name and the attribute names may
- // contain non-letter characters, e.g. CREATE TABLE "with space"("1" int).
- // So here we need to format the names with double quotes (").
- std::string query_string = "SELECT COUNT(DISTINCT \"";
+ std::string query_string = "SELECT MIN(\"";
query_string.append(attr_name);
- query_string.append("\")");
- if (is_min_applicable) {
- query_string.append(", MIN(\"");
- query_string.append(attr_name);
- query_string.append("\")");
- }
- if (is_max_applicable) {
- query_string.append(", MAX(\"");
- query_string.append(attr_name);
- query_string.append("\")");
- }
- query_string.append(" FROM \"");
+ query_string.append("\"), MAX(\"");
+ query_string.append(attr_name);
+ query_string.append("\") FROM \"");
query_string.append(rel_name);
query_string.append("\";");
@@ -240,42 +250,119 @@ void ExecuteAnalyze(const PtrVector<ParseString> &arguments,
storage_manager,
query_processor,
parser_wrapper.get());
-
- auto results_it = results.begin();
- DCHECK_EQ(TypeID::kLong, results_it->getTypeID());
+ DCHECK_EQ(2u, results.size());
const attribute_id attr_id = attribute.getID();
- mutable_stat->setNumDistinctValues(attr_id,
- results_it->getLiteral<std::int64_t>());
- if (is_min_applicable) {
- ++results_it;
- mutable_stat->setMinValue(attr_id, *results_it);
- }
- if (is_max_applicable) {
- ++results_it;
- mutable_stat->setMaxValue(attr_id, *results_it);
+ mutable_stat->setMinValue(attr_id, results[0]);
+ mutable_stat->setMaxValue(attr_id, results[1]);
+ }
+
+ // Get the number of distinct values for each column.
+ for (const CatalogAttribute &attribute : relation) {
+ const std::string attr_name = EscapeQuotes(attribute.getName(), '"');
+
+ std::string query_string = "SELECT COUNT(*) FROM (SELECT \"";
+ query_string.append(attr_name);
+ query_string.append("\" FROM \"");
+ query_string.append(rel_name);
+ query_string.append("\" GROUP BY \"");
+ query_string.append(attr_name);
+ query_string.append("\") t;");
+
+ TypedValue num_distinct_values =
+ ExecuteQueryForSingleResult(main_thread_client_id,
+ foreman_client_id,
+ query_string,
+ bus,
+ storage_manager,
+ query_processor,
+ parser_wrapper.get());
+
+ DCHECK_EQ(TypeID::kLong, num_distinct_values.getTypeID());
+ mutable_stat->setNumDistinctValues(
+ attribute.getID(), num_distinct_values.getLiteral<std::int64_t>());
+ }
+
+ fprintf(out, "done\n");
+ fflush(out);
+ }
+ query_processor->markCatalogAltered();
+ query_processor->saveCatalog();
+}
+
+void ExecuteAnalyzeRange(const PtrVector<ParseString> &arguments,
+ const tmb::client_id main_thread_client_id,
+ const tmb::client_id foreman_client_id,
+ MessageBus *bus,
+ StorageManager *storage_manager,
+ QueryProcessor *query_processor,
+ FILE *out) {
+ const CatalogDatabase &database = *query_processor->getDefaultDatabase();
+
+ std::unique_ptr<SqlParserWrapper> parser_wrapper(new SqlParserWrapper());
+ std::vector<std::reference_wrapper<const CatalogRelation>> relations;
+ if (arguments.empty()) {
+ relations.insert(relations.begin(), database.begin(), database.end());
+ } else {
+ for (const auto &rel_name : arguments) {
+ const CatalogRelation *rel = database.getRelationByName(rel_name.value());
+ if (rel == nullptr) {
+ THROW_SQL_ERROR_AT(&rel_name) << "Table does not exist";
+ } else {
+ relations.emplace_back(*rel);
}
}
+ }
- // Get the number of tuples for the relation.
- std::string query_string = "SELECT COUNT(*) FROM \"";
- query_string.append(rel_name);
- query_string.append("\";");
+ // Analyze each relation in the database.
+ for (const CatalogRelation &relation : relations) {
+ fprintf(out, "Analyzing %s ... ", relation.getName().c_str());
+ fflush(out);
- TypedValue num_tuples =
- ExecuteQueryForSingleResult(main_thread_client_id,
- foreman_client_id,
- query_string,
- bus,
- storage_manager,
- query_processor,
- parser_wrapper.get());
+ CatalogRelation *mutable_relation =
+ query_processor->getDefaultDatabase()->getRelationByIdMutable(relation.getID());
+ CatalogRelationStatistics *mutable_stat =
+ mutable_relation->getStatisticsMutable();
- DCHECK_EQ(TypeID::kLong, num_tuples.getTypeID());
- mutable_stat->setNumTuples(num_tuples.getLiteral<std::int64_t>());
+ if (!mutable_stat->isExact()) {
+ mutable_stat->clear();
- mutable_stat->setExactness(true);
+ const std::string rel_name = EscapeQuotes(relation.getName(), '"');
+ for (const CatalogAttribute &attribute : relation) {
+ const std::string attr_name = EscapeQuotes(attribute.getName(), '"');
+ const Type &attr_type = attribute.getType();
+ bool is_min_applicable =
+ AggregateFunctionMin::Instance().canApplyToTypes({&attr_type});
+ bool is_max_applicable =
+ AggregateFunctionMax::Instance().canApplyToTypes({&attr_type});
+ if (!is_min_applicable || !is_max_applicable) {
+ continue;
+ }
+
+ std::string query_string = "SELECT MIN(\"";
+ query_string.append(attr_name);
+ query_string.append("\"), MAX(\"");
+ query_string.append(attr_name);
+ query_string.append("\") FROM \"");
+ query_string.append(rel_name);
+ query_string.append("\";");
+
+ std::vector<TypedValue> results =
+ ExecuteQueryForSingleRow(main_thread_client_id,
+ foreman_client_id,
+ query_string,
+ bus,
+ storage_manager,
+ query_processor,
+ parser_wrapper.get());
+ DCHECK_EQ(2u, results.size());
+
+ const attribute_id attr_id = attribute.getID();
+ mutable_stat->setMinValue(attr_id, results[0]);
+ mutable_stat->setMaxValue(attr_id, results[1]);
+ }
+ }
fprintf(out, "done\n");
fflush(out);
}
@@ -314,6 +401,13 @@ void executeCommand(const ParseStatement &statement,
bus,
storage_manager,
query_processor, out);
+ } else if (command_str == kAnalyzeRangeCommand) {
+ ExecuteAnalyzeRange(arguments,
+ main_thread_client_id,
+ foreman_client_id,
+ bus,
+ storage_manager,
+ query_processor, out);
} else {
THROW_SQL_ERROR_AT(command.command()) << "Invalid Command";
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/cli/Constants.hpp
----------------------------------------------------------------------
diff --git a/cli/Constants.hpp b/cli/Constants.hpp
index 0b4a37b..d895f32 100644
--- a/cli/Constants.hpp
+++ b/cli/Constants.hpp
@@ -30,6 +30,7 @@ namespace cli {
constexpr char kDescribeDatabaseCommand[] = "\\dt";
constexpr char kDescribeTableCommand[] = "\\d";
constexpr char kAnalyzeCommand[] = "\\analyze";
+constexpr char kAnalyzeRangeCommand[] = "\\analyzerange";
/** @} */
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/expressions/aggregation/AggregateFunctionMax.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionMax.cpp b/expressions/aggregation/AggregateFunctionMax.cpp
index cc04bf4..6ceacc9 100644
--- a/expressions/aggregation/AggregateFunctionMax.cpp
+++ b/expressions/aggregation/AggregateFunctionMax.cpp
@@ -50,7 +50,9 @@ const Type* AggregateFunctionMax::resultTypeForArgumentTypes(
return nullptr;
}
- return &(argument_types.front()->getNullableVersion());
+ // FIXME(jianqiao): The result type can be nullable when it is NOT a group-by
+ // aggregation.
+ return argument_types.front();
}
AggregationHandle* AggregateFunctionMax::createHandle(
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/expressions/aggregation/AggregateFunctionMin.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionMin.cpp b/expressions/aggregation/AggregateFunctionMin.cpp
index 9fa93de..d88169f 100644
--- a/expressions/aggregation/AggregateFunctionMin.cpp
+++ b/expressions/aggregation/AggregateFunctionMin.cpp
@@ -50,7 +50,9 @@ const Type* AggregateFunctionMin::resultTypeForArgumentTypes(
return nullptr;
}
- return &(argument_types.front()->getNullableVersion());
+ // FIXME(jianqiao): The result type can be nullable when it is NOT a group-by
+ // aggregation.
+ return argument_types.front();
}
AggregationHandle* AggregateFunctionMin::createHandle(
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/query_optimizer/ExecutionGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/ExecutionGenerator.cpp b/query_optimizer/ExecutionGenerator.cpp
index 372d576..e7ef82a 100644
--- a/query_optimizer/ExecutionGenerator.cpp
+++ b/query_optimizer/ExecutionGenerator.cpp
@@ -1878,7 +1878,6 @@ void ExecutionGenerator::convertAggregate(
use_parallel_initialization = true;
aggr_state_num_partitions = CalculateNumFinalizationPartitionsForCollisionFreeVectorTable(max_num_groups);
- DCHECK(!group_by_aggrs_info.empty());
CalculateCollisionFreeAggregationInfo(max_num_groups, group_by_aggrs_info,
aggr_state_proto->mutable_collision_free_vector_info());
} else {
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 935e235..b12f59f 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -1016,10 +1016,13 @@ L::LogicalPtr Resolver::resolveInsertSelection(
if (destination_type.equals(selection_type)) {
cast_expressions.emplace_back(selection_attributes[aid]);
} else {
- // TODO(jianqiao): implement Cast operation for non-numeric types.
+ // TODO(jianqiao): Implement Cast operation for non-numeric types.
+ // TODO(jianqiao): We temporarily disable the safely-coercible check for
+ // tricks that work around "argmin". Will switch it back once the "Cast"
+ // function is supported.
if (destination_type.getSuperTypeID() == Type::SuperTypeID::kNumeric &&
selection_type.getSuperTypeID() == Type::SuperTypeID::kNumeric &&
- destination_type.isSafelyCoercibleFrom(selection_type)) {
+ destination_type.isCoercibleFrom(selection_type)) {
// Add cast operation
const E::AttributeReferencePtr attr = selection_attributes[aid];
const E::ExpressionPtr cast_expr =
@@ -1035,7 +1038,7 @@ L::LogicalPtr Resolver::resolveInsertSelection(
<< insert_statement.relation_name()->value() << "."
<< destination_attributes[aid]->attribute_name() << " has type "
<< selection_attributes[aid]->getValueType().getName()
- << ", which cannot be safely coerced to the column's type "
+ << ", which cannot be coerced to the column's type "
<< destination_attributes[aid]->getValueType().getName();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/c29587a1/storage/AggregationOperationState.cpp
----------------------------------------------------------------------
diff --git a/storage/AggregationOperationState.cpp b/storage/AggregationOperationState.cpp
index 0f4795f..1d844ee 100644
--- a/storage/AggregationOperationState.cpp
+++ b/storage/AggregationOperationState.cpp
@@ -393,8 +393,7 @@ bool AggregationOperationState::ProtoIsValid(
}
const S::CollisionFreeVectorInfo &proto_collision_free_vector_info = proto.collision_free_vector_info();
- if (!proto_collision_free_vector_info.IsInitialized() ||
- proto_collision_free_vector_info.state_offsets_size() != group_by_expressions_size) {
+ if (!proto_collision_free_vector_info.IsInitialized()) {
return false;
}
}