Repository: incubator-quickstep
Updated Branches:
  refs/heads/common-subexpression 4f8e15273 -> 449b5e81c


Updates


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

Branch: refs/heads/common-subexpression
Commit: 449b5e81cb08cbc04100d31cc1d83a63ae66e710
Parents: 4f8e152
Author: Jianqiao Zhu <jianq...@cs.wisc.edu>
Authored: Wed Apr 5 21:42:20 2017 -0500
Committer: Jianqiao Zhu <jianq...@cs.wisc.edu>
Committed: Wed Apr 5 21:42:20 2017 -0500

----------------------------------------------------------------------
 expressions/predicate/ComparisonPredicate.cpp   | 36 +++++++----
 expressions/scalar/CMakeLists.txt               |  3 +
 expressions/scalar/Scalar.hpp                   |  7 ++-
 expressions/scalar/ScalarAttribute.cpp          |  6 +-
 expressions/scalar/ScalarAttribute.hpp          |  7 ++-
 expressions/scalar/ScalarBinaryExpression.cpp   | 30 +++++----
 expressions/scalar/ScalarBinaryExpression.hpp   |  7 ++-
 expressions/scalar/ScalarCache.hpp              | 64 ++++++++++++++++++++
 expressions/scalar/ScalarCaseExpression.cpp     | 21 ++++---
 expressions/scalar/ScalarCaseExpression.hpp     |  6 +-
 expressions/scalar/ScalarLiteral.cpp            |  6 +-
 expressions/scalar/ScalarLiteral.hpp            |  7 ++-
 expressions/scalar/ScalarSharedExpression.cpp   | 47 +++++++++++---
 expressions/scalar/ScalarSharedExpression.hpp   |  7 ++-
 expressions/scalar/ScalarUnaryExpression.cpp    | 12 ++--
 expressions/scalar/ScalarUnaryExpression.hpp    |  7 ++-
 relational_operators/HashJoinOperator.cpp       | 51 ++++++++++++----
 .../NestedLoopsJoinOperator.cpp                 |  6 +-
 storage/AggregationOperationState.cpp           |  4 +-
 storage/StorageBlock.cpp                        | 10 ++-
 storage/WindowAggregationOperationState.cpp     |  8 ++-
 21 files changed, 272 insertions(+), 80 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/predicate/ComparisonPredicate.cpp
----------------------------------------------------------------------
diff --git a/expressions/predicate/ComparisonPredicate.cpp 
b/expressions/predicate/ComparisonPredicate.cpp
index 7e454d6..84bc51a 100644
--- a/expressions/predicate/ComparisonPredicate.cpp
+++ b/expressions/predicate/ComparisonPredicate.cpp
@@ -193,7 +193,8 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
     if (short_circuit_adapter) {
       ColumnVectorPtr right_values(right_operand_->getAllValues(
           short_circuit_adapter.get(),
-          sub_blocks_ref));
+          sub_blocks_ref,
+          nullptr /* scalar_cache */));
       return fast_comparator_->compareStaticValueAndColumnVector(
           left_operand_->getStaticValue(),
           *right_values,
@@ -202,7 +203,8 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
     } else {
       ColumnVectorPtr right_values(right_operand_->getAllValues(
           accessor,
-          sub_blocks_ref));
+          sub_blocks_ref,
+          nullptr /* scalar_cache */));
       return fast_comparator_->compareStaticValueAndColumnVector(
           left_operand_->getStaticValue(),
           *right_values,
@@ -225,7 +227,8 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
     if (short_circuit_adapter) {
       ColumnVectorPtr left_values(left_operand_->getAllValues(
           short_circuit_adapter.get(),
-          sub_blocks_ref));
+          sub_blocks_ref,
+          nullptr /* scalar_cache */));
       return fast_comparator_->compareColumnVectorAndStaticValue(
           *left_values,
           right_operand_->getStaticValue(),
@@ -234,7 +237,8 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
     } else {
       ColumnVectorPtr left_values(left_operand_->getAllValues(
           accessor,
-          sub_blocks_ref));
+          sub_blocks_ref,
+          nullptr /* scalar_cache */));
       return fast_comparator_->compareColumnVectorAndStaticValue(
           *left_values,
           right_operand_->getStaticValue(),
@@ -258,7 +262,8 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
         if (short_circuit_adapter) {
           ColumnVectorPtr right_values(right_operand_->getAllValues(
               short_circuit_adapter.get(),
-              sub_blocks_ref));
+              sub_blocks_ref,
+              nullptr /* scalar_cache */));
           return fast_comparator_->compareValueAccessorAndColumnVector(
               short_circuit_adapter.get(),
               left_operand_attr_id,
@@ -268,7 +273,8 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
         } else {
           ColumnVectorPtr right_values(right_operand_->getAllValues(
               accessor,
-              sub_blocks_ref));
+              sub_blocks_ref,
+              nullptr /* scalar_cache */));
           return 
fast_comparator_->compareValueAccessorAndColumnVector(accessor,
                                                                        
left_operand_attr_id,
                                                                        
*right_values,
@@ -280,7 +286,8 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
       if (short_circuit_adapter) {
         ColumnVectorPtr left_values(left_operand_->getAllValues(
             short_circuit_adapter.get(),
-            sub_blocks_ref));
+            sub_blocks_ref,
+            nullptr /* scalar_cache */));
         return fast_comparator_->compareColumnVectorAndValueAccessor(
             *left_values,
             short_circuit_adapter.get(),
@@ -290,7 +297,8 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
       } else {
         ColumnVectorPtr left_values(left_operand_->getAllValues(
             accessor,
-            sub_blocks_ref));
+            sub_blocks_ref,
+            nullptr /* scalar_cache */));
         return 
fast_comparator_->compareColumnVectorAndValueAccessor(*left_values,
                                                                      accessor,
                                                                      
right_operand_attr_id,
@@ -303,10 +311,12 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
     if (short_circuit_adapter) {
       ColumnVectorPtr left_values(left_operand_->getAllValues(
           short_circuit_adapter.get(),
-          sub_blocks_ref));
+          sub_blocks_ref,
+          nullptr /* scalar_cache */));
       ColumnVectorPtr right_values(right_operand_->getAllValues(
           short_circuit_adapter.get(),
-          sub_blocks_ref));
+          sub_blocks_ref,
+          nullptr /* scalar_cache */));
       return fast_comparator_->compareColumnVectors(*left_values,
                                                     *right_values,
                                                     nullptr,
@@ -314,10 +324,12 @@ TupleIdSequence* ComparisonPredicate::getAllMatches(
     } else {
       ColumnVectorPtr left_values(left_operand_->getAllValues(
           accessor,
-          sub_blocks_ref));
+          sub_blocks_ref,
+          nullptr /* scalar_cache */));
       ColumnVectorPtr right_values(right_operand_->getAllValues(
           accessor,
-          sub_blocks_ref));
+          sub_blocks_ref,
+          nullptr /* scalar_cache */));
       return fast_comparator_->compareColumnVectors(*left_values,
                                                     *right_values,
                                                     filter,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/expressions/scalar/CMakeLists.txt 
b/expressions/scalar/CMakeLists.txt
index d16f22e..7a589d6 100644
--- a/expressions/scalar/CMakeLists.txt
+++ b/expressions/scalar/CMakeLists.txt
@@ -23,6 +23,7 @@ add_library(quickstep_expressions_scalar_ScalarAttribute
 add_library(quickstep_expressions_scalar_ScalarBinaryExpression
             ScalarBinaryExpression.cpp
             ScalarBinaryExpression.hpp)
+add_library(quickstep_expressions_scalar_ScalarCache ../../empty_src.cpp 
ScalarCache.hpp)
 add_library(quickstep_expressions_scalar_ScalarCaseExpression
             ScalarCaseExpression.cpp
             ScalarCaseExpression.hpp)
@@ -72,6 +73,8 @@ 
target_link_libraries(quickstep_expressions_scalar_ScalarBinaryExpression
                       
quickstep_types_operations_binaryoperations_BinaryOperation
                       
quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_expressions_scalar_ScalarCache
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_expressions_scalar_ScalarCaseExpression
                       quickstep_catalog_CatalogTypedefs
                       quickstep_expressions_Expressions_proto

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/Scalar.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/Scalar.hpp b/expressions/scalar/Scalar.hpp
index 42961c1..995fd67 100644
--- a/expressions/scalar/Scalar.hpp
+++ b/expressions/scalar/Scalar.hpp
@@ -34,6 +34,7 @@
 
 namespace quickstep {
 
+class ScalarCache;
 class Type;
 class ValueAccessor;
 
@@ -208,7 +209,8 @@ class Scalar : public Expression {
    *         via accessor.
    **/
   virtual ColumnVectorPtr getAllValues(ValueAccessor *accessor,
-                                       const SubBlocksReference 
*sub_blocks_ref) const = 0;
+                                       const SubBlocksReference 
*sub_blocks_ref,
+                                       ScalarCache *scalar_cache) const = 0;
 
   /**
    * @brief Get this Scalar's value for all specified joined tuples from two
@@ -230,7 +232,8 @@ class Scalar : public Expression {
       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 = 0;
+      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+      ScalarCache *scalar_cache) const = 0;
 
  protected:
   void getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarAttribute.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarAttribute.cpp 
b/expressions/scalar/ScalarAttribute.cpp
index fe67a94..8f063e6 100644
--- a/expressions/scalar/ScalarAttribute.cpp
+++ b/expressions/scalar/ScalarAttribute.cpp
@@ -91,7 +91,8 @@ relation_id ScalarAttribute::getRelationIdForValueAccessor() 
const {
 
 ColumnVectorPtr ScalarAttribute::getAllValues(
     ValueAccessor *accessor,
-    const SubBlocksReference *sub_blocks_ref) const {
+    const SubBlocksReference *sub_blocks_ref,
+    ScalarCache *scalar_cache) const {
   const attribute_id attr_id = attribute_.getID();
   const Type &result_type = attribute_.getType();
   return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
@@ -159,7 +160,8 @@ ColumnVectorPtr ScalarAttribute::getAllValuesForJoin(
     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 {
+    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+    ScalarCache *scalar_cache) const {
   DCHECK((attribute_.getParent().getID() == left_relation_id)
          || (attribute_.getParent().getID() == right_relation_id));
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarAttribute.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarAttribute.hpp 
b/expressions/scalar/ScalarAttribute.hpp
index 2aa2445..1bf8dab 100644
--- a/expressions/scalar/ScalarAttribute.hpp
+++ b/expressions/scalar/ScalarAttribute.hpp
@@ -35,6 +35,7 @@
 namespace quickstep {
 
 class CatalogAttribute;
+class ScalarCache;
 class ValueAccessor;
 
 struct SubBlocksReference;
@@ -79,14 +80,16 @@ class ScalarAttribute : public Scalar {
   relation_id getRelationIdForValueAccessor() const override;
 
   ColumnVectorPtr getAllValues(ValueAccessor *accessor,
-                               const SubBlocksReference *sub_blocks_ref) const 
override;
+                               const SubBlocksReference *sub_blocks_ref,
+                               ScalarCache *scalar_cache) const override;
 
   ColumnVectorPtr 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;
+      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+      ScalarCache *scalar_cache) const override;
 
   const CatalogAttribute& getAttribute() const {
     return attribute_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarBinaryExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarBinaryExpression.cpp 
b/expressions/scalar/ScalarBinaryExpression.cpp
index db34154..3da6083 100644
--- a/expressions/scalar/ScalarBinaryExpression.cpp
+++ b/expressions/scalar/ScalarBinaryExpression.cpp
@@ -104,7 +104,8 @@ TypedValue ScalarBinaryExpression::getValueForJoinedTuples(
 
 ColumnVectorPtr ScalarBinaryExpression::getAllValues(
     ValueAccessor *accessor,
-    const SubBlocksReference *sub_blocks_ref) const {
+    const SubBlocksReference *sub_blocks_ref,
+    ScalarCache *scalar_cache) const {
   if (fast_operator_.get() == nullptr) {
     return ColumnVectorPtr(
         ColumnVector::MakeVectorOfValue(getType(),
@@ -128,7 +129,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValues(
 #endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
 
       ColumnVectorPtr right_result(
-          right_operand_->getAllValues(accessor, sub_blocks_ref));
+          right_operand_->getAllValues(accessor, sub_blocks_ref, 
scalar_cache));
       return ColumnVectorPtr(
           fast_operator_->applyToStaticValueAndColumnVector(
               left_operand_->getStaticValue(),
@@ -147,7 +148,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValues(
 #endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
 
       ColumnVectorPtr left_result(
-          left_operand_->getAllValues(accessor, sub_blocks_ref));
+          left_operand_->getAllValues(accessor, sub_blocks_ref, scalar_cache));
       return ColumnVectorPtr(
           fast_operator_->applyToColumnVectorAndStaticValue(
               *left_result,
@@ -168,7 +169,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValues(
                   right_operand_attr_id));
         } else {
           ColumnVectorPtr right_result(
-              right_operand_->getAllValues(accessor, sub_blocks_ref));
+              right_operand_->getAllValues(accessor, sub_blocks_ref, 
scalar_cache));
           return ColumnVectorPtr(
               fast_operator_->applyToValueAccessorAndColumnVector(
                   accessor,
@@ -177,7 +178,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValues(
         }
       } else if (right_operand_attr_id != -1) {
         ColumnVectorPtr left_result(
-            left_operand_->getAllValues(accessor, sub_blocks_ref));
+            left_operand_->getAllValues(accessor, sub_blocks_ref, 
scalar_cache));
         return ColumnVectorPtr(
             fast_operator_->applyToColumnVectorAndValueAccessor(
                 *left_result,
@@ -187,9 +188,9 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValues(
 #endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
 
       ColumnVectorPtr left_result(
-          left_operand_->getAllValues(accessor, sub_blocks_ref));
+          left_operand_->getAllValues(accessor, sub_blocks_ref, scalar_cache));
       ColumnVectorPtr right_result(
-          right_operand_->getAllValues(accessor, sub_blocks_ref));
+          right_operand_->getAllValues(accessor, sub_blocks_ref, 
scalar_cache));
       return ColumnVectorPtr(
           fast_operator_->applyToColumnVectors(*left_result, *right_result));
     }
@@ -201,7 +202,8 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin(
     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 {
+    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+    ScalarCache *scalar_cache) const {
   if (fast_operator_.get() == nullptr) {
     return ColumnVectorPtr(
         ColumnVector::MakeVectorOfValue(getType(),
@@ -236,7 +238,8 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin(
                                               left_accessor,
                                               right_relation_id,
                                               right_accessor,
-                                              joined_tuple_ids));
+                                              joined_tuple_ids,
+                                              scalar_cache));
       return ColumnVectorPtr(
           fast_operator_->applyToStaticValueAndColumnVector(
               left_operand_->getStaticValue(),
@@ -269,7 +272,8 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin(
                                              left_accessor,
                                              right_relation_id,
                                              right_accessor,
-                                             joined_tuple_ids));
+                                             joined_tuple_ids,
+                                             scalar_cache));
       return ColumnVectorPtr(
           fast_operator_->applyToColumnVectorAndStaticValue(
               *left_result,
@@ -358,13 +362,15 @@ ColumnVectorPtr 
ScalarBinaryExpression::getAllValuesForJoin(
                                              left_accessor,
                                              right_relation_id,
                                              right_accessor,
-                                             joined_tuple_ids));
+                                             joined_tuple_ids,
+                                             scalar_cache));
       ColumnVectorPtr right_result(
           right_operand_->getAllValuesForJoin(left_relation_id,
                                               left_accessor,
                                               right_relation_id,
                                               right_accessor,
-                                              joined_tuple_ids));
+                                              joined_tuple_ids,
+                                              scalar_cache));
       return ColumnVectorPtr(
           fast_operator_->applyToColumnVectors(*left_result, *right_result));
     }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarBinaryExpression.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarBinaryExpression.hpp 
b/expressions/scalar/ScalarBinaryExpression.hpp
index 7816e61..76f9dbc 100644
--- a/expressions/scalar/ScalarBinaryExpression.hpp
+++ b/expressions/scalar/ScalarBinaryExpression.hpp
@@ -38,6 +38,7 @@
 
 namespace quickstep {
 
+class ScalarCache;
 class ValueAccessor;
 
 struct SubBlocksReference;
@@ -99,14 +100,16 @@ class ScalarBinaryExpression : public Scalar {
   }
 
   ColumnVectorPtr getAllValues(ValueAccessor *accessor,
-                               const SubBlocksReference *sub_blocks_ref) const 
override;
+                               const SubBlocksReference *sub_blocks_ref,
+                               ScalarCache *scalar_cache) const override;
 
   ColumnVectorPtr 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;
+      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+      ScalarCache *scalar_cache) const override;
 
  protected:
   void getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarCache.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarCache.hpp 
b/expressions/scalar/ScalarCache.hpp
new file mode 100644
index 0000000..1d51362
--- /dev/null
+++ b/expressions/scalar/ScalarCache.hpp
@@ -0,0 +1,64 @@
+/**
+ * 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_CACHE_HPP_
+#define QUICKSTEP_EXPRESSIONS_SCALAR_SCALAR_CACHE_HPP_
+
+#include <unordered_map>
+
+#include "types/containers/ColumnVector.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Expressions
+ *  @{
+ */
+
+class ScalarCache {
+ public:
+  ScalarCache() {}
+
+  inline bool has(const int share_id) const {
+    return cv_cache_.find(share_id) != cv_cache_.end();
+  }
+
+  inline ColumnVectorPtr get(const int share_id) const {
+    DCHECK(has(share_id));
+    return cv_cache_.at(share_id);
+  }
+
+  inline void set(const int share_id, const ColumnVectorPtr &cv) {
+    DCHECK(!has(share_id));
+    cv_cache_.emplace(share_id, cv);
+  }
+
+ private:
+  std::unordered_map<int, ColumnVectorPtr> cv_cache_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScalarCache);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_EXPRESSIONS_SCALAR_SCALAR_CACHE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarCaseExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarCaseExpression.cpp 
b/expressions/scalar/ScalarCaseExpression.cpp
index 80c4711..7e7a2c8 100644
--- a/expressions/scalar/ScalarCaseExpression.cpp
+++ b/expressions/scalar/ScalarCaseExpression.cpp
@@ -195,7 +195,8 @@ TypedValue ScalarCaseExpression::getValueForJoinedTuples(
 
 ColumnVectorPtr ScalarCaseExpression::getAllValues(
     ValueAccessor *accessor,
-    const SubBlocksReference *sub_blocks_ref) const {
+    const SubBlocksReference *sub_blocks_ref,
+    ScalarCache *scalar_cache) const {
   return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
       accessor,
       [&](auto *accessor) -> ColumnVectorPtr {  // NOLINT(build/c++11)
@@ -205,7 +206,8 @@ ColumnVectorPtr ScalarCaseExpression::getAllValues(
                                           static_value_,
                                           accessor->getNumTuples()));
     } else if (fixed_result_expression_ != nullptr) {
-      return fixed_result_expression_->getAllValues(accessor, sub_blocks_ref);
+      return fixed_result_expression_->getAllValues(
+          accessor, sub_blocks_ref, scalar_cache);
     }
 
     const TupleIdSequence *accessor_sequence = accessor->getTupleIdSequence();
@@ -246,14 +248,16 @@ ColumnVectorPtr ScalarCaseExpression::getAllValues(
       std::unique_ptr<ValueAccessor> case_accessor(
           
accessor->createSharedTupleIdSequenceAdapter(*case_matches[case_idx]));
       case_results.emplace_back(
-          result_expressions_[case_idx]->getAllValues(case_accessor.get(), 
sub_blocks_ref));
+          result_expressions_[case_idx]->getAllValues(
+              case_accessor.get(), sub_blocks_ref, scalar_cache));
     }
 
     ColumnVectorPtr else_results;
     if (!else_matches->empty()) {
       std::unique_ptr<ValueAccessor> else_accessor(
           accessor->createSharedTupleIdSequenceAdapter(*else_matches));
-      else_results = 
else_result_expression_->getAllValues(else_accessor.get(), sub_blocks_ref);
+      else_results = else_result_expression_->getAllValues(
+          else_accessor.get(), sub_blocks_ref, scalar_cache);
     }
 
     // Multiplex per-case results into a single ColumnVector with values in the
@@ -273,7 +277,8 @@ ColumnVectorPtr ScalarCaseExpression::getAllValuesForJoin(
     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 {
+    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+    ScalarCache *scalar_cache) const {
   // Slice 'joined_tuple_ids' apart by case.
   //
   // NOTE(chasseur): We use TupleIdSequence to keep track of the positions in
@@ -331,7 +336,8 @@ ColumnVectorPtr ScalarCaseExpression::getAllValuesForJoin(
         left_accessor,
         right_relation_id,
         right_accessor,
-        case_matches[case_idx]));
+        case_matches[case_idx],
+        scalar_cache));
   }
 
   ColumnVectorPtr else_results;
@@ -346,7 +352,8 @@ ColumnVectorPtr ScalarCaseExpression::getAllValuesForJoin(
         left_accessor,
         right_relation_id,
         right_accessor,
-        else_matches);
+        else_matches,
+        scalar_cache);
   }
 
   // Multiplex per-case results into a single ColumnVector with values in the

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarCaseExpression.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarCaseExpression.hpp 
b/expressions/scalar/ScalarCaseExpression.hpp
index f6deb8e..f9062b1 100644
--- a/expressions/scalar/ScalarCaseExpression.hpp
+++ b/expressions/scalar/ScalarCaseExpression.hpp
@@ -132,14 +132,16 @@ class ScalarCaseExpression : public Scalar {
   }
 
   ColumnVectorPtr getAllValues(ValueAccessor *accessor,
-                               const SubBlocksReference *sub_blocks_ref) const 
override;
+                               const SubBlocksReference *sub_blocks_ref,
+                               ScalarCache *scalar_cache) const override;
 
   ColumnVectorPtr 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;
+      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+      ScalarCache *scalar_cache) const override;
 
  protected:
   void getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarLiteral.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarLiteral.cpp 
b/expressions/scalar/ScalarLiteral.cpp
index 6e0baf2..5cb7776 100644
--- a/expressions/scalar/ScalarLiteral.cpp
+++ b/expressions/scalar/ScalarLiteral.cpp
@@ -49,7 +49,8 @@ Scalar* ScalarLiteral::clone() const {
 
 ColumnVectorPtr ScalarLiteral::getAllValues(
     ValueAccessor *accessor,
-    const SubBlocksReference *sub_blocks_ref) const {
+    const SubBlocksReference *sub_blocks_ref,
+    ScalarCache *scalar_cache) const {
   return ColumnVectorPtr(
       ColumnVector::MakeVectorOfValue(type_,
                                       internal_literal_,
@@ -61,7 +62,8 @@ ColumnVectorPtr ScalarLiteral::getAllValuesForJoin(
     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 {
+    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+    ScalarCache *scalar_cache) const {
   return ColumnVectorPtr(
       ColumnVector::MakeVectorOfValue(type_,
                                       internal_literal_,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarLiteral.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarLiteral.hpp 
b/expressions/scalar/ScalarLiteral.hpp
index 11e509a..e81aaf8 100644
--- a/expressions/scalar/ScalarLiteral.hpp
+++ b/expressions/scalar/ScalarLiteral.hpp
@@ -34,6 +34,7 @@
 
 namespace quickstep {
 
+class ScalarCache;
 class Type;
 class ValueAccessor;
 
@@ -103,14 +104,16 @@ class ScalarLiteral : public Scalar {
   }
 
   ColumnVectorPtr getAllValues(ValueAccessor *accessor,
-                               const SubBlocksReference *sub_blocks_ref) const 
override;
+                               const SubBlocksReference *sub_blocks_ref,
+                               ScalarCache *scalar_cache) const override;
 
   ColumnVectorPtr 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;
+      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+      ScalarCache *scalar_cache) const override;
 
  protected:
   void getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarSharedExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarSharedExpression.cpp 
b/expressions/scalar/ScalarSharedExpression.cpp
index b510bfa..8dbb3bb 100644
--- a/expressions/scalar/ScalarSharedExpression.cpp
+++ b/expressions/scalar/ScalarSharedExpression.cpp
@@ -25,6 +25,7 @@
 
 #include "catalog/CatalogTypedefs.hpp"
 #include "expressions/Expressions.pb.h"
+#include "expressions/scalar/ScalarCache.hpp"
 #include "storage/ValueAccessor.hpp"
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVector.hpp"
@@ -76,8 +77,20 @@ TypedValue ScalarSharedExpression::getValueForJoinedTuples(
 
 ColumnVectorPtr ScalarSharedExpression::getAllValues(
     ValueAccessor *accessor,
-    const SubBlocksReference *sub_blocks_ref) const {
-  return operand_->getAllValues(accessor, sub_blocks_ref);
+    const SubBlocksReference *sub_blocks_ref,
+    ScalarCache *scalar_cache) const {
+  if (scalar_cache == nullptr) {
+    return operand_->getAllValues(accessor, sub_blocks_ref, scalar_cache);
+  } else {
+    ColumnVectorPtr result;
+    if (scalar_cache->has(share_id_)) {
+      result = scalar_cache->get(share_id_);
+    } else {
+      result = operand_->getAllValues(accessor, sub_blocks_ref, scalar_cache);
+      scalar_cache->set(share_id_, result);
+    }
+    return result;
+  }
 }
 
 ColumnVectorPtr ScalarSharedExpression::getAllValuesForJoin(
@@ -85,12 +98,30 @@ ColumnVectorPtr ScalarSharedExpression::getAllValuesForJoin(
     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 operand_->getAllValuesForJoin(left_relation_id,
-                                       left_accessor,
-                                       right_relation_id,
-                                       right_accessor,
-                                       joined_tuple_ids);
+    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+    ScalarCache *scalar_cache) const {
+  if (scalar_cache == nullptr) {
+    return operand_->getAllValuesForJoin(left_relation_id,
+                                         left_accessor,
+                                         right_relation_id,
+                                         right_accessor,
+                                         joined_tuple_ids,
+                                         scalar_cache);
+  } else {
+    ColumnVectorPtr result;
+    if (scalar_cache->has(share_id_)) {
+      result = scalar_cache->get(share_id_);
+    } else {
+      result = operand_->getAllValuesForJoin(left_relation_id,
+                                             left_accessor,
+                                             right_relation_id,
+                                             right_accessor,
+                                             joined_tuple_ids,
+                                             scalar_cache);
+      scalar_cache->set(share_id_, result);
+    }
+    return result;
+  }
 }
 
 void ScalarSharedExpression::getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarSharedExpression.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarSharedExpression.hpp 
b/expressions/scalar/ScalarSharedExpression.hpp
index a741bd4..3262ef1 100644
--- a/expressions/scalar/ScalarSharedExpression.hpp
+++ b/expressions/scalar/ScalarSharedExpression.hpp
@@ -35,6 +35,7 @@
 
 namespace quickstep {
 
+class ScalarCache;
 class ValueAccessor;
 
 struct SubBlocksReference;
@@ -84,14 +85,16 @@ class ScalarSharedExpression : public Scalar {
   }
 
   ColumnVectorPtr getAllValues(ValueAccessor *accessor,
-                               const SubBlocksReference *sub_blocks_ref) const 
override;
+                               const SubBlocksReference *sub_blocks_ref,
+                               ScalarCache *scalar_cache) const override;
 
   ColumnVectorPtr 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;
+      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+      ScalarCache *scalar_cache) const override;
 
  protected:
   void getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarUnaryExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarUnaryExpression.cpp 
b/expressions/scalar/ScalarUnaryExpression.cpp
index 5b0164f..80d4944 100644
--- a/expressions/scalar/ScalarUnaryExpression.cpp
+++ b/expressions/scalar/ScalarUnaryExpression.cpp
@@ -94,7 +94,8 @@ TypedValue ScalarUnaryExpression::getValueForJoinedTuples(
 
 ColumnVectorPtr ScalarUnaryExpression::getAllValues(
     ValueAccessor *accessor,
-    const SubBlocksReference *sub_blocks_ref) const {
+    const SubBlocksReference *sub_blocks_ref,
+    ScalarCache *scalar_cache) const {
   if (fast_operator_.get() == nullptr) {
     return ColumnVectorPtr(
         ColumnVector::MakeVectorOfValue(getType(),
@@ -109,7 +110,8 @@ ColumnVectorPtr ScalarUnaryExpression::getAllValues(
     }
 #endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
 
-    ColumnVectorPtr operand_result(operand_->getAllValues(accessor, 
sub_blocks_ref));
+    ColumnVectorPtr operand_result(
+        operand_->getAllValues(accessor, sub_blocks_ref, scalar_cache));
     return ColumnVectorPtr(
         fast_operator_->applyToColumnVector(*operand_result));
   }
@@ -120,7 +122,8 @@ ColumnVectorPtr ScalarUnaryExpression::getAllValuesForJoin(
     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 {
+    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+    ScalarCache *scalar_cache) const {
   if (fast_operator_.get() == nullptr) {
     return ColumnVectorPtr(
         ColumnVector::MakeVectorOfValue(getType(),
@@ -150,7 +153,8 @@ ColumnVectorPtr ScalarUnaryExpression::getAllValuesForJoin(
                                       left_accessor,
                                       right_relation_id,
                                       right_accessor,
-                                      joined_tuple_ids));
+                                      joined_tuple_ids,
+                                      scalar_cache));
     return ColumnVectorPtr(
         fast_operator_->applyToColumnVector(*operand_result));
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/expressions/scalar/ScalarUnaryExpression.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarUnaryExpression.hpp 
b/expressions/scalar/ScalarUnaryExpression.hpp
index 31c5244..efba14e 100644
--- a/expressions/scalar/ScalarUnaryExpression.hpp
+++ b/expressions/scalar/ScalarUnaryExpression.hpp
@@ -38,6 +38,7 @@
 
 namespace quickstep {
 
+class ScalarCache;
 class ValueAccessor;
 
 struct SubBlocksReference;
@@ -95,14 +96,16 @@ class ScalarUnaryExpression : public Scalar {
   }
 
   ColumnVectorPtr getAllValues(ValueAccessor *accessor,
-                               const SubBlocksReference *sub_blocks_ref) const 
override;
+                               const SubBlocksReference *sub_blocks_ref,
+                               ScalarCache *scalar_cache) const override;
 
   ColumnVectorPtr 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;
+      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
+      ScalarCache *scalar_cache) const override;
 
  protected:
   void getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/relational_operators/HashJoinOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/HashJoinOperator.cpp 
b/relational_operators/HashJoinOperator.cpp
index 0e75411..cd376c1 100644
--- a/relational_operators/HashJoinOperator.cpp
+++ b/relational_operators/HashJoinOperator.cpp
@@ -32,6 +32,7 @@
 #include "expressions/predicate/Predicate.hpp"
 #include "expressions/scalar/Scalar.hpp"
 #include "expressions/scalar/ScalarAttribute.hpp"
+#include "expressions/scalar/ScalarCache.hpp"
 #include "query_execution/QueryContext.hpp"
 #include "query_execution/WorkOrderProtosContainer.hpp"
 #include "query_execution/WorkOrdersContainer.hpp"
@@ -532,6 +533,7 @@ void 
HashInnerJoinWorkOrder::executeWithoutCopyElision(ValueAccessor *probe_acce
     }
 
     ColumnVectorsValueAccessor temp_result;
+    std::unique_ptr<ScalarCache> scalar_cache = 
std::make_unique<ScalarCache>();
     for (auto selection_cit = selection_.begin();
          selection_cit != selection_.end();
          ++selection_cit) {
@@ -539,8 +541,10 @@ void 
HashInnerJoinWorkOrder::executeWithoutCopyElision(ValueAccessor *probe_acce
                                                                   
build_accessor.get(),
                                                                   
probe_relation_id,
                                                                   
probe_accessor,
-                                                                  
build_block_entry.second));
+                                                                  
build_block_entry.second,
+                                                                  
scalar_cache.get()));
     }
+    scalar_cache.reset();
 
     output_destination_->bulkInsertTuples(&temp_result);
   }
@@ -649,12 +653,14 @@ void 
HashInnerJoinWorkOrder::executeWithCopyElision(ValueAccessor *probe_accesso
         zipped_joined_tuple_ids.emplace_back(build_tids[i], probe_tids[i]);
       }
 
+      ScalarCache scalar_cache;
       for (const Scalar *scalar : non_trivial_expressions) {
         temp_result.addColumn(scalar->getAllValuesForJoin(build_relation_id,
                                                           build_accessor.get(),
                                                           probe_relation_id,
                                                           probe_accessor,
-                                                          
zipped_joined_tuple_ids));
+                                                          
zipped_joined_tuple_ids,
+                                                          &scalar_cache));
       }
     }
 
@@ -765,13 +771,16 @@ void 
HashSemiJoinWorkOrder::executeWithResidualPredicate() {
 
   std::unique_ptr<ValueAccessor> probe_accessor_with_filter(
       probe_store.createValueAccessor(&filter));
+
   ColumnVectorsValueAccessor temp_result;
+  std::unique_ptr<ScalarCache> scalar_cache = std::make_unique<ScalarCache>();
   for (vector<unique_ptr<const Scalar>>::const_iterator selection_it = 
selection_.begin();
        selection_it != selection_.end();
        ++selection_it) {
     temp_result.addColumn((*selection_it)->getAllValues(
-        probe_accessor_with_filter.get(), &sub_blocks_ref));
+        probe_accessor_with_filter.get(), &sub_blocks_ref, 
scalar_cache.get()));
   }
+  scalar_cache.reset();
 
   output_destination_->bulkInsertTuples(&temp_result);
 }
@@ -828,12 +837,15 @@ void 
HashSemiJoinWorkOrder::executeWithoutResidualPredicate() {
 
   std::unique_ptr<ValueAccessor> probe_accessor_with_filter(
       
probe_accessor->createSharedTupleIdSequenceAdapterVirtual(*existence_map));
+
   ColumnVectorsValueAccessor temp_result;
+  std::unique_ptr<ScalarCache> scalar_cache = std::make_unique<ScalarCache>();
   for (vector<unique_ptr<const Scalar>>::const_iterator selection_it = 
selection_.begin();
        selection_it != selection_.end(); ++selection_it) {
     temp_result.addColumn((*selection_it)->getAllValues(
-        probe_accessor_with_filter.get(), &sub_blocks_ref));
+        probe_accessor_with_filter.get(), &sub_blocks_ref, 
scalar_cache.get()));
   }
+  scalar_cache.reset();
 
   output_destination_->bulkInsertTuples(&temp_result);
 }
@@ -886,12 +898,15 @@ void 
HashAntiJoinWorkOrder::executeWithoutResidualPredicate() {
 
   std::unique_ptr<ValueAccessor> probe_accessor_with_filter(
       
probe_accessor->createSharedTupleIdSequenceAdapterVirtual(*existence_map));
+
   ColumnVectorsValueAccessor temp_result;
+  std::unique_ptr<ScalarCache> scalar_cache = std::make_unique<ScalarCache>();
   for (vector<unique_ptr<const Scalar>>::const_iterator selection_it = 
selection_.begin();
        selection_it != selection_.end(); ++selection_it) {
     temp_result.addColumn((*selection_it)->getAllValues(
-        probe_accessor_with_filter.get(), &sub_blocks_ref));
+        probe_accessor_with_filter.get(), &sub_blocks_ref, 
scalar_cache.get()));
   }
+  scalar_cache.reset();
 
   output_destination_->bulkInsertTuples(&temp_result);
 }
@@ -976,14 +991,18 @@ void 
HashAntiJoinWorkOrder::executeWithResidualPredicate() {
 
   std::unique_ptr<ValueAccessor> probe_accessor_with_filter(
       
probe_accessor->createSharedTupleIdSequenceAdapterVirtual(*existence_map));
+
   ColumnVectorsValueAccessor temp_result;
+  std::unique_ptr<ScalarCache> scalar_cache = std::make_unique<ScalarCache>();
   for (vector<unique_ptr<const Scalar>>::const_iterator selection_it = 
selection_.begin();
        selection_it != selection_.end();
        ++selection_it) {
     temp_result.addColumn(
         (*selection_it)->getAllValues(probe_accessor_with_filter.get(),
-                                      &sub_blocks_ref));
+                                      &sub_blocks_ref,
+                                      scalar_cache.get()));
   }
+  scalar_cache.reset();
 
   output_destination_->bulkInsertTuples(&temp_result);
 }
@@ -1032,12 +1051,11 @@ void HashOuterJoinWorkOrder::execute() {
            &build_block_entry : *collector.getJoinedTupleMap()) {
     const BlockReference build_block =
         storage_manager_->getBlock(build_block_entry.first, build_relation_);
-    const TupleStorageSubBlock &build_store =
-        build_block->getTupleStorageSubBlock();
+    const TupleStorageSubBlock &build_store = 
build_block->getTupleStorageSubBlock();
+    std::unique_ptr<ValueAccessor> 
build_accessor(build_store.createValueAccessor());
 
-    std::unique_ptr<ValueAccessor> build_accessor(
-        build_store.createValueAccessor());
     ColumnVectorsValueAccessor temp_result;
+    std::unique_ptr<ScalarCache> scalar_cache = 
std::make_unique<ScalarCache>();
     for (auto selection_it = selection_.begin();
          selection_it != selection_.end();
          ++selection_it) {
@@ -1047,8 +1065,11 @@ void HashOuterJoinWorkOrder::execute() {
               build_accessor.get(),
               probe_relation_id,
               probe_accessor.get(),
-              build_block_entry.second));
+              build_block_entry.second,
+              scalar_cache.get()));
     }
+    scalar_cache.reset();
+
     output_destination_->bulkInsertTuples(&temp_result);
   }
 
@@ -1061,8 +1082,9 @@ void HashOuterJoinWorkOrder::execute() {
   if (num_tuples_without_matches > 0) {
     std::unique_ptr<ValueAccessor> probe_accessor_with_filter(
         
probe_accessor->createSharedTupleIdSequenceAdapterVirtual(*existence_map));
-    ColumnVectorsValueAccessor temp_result;
 
+    ColumnVectorsValueAccessor temp_result;
+    std::unique_ptr<ScalarCache> scalar_cache = 
std::make_unique<ScalarCache>();
     for (std::size_t i = 0; i < selection_.size(); ++i) {
       if (is_selection_on_build_[i]) {
         // NOTE(harshad, jianqiao): The assumption here is that any operation
@@ -1090,9 +1112,12 @@ void HashOuterJoinWorkOrder::execute() {
       } else {
         temp_result.addColumn(
             selection_[i]->getAllValues(probe_accessor_with_filter.get(),
-                                        &sub_blocks_ref));
+                                        &sub_blocks_ref,
+                                        scalar_cache.get()));
       }
     }
+    scalar_cache.reset();
+
     output_destination_->bulkInsertTuples(&temp_result);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/relational_operators/NestedLoopsJoinOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/NestedLoopsJoinOperator.cpp 
b/relational_operators/NestedLoopsJoinOperator.cpp
index f17402f..a6bacc7 100644
--- a/relational_operators/NestedLoopsJoinOperator.cpp
+++ b/relational_operators/NestedLoopsJoinOperator.cpp
@@ -27,6 +27,7 @@
 #include "catalog/CatalogRelationSchema.hpp"
 #include "expressions/predicate/Predicate.hpp"
 #include "expressions/scalar/Scalar.hpp"
+#include "expressions/scalar/ScalarCache.hpp"
 #include "query_execution/QueryContext.hpp"
 #include "query_execution/WorkOrderProtosContainer.hpp"
 #include "query_execution/WorkOrdersContainer.hpp"
@@ -417,6 +418,7 @@ void NestedLoopsJoinWorkOrder::executeHelper(const 
TupleStorageSubBlock &left_st
     // evaluation and data movement, but low enough that temporary memory
     // requirements don't get out of hand).
     ColumnVectorsValueAccessor temp_result;
+    std::unique_ptr<ScalarCache> scalar_cache = 
std::make_unique<ScalarCache>();
     for (vector<unique_ptr<const Scalar>>::const_iterator selection_cit = 
selection_.begin();
          selection_cit != selection_.end();
          ++selection_cit) {
@@ -424,8 +426,10 @@ void NestedLoopsJoinWorkOrder::executeHelper(const 
TupleStorageSubBlock &left_st
                                                                   
left_accessor.get(),
                                                                   
right_input_relation_id,
                                                                   
right_accessor.get(),
-                                                                  
joined_tuple_ids));
+                                                                  
joined_tuple_ids,
+                                                                  
scalar_cache.get()));
     }
+    scalar_cache.reset();
 
     output_destination_->bulkInsertTuples(&temp_result);
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/storage/AggregationOperationState.cpp
----------------------------------------------------------------------
diff --git a/storage/AggregationOperationState.cpp 
b/storage/AggregationOperationState.cpp
index 90543c4..facc7fa 100644
--- a/storage/AggregationOperationState.cpp
+++ b/storage/AggregationOperationState.cpp
@@ -38,6 +38,7 @@
 #include "expressions/aggregation/AggregationHandle.hpp"
 #include "expressions/predicate/Predicate.hpp"
 #include "expressions/scalar/Scalar.hpp"
+#include "expressions/scalar/ScalarCache.hpp"
 #include "storage/AggregationOperationState.pb.h"
 #include "storage/CollisionFreeVectorTable.hpp"
 #include "storage/HashTableFactory.hpp"
@@ -491,9 +492,10 @@ void AggregationOperationState::aggregateBlock(const 
block_id input_block,
     SubBlocksReference sub_blocks_ref(tuple_store,
                                       block->getIndices(),
                                       block->getIndicesConsistent());
+    ScalarCache scalar_cache;
     for (const auto &expression : non_trivial_expressions_) {
       non_trivial_results->addColumn(
-          expression->getAllValues(accessor, &sub_blocks_ref));
+          expression->getAllValues(accessor, &sub_blocks_ref, &scalar_cache));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/storage/StorageBlock.cpp
----------------------------------------------------------------------
diff --git a/storage/StorageBlock.cpp b/storage/StorageBlock.cpp
index e91c1ac..d724317 100644
--- a/storage/StorageBlock.cpp
+++ b/storage/StorageBlock.cpp
@@ -30,6 +30,7 @@
 #include "catalog/CatalogTypedefs.hpp"
 #include "expressions/predicate/Predicate.hpp"
 #include "expressions/scalar/Scalar.hpp"
+#include "expressions/scalar/ScalarCache.hpp"
 #include "storage/BasicColumnStoreTupleStorageSubBlock.hpp"
 #include "storage/BloomFilterIndexSubBlock.hpp"
 #include "storage/CSBTreeIndexSubBlock.hpp"
@@ -369,15 +370,18 @@ void StorageBlock::select(const vector<unique_ptr<const 
Scalar>> &selection,
                                       indices_,
                                       indices_consistent_);
 
-    std::unique_ptr<ValueAccessor> accessor(
-        tuple_store_->createValueAccessor(filter));
+    std::unique_ptr<ValueAccessor> 
accessor(tuple_store_->createValueAccessor(filter));
+    ScalarCache scalar_cache;
 
     for (vector<unique_ptr<const Scalar>>::const_iterator selection_cit = 
selection.begin();
          selection_cit != selection.end();
          ++selection_cit) {
       // TODO(chasseur): Can probably elide some copies for parts of the
       // selection that are ScalarAttribute or ScalarLiteral.
-      temp_result.addColumn((*selection_cit)->getAllValues(accessor.get(), 
&sub_blocks_ref));
+      temp_result.addColumn(
+          (*selection_cit)->getAllValues(accessor.get(),
+                                         &sub_blocks_ref,
+                                         &scalar_cache));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/449b5e81/storage/WindowAggregationOperationState.cpp
----------------------------------------------------------------------
diff --git a/storage/WindowAggregationOperationState.cpp 
b/storage/WindowAggregationOperationState.cpp
index 58bdf18..2c571ef 100644
--- a/storage/WindowAggregationOperationState.cpp
+++ b/storage/WindowAggregationOperationState.cpp
@@ -33,6 +33,7 @@
 #include "expressions/Expressions.pb.h"
 #include "expressions/scalar/Scalar.hpp"
 #include "expressions/scalar/ScalarAttribute.hpp"
+#include "expressions/scalar/ScalarCache.hpp"
 #include "expressions/window_aggregation/WindowAggregateFunction.hpp"
 #include "expressions/window_aggregation/WindowAggregateFunctionFactory.hpp"
 #include "expressions/window_aggregation/WindowAggregationHandle.hpp"
@@ -236,11 +237,16 @@ void 
WindowAggregationOperationState::windowAggregateBlocks(
       argument_accessor = new ColumnVectorsValueAccessor();
     }
 
+    std::unique_ptr<ScalarCache> scalar_cache = 
std::make_unique<ScalarCache>();
     for (const std::unique_ptr<const Scalar> &argument : arguments_) {
       argument_accessor->addColumn(argument->getAllValues(tuple_accessor,
-                                                          &sub_block_ref));
+                                                          &sub_block_ref,
+                                                          scalar_cache.get()));
     }
 
+    // Release common subexpression cache as early as possible.
+    scalar_cache.reset();
+
     InvokeOnAnyValueAccessor(tuple_accessor,
                              [&] (auto *tuple_accessor) -> void {  // 
NOLINT(build/c++11)
       tuple_accessor->beginIteration();

Reply via email to