quickstep-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jianq...@apache.org
Subject incubator-quickstep git commit: Optimizer logical changes for ScalarQueryLiteral
Date Sat, 05 Nov 2016 06:22:20 GMT
Repository: incubator-quickstep
Updated Branches:
  refs/heads/collision-free-agg 3b0f4e054 -> d43e9c8ed


Optimizer logical changes for ScalarQueryLiteral


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/d43e9c8e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/d43e9c8e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/d43e9c8e

Branch: refs/heads/collision-free-agg
Commit: d43e9c8edf51d99f21c7652fb8a7adb9de46701a
Parents: 3b0f4e0
Author: Jianqiao Zhu <jianqiao@cs.wisc.edu>
Authored: Sat Nov 5 01:22:09 2016 -0500
Committer: Jianqiao Zhu <jianqiao@cs.wisc.edu>
Committed: Sat Nov 5 01:22:09 2016 -0500

----------------------------------------------------------------------
 expressions/Expressions.proto                   |   8 +
 expressions/scalar/CMakeLists.txt               |  16 ++
 expressions/scalar/Scalar.hpp                   |   1 +
 expressions/scalar/ScalarQueryLiteral.cpp       |  74 ++++++++
 expressions/scalar/ScalarQueryLiteral.hpp       | 116 +++++++++++++
 query_optimizer/CMakeLists.txt                  |   1 +
 query_optimizer/LogicalGenerator.cpp            |   3 +-
 query_optimizer/PhysicalGenerator.cpp           |   4 +-
 .../expressions/AttributeReference.cpp          |  11 +-
 query_optimizer/expressions/CMakeLists.txt      |   1 +
 query_optimizer/expressions/ExpressionType.hpp  |   1 +
 query_optimizer/expressions/PatternMatcher.hpp  |   1 +
 query_optimizer/logical/TopLevelPlan.cpp        |   5 +
 query_optimizer/rules/CMakeLists.txt            |  11 +-
 .../PushDownLowCostDisjunctivePredicate.cpp     | 161 +++++++++++++++++-
 .../PushDownLowCostDisjunctivePredicate.hpp     |  25 ++-
 query_optimizer/rules/UnnestSubqueries.cpp      |  17 +-
 .../CollisionFreeAggregationStateHashTable.cpp  |  65 +++++--
 .../CollisionFreeAggregationStateHashTable.hpp  | 168 +++++++++++--------
 19 files changed, 584 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/expressions/Expressions.proto
----------------------------------------------------------------------
diff --git a/expressions/Expressions.proto b/expressions/Expressions.proto
index 8d923c5..261e713 100644
--- a/expressions/Expressions.proto
+++ b/expressions/Expressions.proto
@@ -50,6 +50,7 @@ message Scalar {
     UNARY_EXPRESSION = 2;
     BINARY_EXPRESSION = 3;
     CASE_EXPRESSION = 4;
+    SCALAR_QUERY_LITERAL = 5;
   }
 
   required ScalarDataSource data_source = 1;
@@ -123,3 +124,10 @@ message ScalarCaseExpression {
     optional Scalar else_result_expression = 163;
   }
 }
+
+message ScalarQueryLiteral {
+  extend Scalar {
+    optional int32 subplan_id = 192;
+    optional Type value_type = 193;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/expressions/scalar/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/expressions/scalar/CMakeLists.txt b/expressions/scalar/CMakeLists.txt
index 8f509da..ddf6e65 100644
--- a/expressions/scalar/CMakeLists.txt
+++ b/expressions/scalar/CMakeLists.txt
@@ -29,6 +29,9 @@ add_library(quickstep_expressions_scalar_ScalarCaseExpression
 add_library(quickstep_expressions_scalar_ScalarLiteral
             ScalarLiteral.cpp
             ScalarLiteral.hpp)
+add_library(quickstep_expressions_scalar_ScalarQueryLiteral
+            ScalarQueryLiteral.cpp
+            ScalarQueryLiteral.hpp)
 add_library(quickstep_expressions_scalar_ScalarUnaryExpression
             ScalarUnaryExpression.cpp
             ScalarUnaryExpression.hpp)
@@ -92,6 +95,18 @@ target_link_libraries(quickstep_expressions_scalar_ScalarLiteral
                       quickstep_types_TypedValue_proto
                       quickstep_types_containers_ColumnVector
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_expressions_scalar_ScalarQueryLiteral
+                      quickstep_catalog_CatalogTypedefs
+                      quickstep_expressions_Expressions_proto
+                      quickstep_expressions_scalar_Scalar
+                      quickstep_storage_StorageBlockInfo
+                      quickstep_storage_ValueAccessor
+                      quickstep_types_Type
+                      quickstep_types_Type_proto
+                      quickstep_types_TypedValue
+                      quickstep_types_TypedValue_proto
+                      quickstep_types_containers_ColumnVector
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_expressions_scalar_ScalarUnaryExpression
                       quickstep_catalog_CatalogTypedefs
                       quickstep_expressions_Expressions_proto
@@ -114,6 +129,7 @@ target_link_libraries(quickstep_expressions_scalar
                       quickstep_expressions_scalar_ScalarBinaryExpression
                       quickstep_expressions_scalar_ScalarCaseExpression
                       quickstep_expressions_scalar_ScalarLiteral
+                      quickstep_expressions_scalar_ScalarQueryLiteral
                       quickstep_expressions_scalar_ScalarUnaryExpression)
 
 # Tests:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/expressions/scalar/Scalar.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/Scalar.hpp b/expressions/scalar/Scalar.hpp
index 2db850a..cd91b70 100644
--- a/expressions/scalar/Scalar.hpp
+++ b/expressions/scalar/Scalar.hpp
@@ -55,6 +55,7 @@ class Scalar {
     kUnaryExpression,
     kBinaryExpression,
     kCaseExpression,
+    kScalarQueryLiteral,
     kNumScalarDataSources  // Not a real ScalarDataSource, exists for counting purposes.
   };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/expressions/scalar/ScalarQueryLiteral.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarQueryLiteral.cpp b/expressions/scalar/ScalarQueryLiteral.cpp
new file mode 100644
index 0000000..a856726
--- /dev/null
+++ b/expressions/scalar/ScalarQueryLiteral.cpp
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "expressions/scalar/ScalarQueryLiteral.hpp"
+
+#include <utility>
+#include <vector>
+
+#include "expressions/Expressions.pb.h"
+#include "storage/ValueAccessor.hpp"
+#include "types/Type.hpp"
+#include "types/Type.pb.h"
+#include "types/TypedValue.hpp"
+#include "types/TypedValue.pb.h"
+#include "types/containers/ColumnVector.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+serialization::Scalar ScalarQueryLiteral::getProto() const {
+  DCHECK_GE(subplan_id_, 0);
+  DCHECK(literal_reference_ == nullptr);
+
+  serialization::Scalar proto;
+  proto.set_data_source(serialization::Scalar::SCALAR_QUERY_LITERAL);
+  proto.SetExtension(serialization::ScalarQueryLiteral::subplan_id, subplan_id_);
+  proto.MutableExtension(serialization::ScalarQueryLiteral::value_type)
+      ->CopyFrom(type_.getProto());
+
+  return proto;
+}
+
+Scalar* ScalarQueryLiteral::clone() const {
+  return new ScalarQueryLiteral(literal_reference_, type_);
+}
+
+ColumnVector* ScalarQueryLiteral::getAllValues(
+    ValueAccessor *accessor,
+    const SubBlocksReference *sub_blocks_ref) const {
+  return ColumnVector::MakeVectorOfValue(
+      type_,
+      *literal_reference_,
+      accessor->getNumTuplesVirtual());
+}
+
+ColumnVector* ScalarQueryLiteral::getAllValuesForJoin(
+    const relation_id left_relation_id,
+    ValueAccessor *left_accessor,
+    const relation_id right_relation_id,
+    ValueAccessor *right_accessor,
+    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
+  return ColumnVector::MakeVectorOfValue(type_,
+                                         *literal_reference_,
+                                         joined_tuple_ids.size());
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/expressions/scalar/ScalarQueryLiteral.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarQueryLiteral.hpp b/expressions/scalar/ScalarQueryLiteral.hpp
new file mode 100644
index 0000000..61dc903
--- /dev/null
+++ b/expressions/scalar/ScalarQueryLiteral.hpp
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_EXPRESSIONS_SCALAR_SCALAR_QUERY_LITERAL_HPP_
+#define QUICKSTEP_EXPRESSIONS_SCALAR_SCALAR_QUERY_LITERAL_HPP_
+
+#include <utility>
+#include <vector>
+
+#include "catalog/CatalogTypedefs.hpp"
+#include "expressions/Expressions.pb.h"
+#include "expressions/scalar/Scalar.hpp"
+#include "storage/StorageBlockInfo.hpp"
+#include "types/TypedValue.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+class ColumnVector;
+class Type;
+class ValueAccessor;
+
+struct SubBlocksReference;
+
+/** \addtogroup Expressions
+ *  @{
+ */
+
+class ScalarQueryLiteral : public Scalar {
+ public:
+  ScalarQueryLiteral(const int subplan_id,
+                     const Type &value_type)
+      : Scalar(value_type),
+        literal_reference_(nullptr),
+        subplan_id_(subplan_id) {
+  }
+
+  ScalarQueryLiteral(const TypedValue *literal_reference,
+                     const Type &value_type)
+      : Scalar(value_type),
+        literal_reference_(literal_reference),
+        subplan_id_(-1) {
+  }
+
+  ~ScalarQueryLiteral() override {
+  }
+
+  serialization::Scalar getProto() const override;
+
+  Scalar* clone() const override;
+
+  ScalarDataSource getDataSource() const override {
+    return kScalarQueryLiteral;
+  }
+
+  TypedValue getValueForSingleTuple(const ValueAccessor &accessor,
+                                    const tuple_id tuple) const override {
+    return literal_reference_->makeReferenceToThis();
+  }
+
+  TypedValue getValueForJoinedTuples(
+      const ValueAccessor &left_accessor,
+      const relation_id left_relation_id,
+      const tuple_id left_tuple_id,
+      const ValueAccessor &right_accessor,
+      const relation_id right_relation_id,
+      const tuple_id right_tuple_id) const override {
+    return literal_reference_->makeReferenceToThis();
+  }
+
+  bool hasStaticValue() const override {
+    return true;
+  }
+
+  const TypedValue& getStaticValue() const override {
+    return *literal_reference_;
+  }
+
+  ColumnVector* getAllValues(ValueAccessor *accessor,
+                             const SubBlocksReference *sub_blocks_ref) const override;
+
+  ColumnVector* getAllValuesForJoin(
+      const relation_id left_relation_id,
+      ValueAccessor *left_accessor,
+      const relation_id right_relation_id,
+      ValueAccessor *right_accessor,
+      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override;
+
+ private:
+  const TypedValue *literal_reference_;
+  const int subplan_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScalarQueryLiteral);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_EXPRESSIONS_SCALAR_SCALAR_QUERY_LITERAL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/CMakeLists.txt b/query_optimizer/CMakeLists.txt
index 225955d..23929e8 100644
--- a/query_optimizer/CMakeLists.txt
+++ b/query_optimizer/CMakeLists.txt
@@ -215,6 +215,7 @@ target_link_libraries(quickstep_queryoptimizer_PhysicalGenerator
                       quickstep_queryoptimizer_rules_AttachLIPFilters
                       quickstep_queryoptimizer_rules_InjectJoinFilters
                       quickstep_queryoptimizer_rules_PruneColumns
+                      quickstep_queryoptimizer_rules_PushDownLowCostDisjunctivePredicate
                       quickstep_queryoptimizer_rules_StarSchemaHashJoinOrderOptimization
                       quickstep_queryoptimizer_rules_SwapProbeBuild
                       quickstep_queryoptimizer_strategy_Aggregate

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/LogicalGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/LogicalGenerator.cpp b/query_optimizer/LogicalGenerator.cpp
index abeca53..9c28c95 100644
--- a/query_optimizer/LogicalGenerator.cpp
+++ b/query_optimizer/LogicalGenerator.cpp
@@ -56,7 +56,8 @@ L::LogicalPtr LogicalGenerator::generatePlan(
   DVLOG(4) << "Initial logical plan:\n" << logical_plan_->toString();
 
   optimizePlan();
-  DVLOG(4) << "Optimized logical plan:\n" << logical_plan_->toString();
+  std::cerr << "Optimized logical plan:\n" << logical_plan_->toString();
+  exit(0);
 
   return logical_plan_;
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/PhysicalGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/PhysicalGenerator.cpp b/query_optimizer/PhysicalGenerator.cpp
index 0e1b61e..dc9eab7 100644
--- a/query_optimizer/PhysicalGenerator.cpp
+++ b/query_optimizer/PhysicalGenerator.cpp
@@ -27,10 +27,11 @@
 #include "query_optimizer/logical/Logical.hpp"
 #include "query_optimizer/physical/Physical.hpp"
 #include "query_optimizer/rules/AttachLIPFilters.hpp"
+#include "query_optimizer/rules/InjectJoinFilters.hpp"
 #include "query_optimizer/rules/PruneColumns.hpp"
+#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
 #include "query_optimizer/rules/StarSchemaHashJoinOrderOptimization.hpp"
 #include "query_optimizer/rules/SwapProbeBuild.hpp"
-#include "query_optimizer/rules/InjectJoinFilters.hpp"
 #include "query_optimizer/strategy/Aggregate.hpp"
 #include "query_optimizer/strategy/Join.hpp"
 #include "query_optimizer/strategy/OneToOne.hpp"
@@ -106,6 +107,7 @@ P::PhysicalPtr PhysicalGenerator::generateInitialPlan(
 P::PhysicalPtr PhysicalGenerator::optimizePlan() {
   std::vector<std::unique_ptr<Rule<P::Physical>>> rules;
   rules.emplace_back(new PruneColumns());
+  rules.emplace_back(new PushDownLowCostDisjunctivePredicate());
   if (FLAGS_reorder_hash_joins) {
     rules.emplace_back(new StarSchemaHashJoinOrderOptimization());
     rules.emplace_back(new PruneColumns());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/expressions/AttributeReference.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/AttributeReference.cpp b/query_optimizer/expressions/AttributeReference.cpp
index f0e49d4..4c98a20 100644
--- a/query_optimizer/expressions/AttributeReference.cpp
+++ b/query_optimizer/expressions/AttributeReference.cpp
@@ -46,7 +46,16 @@ ExpressionPtr AttributeReference::copyWithNewChildren(
 
 std::vector<AttributeReferencePtr> AttributeReference::getReferencedAttributes()
     const {
-  return { Create(id(), attribute_name(), attribute_alias(), relation_name(), getValueType(), scope()) };
+  if (scope_ == AttributeReferenceScope::kLocal) {
+    return {Create(id(),
+                   attribute_name(),
+                   attribute_alias(),
+                   relation_name(),
+                   getValueType(),
+                   scope())};
+  } else {
+    return {};
+  }
 }
 
 ::quickstep::Scalar *AttributeReference::concretize(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index 35fac90..0db2a54 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -341,6 +341,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions
                       quickstep_queryoptimizer_expressions_PredicateLiteral
                       quickstep_queryoptimizer_expressions_Scalar
                       quickstep_queryoptimizer_expressions_ScalarLiteral
+                      quickstep_queryoptimizer_expressions_ScalarQueryLiteral
                       quickstep_queryoptimizer_expressions_SearchedCase
                       quickstep_queryoptimizer_expressions_SimpleCase
                       quickstep_queryoptimizer_expressions_SubqueryExpression

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/expressions/ExpressionType.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/ExpressionType.hpp b/query_optimizer/expressions/ExpressionType.hpp
index 5008f1d..4ef0fe2 100644
--- a/query_optimizer/expressions/ExpressionType.hpp
+++ b/query_optimizer/expressions/ExpressionType.hpp
@@ -46,6 +46,7 @@ enum class ExpressionType {
   kLogicalNot,
   kPredicateLiteral,
   kScalarLiteral,
+  kScalarQueryLiteral,
   kSearchedCase,
   kSimpleCase,
   kSubqueryExpression,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/expressions/PatternMatcher.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/PatternMatcher.hpp b/query_optimizer/expressions/PatternMatcher.hpp
index 18d6b1c..c732df8 100644
--- a/query_optimizer/expressions/PatternMatcher.hpp
+++ b/query_optimizer/expressions/PatternMatcher.hpp
@@ -151,6 +151,7 @@ using SomeScalar = SomeExpressionNode<Scalar,
                                       ExpressionType::kLogicalOr,
                                       ExpressionType::kPredicateLiteral,
                                       ExpressionType::kScalarLiteral,
+                                      ExpressionType::kScalarQueryLiteral,
                                       ExpressionType::kSearchedCase,
                                       ExpressionType::kSimpleCase,
                                       ExpressionType::kUnaryExpression>;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/logical/TopLevelPlan.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/logical/TopLevelPlan.cpp b/query_optimizer/logical/TopLevelPlan.cpp
index 3a6eb44..4b44fd7 100644
--- a/query_optimizer/logical/TopLevelPlan.cpp
+++ b/query_optimizer/logical/TopLevelPlan.cpp
@@ -51,6 +51,11 @@ void TopLevelPlan::getFieldStringItems(
   container_child_field_names->push_back("output_attributes");
   container_child_fields->push_back(
       CastSharedPtrVector<OptimizerTreeBase>(plan_->getOutputAttributes()));
+
+  for (const auto &pair : uncorrelated_subquery_map_) {
+    inline_field_names->emplace_back(std::to_string(pair.first));
+    inline_field_values->emplace_back(std::to_string(pair.second));
+  }
 }
 
 }  // namespace logical

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/rules/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/CMakeLists.txt b/query_optimizer/rules/CMakeLists.txt
index c44e576..cace3f2 100644
--- a/query_optimizer/rules/CMakeLists.txt
+++ b/query_optimizer/rules/CMakeLists.txt
@@ -118,13 +118,18 @@ target_link_libraries(quickstep_queryoptimizer_rules_PushDownLowCostDisjunctiveP
                       quickstep_queryoptimizer_costmodel_StarSchemaSimpleCostModel
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_ExprId
-                      quickstep_queryoptimizer_physical_Aggregate
+                      quickstep_queryoptimizer_expressions_ExpressionUtil
+                      quickstep_queryoptimizer_expressions_LogicalAnd
+                      quickstep_queryoptimizer_expressions_LogicalOr
+                      quickstep_queryoptimizer_expressions_PatternMatcher
+                      quickstep_queryoptimizer_expressions_Predicate
                       quickstep_queryoptimizer_physical_HashJoin
+                      quickstep_queryoptimizer_physical_NestedLoopsJoin
                       quickstep_queryoptimizer_physical_PatternMatcher
                       quickstep_queryoptimizer_physical_Physical
                       quickstep_queryoptimizer_physical_PhysicalType
                       quickstep_queryoptimizer_physical_Selection
-                      quickstep_queryoptimizer_physical_TopLevelPlan
+                      quickstep_queryoptimizer_physical_TableReference
                       quickstep_queryoptimizer_rules_Rule
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_rules_PushDownSemiAntiJoin
@@ -199,6 +204,7 @@ target_link_libraries(quickstep_queryoptimizer_rules_InjectJoinFilters
                       quickstep_utility_lipfilter_LIPFilter)
 target_link_libraries(quickstep_queryoptimizer_rules_UnnestSubqueries
                       quickstep_queryoptimizer_OptimizerContext
+                      quickstep_queryoptimizer_expressions_Alias
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_ComparisonExpression
                       quickstep_queryoptimizer_expressions_Exists
@@ -250,6 +256,7 @@ target_link_libraries(quickstep_queryoptimizer_rules
                       quickstep_queryoptimizer_rules_InjectJoinFilters
                       quickstep_queryoptimizer_rules_PruneColumns
                       quickstep_queryoptimizer_rules_PushDownFilter
+                      quickstep_queryoptimizer_rules_PushDownLowCostDisjunctivePredicate
                       quickstep_queryoptimizer_rules_PushDownSemiAntiJoin
                       quickstep_queryoptimizer_rules_Rule
                       quickstep_queryoptimizer_rules_RuleHelper

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp b/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp
index dfe5d53..6799f16 100644
--- a/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp
+++ b/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp
@@ -17,7 +17,7 @@
  * under the License.
  **/
 
-#include "query_optimizer/rules/AttachLIPFilters.hpp"
+#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
 
 #include <map>
 #include <set>
@@ -28,15 +28,18 @@
 
 #include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
 #include "query_optimizer/expressions/AttributeReference.hpp"
-#include "query_optimizer/physical/LIPFilterConfiguration.hpp"
-#include "query_optimizer/physical/Aggregate.hpp"
+#include "query_optimizer/expressions/ExpressionUtil.hpp"
+#include "query_optimizer/expressions/LogicalAnd.hpp"
+#include "query_optimizer/expressions/LogicalOr.hpp"
+#include "query_optimizer/expressions/PatternMatcher.hpp"
+#include "query_optimizer/expressions/Predicate.hpp"
 #include "query_optimizer/physical/HashJoin.hpp"
+#include "query_optimizer/physical/NestedLoopsJoin.hpp"
 #include "query_optimizer/physical/PatternMatcher.hpp"
 #include "query_optimizer/physical/Physical.hpp"
 #include "query_optimizer/physical/PhysicalType.hpp"
 #include "query_optimizer/physical/Selection.hpp"
-#include "query_optimizer/physical/TopLevelPlan.hpp"
-#include "utility/lip_filter/LIPFilter.hpp"
+#include "query_optimizer/physical/TableReference.hpp"
 
 #include "glog/logging.h"
 
@@ -46,6 +49,154 @@ namespace optimizer {
 namespace E = ::quickstep::optimizer::expressions;
 namespace P = ::quickstep::optimizer::physical;
 
+P::PhysicalPtr PushDownLowCostDisjunctivePredicate::apply(const P::PhysicalPtr &input) {
+  DCHECK(input->getPhysicalType() == P::PhysicalType::kTopLevelPlan);
+
+  const P::TopLevelPlanPtr top_level_plan =
+     std::static_pointer_cast<const P::TopLevelPlan>(input);
+  cost_model_.reset(
+      new cost::StarSchemaSimpleCostModel(
+          top_level_plan->shared_subplans()));
+
+  collectApplicablePredicates(input);
+//  std::cout << "Num nodes = " << applicable_predicates_.size() << "\n";
+//  for (const auto &pair : applicable_predicates_) {
+//    std::cout << "Num predicates = " << pair.second.predicates.size() << "\n";
+//    for (const auto &predicate : pair.second.predicates) {
+//      std::cout << predicate->toString() << "\n";
+//    }
+//  }
+
+  if (!applicable_predicates_.empty()) {
+    return attachPredicates(input);
+  } else {
+    return input;
+  }
+}
+
+void PushDownLowCostDisjunctivePredicate::collectApplicablePredicates(
+    const physical::PhysicalPtr &input) {
+  // Currently consider only stored relations with small cardinality as targets.
+  P::TableReferencePtr table_reference;
+  if (P::SomeTableReference::MatchesWithConditionalCast(input, &table_reference)) {
+    if (cost_model_->estimateCardinality(input) <= 100u) {
+      applicable_nodes_.emplace(input, table_reference->attribute_list());
+    }
+    return;
+  }
+
+  for (const auto &child : input->children()) {
+    collectApplicablePredicates(child);
+  }
+
+  E::PredicatePtr filter_predicate = nullptr;
+  switch (input->getPhysicalType()) {
+    case P::PhysicalType::kHashJoin:
+      filter_predicate =
+          std::static_pointer_cast<const P::HashJoin>(input)->residual_predicate();
+      break;
+    case P::PhysicalType::kNestedLoopsJoin:
+      filter_predicate =
+          std::static_pointer_cast<const P::NestedLoopsJoin>(input)->join_predicate();
+      break;
+    default:
+      break;
+  }
+
+  E::LogicalOrPtr disjunctive_predicate;
+  if (filter_predicate == nullptr ||
+      !E::SomeLogicalOr::MatchesWithConditionalCast(filter_predicate, &disjunctive_predicate)) {
+    return;
+  }
+
+  // Currently consider only disjunctive normal form. E.g. disjunction of conjunctions.
+  std::vector<std::vector<E::PredicatePtr>> candidate_predicates;
+  std::vector<std::vector<std::vector<E::AttributeReferencePtr>>> candidate_attributes;
+  for (const auto &conjunctive_predicate : disjunctive_predicate->operands()) {
+    candidate_predicates.emplace_back();
+    candidate_attributes.emplace_back();
+    E::LogicalAndPtr logical_and;
+    if (E::SomeLogicalAnd::MatchesWithConditionalCast(conjunctive_predicate, &logical_and)) {
+      for (const auto &predicate : logical_and->operands()) {
+        candidate_predicates.back().emplace_back(predicate);
+        candidate_attributes.back().emplace_back(
+            predicate->getReferencedAttributes());
+      }
+    } else {
+      candidate_predicates.back().emplace_back(conjunctive_predicate);
+      candidate_attributes.back().emplace_back(
+          conjunctive_predicate->getReferencedAttributes());
+    }
+  }
+
+  for (const auto &node_pair : applicable_nodes_) {
+    const std::vector<E::AttributeReferencePtr> &target_attributes = node_pair.second;
+    std::vector<E::PredicatePtr> selected_disj_preds;
+    for (std::size_t i = 0; i < candidate_predicates.size(); ++i) {
+      const auto &cand_preds = candidate_predicates[i];
+      const auto &cand_attrs = candidate_attributes[i];
+
+      std::vector<E::PredicatePtr> selected_conj_preds;
+      for (std::size_t j = 0; j < cand_preds.size(); ++j) {
+        if (E::SubsetOfExpressions(cand_attrs[j], target_attributes)) {
+          selected_conj_preds.emplace_back(cand_preds[j]);
+        }
+      }
+      if (!selected_conj_preds.empty()) {
+        selected_disj_preds.emplace_back(
+            CreateConjunctive(selected_conj_preds));
+      }
+    }
+    if (!selected_disj_preds.empty()) {
+      applicable_predicates_[node_pair.first].add(
+          CreateDisjunctive(selected_disj_preds));
+    }
+  }
+}
+
+P::PhysicalPtr PushDownLowCostDisjunctivePredicate::attachPredicates(
+    const P::PhysicalPtr &input) const {
+  std::vector<P::PhysicalPtr> new_children;
+  for (const P::PhysicalPtr &child : input->children()) {
+    const P::PhysicalPtr new_child = attachPredicates(child);
+    new_children.push_back(new_child);
+  }
+
+  const P::PhysicalPtr output =
+      new_children == input->children() ? input
+                                        : input->copyWithNewChildren(new_children);
+
+  const auto &node_it = applicable_predicates_.find(input);
+  if (node_it != applicable_predicates_.end()) {
+    const E::PredicatePtr filter_predicate =
+        CreateConjunctive(node_it->second.predicates);
+    return P::Selection::Create(output,
+                                E::ToNamedExpressions(output->getOutputAttributes()),
+                                filter_predicate);
+  }
+
+  return output;
+}
+
+E::PredicatePtr PushDownLowCostDisjunctivePredicate::CreateConjunctive(
+    const std::vector<E::PredicatePtr> predicates) {
+  DCHECK_GE(predicates.size(), 1u);
+  if (predicates.size() == 1) {
+    return predicates.front();
+  } else {
+    return E::LogicalAnd::Create(predicates);
+  }
+}
+
+E::PredicatePtr PushDownLowCostDisjunctivePredicate::CreateDisjunctive(
+    const std::vector<E::PredicatePtr> predicates) {
+  DCHECK_GE(predicates.size(), 1u);
+  if (predicates.size() == 1) {
+    return predicates.front();
+  } else {
+    return E::LogicalOr::Create(predicates);
+  }
+}
 
 
 }  // namespace optimizer

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp b/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp
index 9017437..0af704f 100644
--- a/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp
+++ b/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp
@@ -23,13 +23,13 @@
 #include <cstddef>
 #include <map>
 #include <memory>
-#include <set>
 #include <string>
 #include <vector>
 
 #include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
 #include "query_optimizer/expressions/AttributeReference.hpp"
 #include "query_optimizer/expressions/ExprId.hpp"
+#include "query_optimizer/expressions/Predicate.hpp"
 #include "query_optimizer/physical/Physical.hpp"
 #include "query_optimizer/rules/Rule.hpp"
 #include "utility/Macros.hpp"
@@ -57,6 +57,29 @@ class PushDownLowCostDisjunctivePredicate : public Rule<physical::Physical> {
   physical::PhysicalPtr apply(const physical::PhysicalPtr &input) override;
 
  private:
+  struct PredicateInfo {
+    PredicateInfo() {}
+    inline void add(expressions::PredicatePtr predicate) {
+      predicates.emplace_back(predicate);
+    }
+    std::vector<expressions::PredicatePtr> predicates;
+  };
+
+  void collectApplicablePredicates(const physical::PhysicalPtr &input);
+  physical::PhysicalPtr attachPredicates(const physical::PhysicalPtr &input) const;
+
+  static expressions::PredicatePtr CreateConjunctive(
+      const std::vector<expressions::PredicatePtr> predicates);
+
+  static expressions::PredicatePtr CreateDisjunctive(
+      const std::vector<expressions::PredicatePtr> predicates);
+
+  std::unique_ptr<cost::StarSchemaSimpleCostModel> cost_model_;
+
+  std::map<physical::PhysicalPtr,
+           std::vector<expressions::AttributeReferencePtr>> applicable_nodes_;
+  std::map<physical::PhysicalPtr, PredicateInfo> applicable_predicates_;
+
   DISALLOW_COPY_AND_ASSIGN(PushDownLowCostDisjunctivePredicate);
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/query_optimizer/rules/UnnestSubqueries.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/UnnestSubqueries.cpp b/query_optimizer/rules/UnnestSubqueries.cpp
index b376b0b..9c22d10 100644
--- a/query_optimizer/rules/UnnestSubqueries.cpp
+++ b/query_optimizer/rules/UnnestSubqueries.cpp
@@ -27,6 +27,7 @@
 #include <vector>
 
 #include "query_optimizer/OptimizerContext.hpp"
+#include "query_optimizer/expressions/Alias.hpp"
 #include "query_optimizer/expressions/AttributeReference.hpp"
 #include "query_optimizer/expressions/ComparisonExpression.hpp"
 #include "query_optimizer/expressions/Exists.hpp"
@@ -568,16 +569,20 @@ E::ExpressionPtr UnnestSubqueriesForExpession::applyInternal(
                                                             &non_hash_join_predicates);
       const L::LogicalPtr subquery = subquery_expression.subquery();
       const L::LogicalPtr new_subquery = unnest_logical_rule.apply(subquery);
-      const E::AttributeReferencePtr output_attribute = subquery->getOutputAttributes()[0];
+      const E::AttributeReferencePtr output_attribute = subquery->getOutputAttributes().front();
       DCHECK(!new_subquery->getOutputAttributes().empty());
       if (probe_join_attributes.empty()) {
         DCHECK(non_hash_join_predicates.empty());
         DCHECK_EQ(1u, new_subquery->getOutputAttributes().size()) << node->toString();
-        correlated_query_info_vec_->emplace_back(CorrelatedQueryInfo::JoinType::kCartesianJoin,
-                                                 new_subquery,
-                                                 std::move(probe_join_attributes),
-                                                 std::move(build_join_attributes),
-                                                 std::move(non_hash_join_predicates));
+        const E::AttributeReferencePtr new_output_attribute =
+            E::AttributeReference::Create(context_->nextExprId(),
+                                          output_attribute->attribute_name(),
+                                          output_attribute->attribute_alias(),
+                                          output_attribute->relation_name(),
+                                          output_attribute->getValueType(),
+                                          E::AttributeReferenceScope::kOuter);
+        uncorrelated_subqueries_->emplace(new_output_attribute->id(), new_subquery);
+        return new_output_attribute;
       } else {
         correlated_query_info_vec_->emplace_back(CorrelatedQueryInfo::JoinType::kInnerJoin,
                                                  new_subquery,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/storage/CollisionFreeAggregationStateHashTable.cpp
----------------------------------------------------------------------
diff --git a/storage/CollisionFreeAggregationStateHashTable.cpp b/storage/CollisionFreeAggregationStateHashTable.cpp
index 8c9be7b..a24a9d3 100644
--- a/storage/CollisionFreeAggregationStateHashTable.cpp
+++ b/storage/CollisionFreeAggregationStateHashTable.cpp
@@ -132,18 +132,12 @@ bool CollisionFreeAggregationStateHashTable::upsertValueAccessor(
   const attribute_id key_attr_id = key_attr_ids.front();
   const bool is_key_nullable = key_type_->isNullable();
 
-  // TODO: aux_accessor
-  CHECK_GE(key_attr_id, 0);
-
   for (std::size_t i = 0; i < num_handles_; ++i) {
     DCHECK_LE(argument_ids[i].size(), 1u);
 
     const attribute_id argument_id =
         argument_ids[i].empty() ? kInvalidAttributeID : argument_ids[i].front();
 
-    // TODO: aux_accessor
-    CHECK_GE(argument_id, 0u);
-
     const AggregationHandle *handle = handles_[i];
     const auto &argument_types = handle->getArgumentTypes();
 
@@ -157,19 +151,58 @@ bool CollisionFreeAggregationStateHashTable::upsertValueAccessor(
       is_argument_nullable = argument_type->isNullable();
     }
 
-    // TODO: aux_accessor
     InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
         base_accessor,
         [&](auto *accessor) -> void {  // NOLINT(build/c++11)
-      upsertValueAccessorDispatchHelper(is_key_nullable,
-                                        is_argument_nullable,
-                                        key_type_,
-                                        argument_type,
-                                        handle->getAggregationID(),
-                                        key_attr_id,
-                                        argument_id,
-                                        vec_tables_[i],
-                                        accessor);
+      if (key_attr_id >= 0) {
+        if (argument_id >= 0) {
+          upsertValueAccessorDispatchHelper<false>(is_key_nullable,
+                                                   is_argument_nullable,
+                                                   key_type_,
+                                                   argument_type,
+                                                   handle->getAggregationID(),
+                                                   key_attr_id,
+                                                   argument_id,
+                                                   vec_tables_[i],
+                                                   accessor,
+                                                   accessor);
+        } else {
+          upsertValueAccessorDispatchHelper<true>(is_key_nullable,
+                                                  is_argument_nullable,
+                                                  key_type_,
+                                                  argument_type,
+                                                  handle->getAggregationID(),
+                                                  key_attr_id,
+                                                  -(argument_id+2),
+                                                  vec_tables_[i],
+                                                  accessor,
+                                                  aux_accessor);
+        }
+      } else {
+        if (argument_id >= 0) {
+          upsertValueAccessorDispatchHelper<true>(is_key_nullable,
+                                                  is_argument_nullable,
+                                                  key_type_,
+                                                  argument_type,
+                                                  handle->getAggregationID(),
+                                                  -(key_attr_id+2),
+                                                  argument_id,
+                                                  vec_tables_[i],
+                                                  aux_accessor,
+                                                  accessor);
+        } else {
+          upsertValueAccessorDispatchHelper<false>(is_key_nullable,
+                                                   is_argument_nullable,
+                                                   key_type_,
+                                                   argument_type,
+                                                   handle->getAggregationID(),
+                                                   -(key_attr_id+2),
+                                                   -(argument_id+2),
+                                                   vec_tables_[i],
+                                                   aux_accessor,
+                                                   aux_accessor);
+        }
+      }
     });
   }
   return true;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d43e9c8e/storage/CollisionFreeAggregationStateHashTable.hpp
----------------------------------------------------------------------
diff --git a/storage/CollisionFreeAggregationStateHashTable.hpp b/storage/CollisionFreeAggregationStateHashTable.hpp
index 0fa539b..be76f1c 100644
--- a/storage/CollisionFreeAggregationStateHashTable.hpp
+++ b/storage/CollisionFreeAggregationStateHashTable.hpp
@@ -128,71 +128,77 @@ class CollisionFreeAggregationStateHashTable
                     num_entries_);
   }
 
-  template <typename ...ArgTypes>
+  template <bool use_two_accessors, typename ...ArgTypes>
   inline void upsertValueAccessorDispatchHelper(
       const bool is_key_nullable,
       const bool is_argument_nullable,
       ArgTypes &&...args);
 
-  template <bool is_key_nullable, bool is_value_nullable, typename ...ArgTypes>
+  template <bool ...bool_values, typename ...ArgTypes>
   inline void upsertValueAccessorDispatchHelper(
       const Type *key_type,
       ArgTypes &&...args);
 
-  template <bool is_key_nullable, bool is_value_nullable,
+  template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
             typename KeyT, typename ...ArgTypes>
   inline void upsertValueAccessorDispatchHelper(
       const Type *argument_type,
       const AggregationID agg_id,
       ArgTypes &&...args);
 
-  template <bool is_key_nullable, bool is_value_nullable,
-            typename KeyT, typename ValueAccessorT>
+  template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
+            typename KeyT, typename KeyValueAccessorT, typename ArgumentValueAccessorT>
   inline void upsertValueAccessorCountHelper(
       const attribute_id key_attr_id,
       const attribute_id argument_id,
       void *vec_table,
-      ValueAccessorT *accessor);
+      KeyValueAccessorT *key_accessor,
+      ArgumentValueAccessorT *argument_accessor);
 
-  template <bool is_key_nullable, bool is_value_nullable,
-            typename KeyT, typename ValueAccessorT>
+  template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
+            typename KeyT, typename KeyValueAccessorT, typename ArgumentValueAccessorT>
   inline void upsertValueAccessorSumHelper(
       const Type *argument_type,
       const attribute_id key_attr_id,
       const attribute_id argument_id,
       void *vec_table,
-      ValueAccessorT *accessor);
+      KeyValueAccessorT *key_accessor,
+      ArgumentValueAccessorT *argument_accessor);
 
-  template <bool is_key_nullable, typename KeyT, typename ValueAccessorT>
+  template <bool is_key_nullable, typename KeyT, typename KeyValueAccessorT>
   inline void upsertValueAccessorCountNullary(
       const attribute_id key_attr_id,
       std::atomic<std::size_t> *vec_table,
-      ValueAccessorT *accessor);
+      KeyValueAccessorT *key_accessor);
 
-  template <bool is_key_nullable, typename KeyT, typename ValueAccessorT>
+  template <bool use_two_accessors, bool is_key_nullable, typename KeyT,
+            typename KeyValueAccessorT, typename ArgumentValueAccessorT>
   inline void upsertValueAccessorCountUnary(
       const attribute_id key_attr_id,
       const attribute_id argument_id,
       std::atomic<std::size_t> *vec_table,
-      ValueAccessorT *accessor);
+      KeyValueAccessorT *key_accessor,
+      ArgumentValueAccessorT *argument_accessor);
 
-  template <bool is_key_nullable, bool is_argument_nullable,
+  template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
             typename KeyT, typename ArgumentT, typename StateT,
-            typename ValueAccessorT>
+            typename KeyValueAccessorT, typename ArgumentValueAccessorT>
   inline void upsertValueAccessorIntegerSum(
       const attribute_id key_attr_id,
       const attribute_id argument_id,
       std::atomic<StateT> *vec_table,
-      ValueAccessorT *accessor);
+      KeyValueAccessorT *key_accessor,
+      ArgumentValueAccessorT *argument_accessor);
 
-  template <bool is_key_nullable, bool is_argument_nullable,
+  template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
             typename KeyT, typename ArgumentT, typename StateT,
-            typename ValueAccessorT>
+            typename KeyValueAccessorT, typename ArgumentValueAccessorT>
   inline void upsertValueAccessorGenericSum(
       const attribute_id key_attr_id,
       const attribute_id argument_id,
       std::atomic<StateT> *vec_table,
-      ValueAccessorT *accessor);
+      KeyValueAccessorT *key_accessor,
+      ArgumentValueAccessorT *argument_accessor);
 
   template <typename KeyT>
   inline void finalizeKeyInternal(const std::size_t start_position,
@@ -296,7 +302,7 @@ class CollisionFreeAggregationStateHashTable
 // ----------------------------------------------------------------------------
 // Implementations of template methods follow.
 
-template <typename ...ArgTypes>
+template <bool use_two_accessors, typename ...ArgTypes>
 inline void CollisionFreeAggregationStateHashTable
     ::upsertValueAccessorDispatchHelper(
         const bool is_key_nullable,
@@ -304,45 +310,43 @@ inline void CollisionFreeAggregationStateHashTable
         ArgTypes &&...args) {
   if (is_key_nullable) {
     if (is_argument_nullable) {
-      upsertValueAccessorDispatchHelper<true, true>(
+      upsertValueAccessorDispatchHelper<use_two_accessors, true, true>(
           std::forward<ArgTypes>(args)...);
     } else {
-      upsertValueAccessorDispatchHelper<true, false>(
+      upsertValueAccessorDispatchHelper<use_two_accessors, true, false>(
           std::forward<ArgTypes>(args)...);
     }
   } else {
     if (is_argument_nullable) {
-      upsertValueAccessorDispatchHelper<false, true>(
+      upsertValueAccessorDispatchHelper<use_two_accessors, false, true>(
           std::forward<ArgTypes>(args)...);
     } else {
-      upsertValueAccessorDispatchHelper<false, false>(
+      upsertValueAccessorDispatchHelper<use_two_accessors, false, false>(
           std::forward<ArgTypes>(args)...);
     }
   }
 }
 
-template <bool is_key_nullable, bool is_value_nullable, typename ...ArgTypes>
+template <bool ...bool_values, typename ...ArgTypes>
 inline void CollisionFreeAggregationStateHashTable
     ::upsertValueAccessorDispatchHelper(
         const Type *key_type,
         ArgTypes &&...args) {
   switch (key_type->getTypeID()) {
     case TypeID::kInt:
-      upsertValueAccessorDispatchHelper<
-          is_key_nullable, is_value_nullable, int>(
-              std::forward<ArgTypes>(args)...);
+      upsertValueAccessorDispatchHelper<bool_values..., int>(
+          std::forward<ArgTypes>(args)...);
       return;
     case TypeID::kLong:
-      upsertValueAccessorDispatchHelper<
-          is_key_nullable, is_value_nullable, std::int64_t>(
-              std::forward<ArgTypes>(args)...);
+      upsertValueAccessorDispatchHelper<bool_values..., std::int64_t>(
+          std::forward<ArgTypes>(args)...);
       return;
     default:
       LOG(FATAL) << "Not supported";
   }
 }
 
-template <bool is_key_nullable, bool is_value_nullable,
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
           typename KeyT, typename ...ArgTypes>
 inline void CollisionFreeAggregationStateHashTable
     ::upsertValueAccessorDispatchHelper(
@@ -352,12 +356,12 @@ inline void CollisionFreeAggregationStateHashTable
   switch (agg_id) {
      case AggregationID::kCount:
        upsertValueAccessorCountHelper<
-           is_key_nullable, is_value_nullable, KeyT>(
+           use_two_accessors, is_key_nullable, is_argument_nullable, KeyT>(
                std::forward<ArgTypes>(args)...);
        return;
      case AggregationID::kSum:
        upsertValueAccessorSumHelper<
-           is_key_nullable, is_value_nullable, KeyT>(
+           use_two_accessors, is_key_nullable, is_argument_nullable, KeyT>(
                argument_type, std::forward<ArgTypes>(args)...);
        return;
      default:
@@ -365,41 +369,44 @@ inline void CollisionFreeAggregationStateHashTable
   }
 }
 
-template <bool is_key_nullable, bool is_value_nullable,
-          typename KeyT, typename ValueAccessorT>
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
+          typename KeyT, typename KeyValueAccessorT, typename ArgumentValueAccessorT>
 inline void CollisionFreeAggregationStateHashTable
     ::upsertValueAccessorCountHelper(
         const attribute_id key_attr_id,
         const attribute_id argument_id,
         void *vec_table,
-        ValueAccessorT *accessor) {
+        KeyValueAccessorT *key_accessor,
+        ArgumentValueAccessorT *argument_accessor) {
   DCHECK_GE(key_attr_id, 0u);
 
-  if (is_value_nullable && argument_id != kInvalidAttributeID) {
-    upsertValueAccessorCountUnary<is_key_nullable, KeyT>(
+  if (is_argument_nullable && argument_id != kInvalidAttributeID) {
+    upsertValueAccessorCountUnary<use_two_accessors, is_key_nullable, KeyT>(
         key_attr_id,
         argument_id,
         static_cast<std::atomic<std::size_t> *>(vec_table),
-        accessor);
+        key_accessor,
+        argument_accessor);
     return;
   } else {
     upsertValueAccessorCountNullary<is_key_nullable, KeyT>(
         key_attr_id,
         static_cast<std::atomic<std::size_t> *>(vec_table),
-        accessor);
+        key_accessor);
     return;
   }
 }
 
-template <bool is_key_nullable, bool is_value_nullable,
-          typename KeyT, typename ValueAccessorT>
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
+          typename KeyT, typename KeyValueAccessorT, typename ArgumentValueAccessorT>
 inline void CollisionFreeAggregationStateHashTable
     ::upsertValueAccessorSumHelper(
         const Type *argument_type,
         const attribute_id key_attr_id,
         const attribute_id argument_id,
         void *vec_table,
-        ValueAccessorT *accessor) {
+        KeyValueAccessorT *key_accessor,
+        ArgumentValueAccessorT *argument_accessor) {
   DCHECK_GE(key_attr_id, 0u);
   DCHECK_GE(argument_id, 0u);
   DCHECK(argument_type != nullptr);
@@ -407,35 +414,39 @@ inline void CollisionFreeAggregationStateHashTable
   switch (argument_type->getTypeID()) {
     case TypeID::kInt:
       upsertValueAccessorIntegerSum<
-          is_key_nullable, is_value_nullable, KeyT, int>(
+          use_two_accessors, is_key_nullable, is_argument_nullable, KeyT, int>(
               key_attr_id,
               argument_id,
               static_cast<std::atomic<std::int64_t> *>(vec_table),
-              accessor);
+              key_accessor,
+              argument_accessor);
       return;
     case TypeID::kLong:
       upsertValueAccessorIntegerSum<
-          is_key_nullable, is_value_nullable, KeyT, std::int64_t>(
+          use_two_accessors, is_key_nullable, is_argument_nullable, KeyT, std::int64_t>(
               key_attr_id,
               argument_id,
               static_cast<std::atomic<std::int64_t> *>(vec_table),
-              accessor);
+              key_accessor,
+              argument_accessor);
       return;
     case TypeID::kFloat:
       upsertValueAccessorGenericSum<
-          is_key_nullable, is_value_nullable, KeyT, float>(
+          use_two_accessors, is_key_nullable, is_argument_nullable, KeyT, float>(
               key_attr_id,
               argument_id,
               static_cast<std::atomic<double> *>(vec_table),
-              accessor);
+              key_accessor,
+              argument_accessor);
       return;
     case TypeID::kDouble:
       upsertValueAccessorGenericSum<
-          is_key_nullable, is_value_nullable, KeyT, double>(
+          use_two_accessors, is_key_nullable, is_argument_nullable, KeyT, double>(
               key_attr_id,
               argument_id,
               static_cast<std::atomic<double> *>(vec_table),
-              accessor);
+              key_accessor,
+              argument_accessor);
       return;
     default:
       LOG(FATAL) << "Not supported";
@@ -461,49 +472,58 @@ inline void CollisionFreeAggregationStateHashTable
   }
 }
 
-template <bool is_key_nullable, typename KeyT, typename ValueAccessorT>
+template <bool use_two_accessors, bool is_key_nullable, typename KeyT,
+          typename KeyValueAccessorT, typename ArgumentValueAccessorT>
 inline void CollisionFreeAggregationStateHashTable
     ::upsertValueAccessorCountUnary(
         const attribute_id key_attr_id,
         const attribute_id argument_id,
         std::atomic<std::size_t> *vec_table,
-        ValueAccessorT *accessor) {
-  accessor->beginIteration();
-  while (accessor->next()) {
+        KeyValueAccessorT *key_accessor,
+        ArgumentValueAccessorT *argument_accessor) {
+  key_accessor->beginIteration();
+  while (key_accessor->next()) {
+    if (use_two_accessors) {
+      argument_accessor->next();
+    }
     const KeyT *key = static_cast<const KeyT *>(
-        accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
+        key_accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
     if (is_key_nullable && key == nullptr) {
       continue;
     }
     const std::size_t loc = *key;
     existence_map_->setBit(loc);
-    if (accessor->getUntypedValue(argument_id) == nullptr) {
+    if (argument_accessor->getUntypedValue(argument_id) == nullptr) {
       continue;
     }
     vec_table[loc].fetch_add(1u, std::memory_order_relaxed);
   }
 }
 
-template <bool is_key_nullable, bool is_argument_nullable,
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
           typename KeyT, typename ArgumentT, typename StateT,
-          typename ValueAccessorT>
+          typename KeyValueAccessorT, typename ArgumentValueAccessorT>
 inline void CollisionFreeAggregationStateHashTable
     ::upsertValueAccessorIntegerSum(
         const attribute_id key_attr_id,
         const attribute_id argument_id,
         std::atomic<StateT> *vec_table,
-        ValueAccessorT *accessor) {
-  accessor->beginIteration();
-  while (accessor->next()) {
+        KeyValueAccessorT *key_accessor,
+        ArgumentValueAccessorT *argument_accessor) {
+  key_accessor->beginIteration();
+  while (key_accessor->next()) {
+    if (use_two_accessors) {
+      argument_accessor->next();
+    }
     const KeyT *key = static_cast<const KeyT *>(
-        accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
+        key_accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
     if (is_key_nullable && key == nullptr) {
       continue;
     }
     const std::size_t loc = *key;
     existence_map_->setBit(loc);
     const ArgumentT *argument = static_cast<const ArgumentT *>(
-        accessor->template getUntypedValue<is_argument_nullable>(argument_id));
+        argument_accessor->template getUntypedValue<is_argument_nullable>(argument_id));
     if (is_argument_nullable && argument == nullptr) {
       continue;
     }
@@ -511,26 +531,30 @@ inline void CollisionFreeAggregationStateHashTable
   }
 }
 
-template <bool is_key_nullable, bool is_argument_nullable,
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
           typename KeyT, typename ArgumentT, typename StateT,
-          typename ValueAccessorT>
+          typename KeyValueAccessorT, typename ArgumentValueAccessorT>
 inline void CollisionFreeAggregationStateHashTable
     ::upsertValueAccessorGenericSum(
         const attribute_id key_attr_id,
         const attribute_id argument_id,
         std::atomic<StateT> *vec_table,
-        ValueAccessorT *accessor) {
-  accessor->beginIteration();
-  while (accessor->next()) {
+        KeyValueAccessorT *key_accessor,
+        ArgumentValueAccessorT *argument_accessor) {
+  key_accessor->beginIteration();
+  while (key_accessor->next()) {
+    if (use_two_accessors) {
+      argument_accessor->next();
+    }
     const KeyT *key = static_cast<const KeyT *>(
-        accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
+        key_accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
     if (is_key_nullable && key == nullptr) {
       continue;
     }
     const std::size_t loc = *key;
     existence_map_->setBit(loc);
     const ArgumentT *argument = static_cast<const ArgumentT *>(
-        accessor->template getUntypedValue<is_argument_nullable>(argument_id));
+        argument_accessor->template getUntypedValue<is_argument_nullable>(argument_id));
     if (is_argument_nullable && argument == nullptr) {
       continue;
     }


Mime
View raw message