QUICKSTEP-121: Added the self-join support.
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/8b7c3801 Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/8b7c3801 Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/8b7c3801 Branch: refs/heads/master Commit: 8b7c38010e1505ef03e0b6de8c6ac16cceb04695 Parents: 42588d4 Author: Zuyu Zhang <z...@cs.wisc.edu> Authored: Tue May 1 00:48:34 2018 -0500 Committer: Zuyu Zhang <z...@cs.wisc.edu> Committed: Wed May 9 16:34:47 2018 -0500 ---------------------------------------------------------------------- expressions/ExpressionFactories.cpp | 17 +++- expressions/Expressions.proto | 7 ++ expressions/predicate/ComparisonPredicate.cpp | 26 +++--- expressions/predicate/ComparisonPredicate.hpp | 2 - expressions/predicate/ConjunctionPredicate.cpp | 4 - expressions/predicate/ConjunctionPredicate.hpp | 2 - expressions/predicate/DisjunctionPredicate.cpp | 4 - expressions/predicate/DisjunctionPredicate.hpp | 2 - expressions/predicate/NegationPredicate.cpp | 4 - expressions/predicate/NegationPredicate.hpp | 2 - expressions/predicate/Predicate.hpp | 6 -- expressions/predicate/TrivialPredicates.hpp | 4 - expressions/scalar/Scalar.hpp | 50 +++++------ expressions/scalar/ScalarAttribute.cpp | 58 +++++++++---- expressions/scalar/ScalarAttribute.hpp | 10 +-- expressions/scalar/ScalarBinaryExpression.cpp | 80 +++++------------ expressions/scalar/ScalarBinaryExpression.hpp | 4 - expressions/scalar/ScalarCaseExpression.cpp | 62 +++----------- expressions/scalar/ScalarCaseExpression.hpp | 4 - expressions/scalar/ScalarLiteral.cpp | 2 - expressions/scalar/ScalarLiteral.hpp | 4 - expressions/scalar/ScalarSharedExpression.cpp | 14 +-- expressions/scalar/ScalarSharedExpression.hpp | 4 - expressions/scalar/ScalarUnaryExpression.cpp | 18 +--- expressions/scalar/ScalarUnaryExpression.hpp | 4 - .../tests/ScalarCaseExpression_unittest.cpp | 58 ++++++------- query_optimizer/ExecutionGenerator.cpp | 88 ++++++++++++------- query_optimizer/ExecutionGenerator.hpp | 21 +++-- query_optimizer/expressions/Alias.cpp | 5 +- query_optimizer/expressions/Alias.hpp | 5 +- .../expressions/AttributeReference.cpp | 19 ++++- .../expressions/AttributeReference.hpp | 5 +- .../expressions/BinaryExpression.cpp | 9 +- .../expressions/BinaryExpression.hpp | 5 +- query_optimizer/expressions/CMakeLists.txt | 1 + query_optimizer/expressions/Cast.cpp | 10 ++- query_optimizer/expressions/Cast.hpp | 5 +- .../expressions/CommonSubexpression.cpp | 7 +- .../expressions/CommonSubexpression.hpp | 5 +- .../expressions/ComparisonExpression.cpp | 9 +- .../expressions/ComparisonExpression.hpp | 5 +- query_optimizer/expressions/Exists.cpp | 5 +- query_optimizer/expressions/Exists.hpp | 5 +- query_optimizer/expressions/InTableQuery.cpp | 5 +- query_optimizer/expressions/InTableQuery.hpp | 5 +- query_optimizer/expressions/InValueList.cpp | 7 +- query_optimizer/expressions/InValueList.hpp | 5 +- query_optimizer/expressions/LogicalAnd.cpp | 9 +- query_optimizer/expressions/LogicalAnd.hpp | 5 +- query_optimizer/expressions/LogicalNot.cpp | 7 +- query_optimizer/expressions/LogicalNot.hpp | 5 +- query_optimizer/expressions/LogicalOr.cpp | 9 +- query_optimizer/expressions/LogicalOr.hpp | 5 +- query_optimizer/expressions/Predicate.hpp | 7 +- .../expressions/PredicateLiteral.cpp | 5 +- .../expressions/PredicateLiteral.hpp | 5 +- query_optimizer/expressions/Scalar.hpp | 8 +- query_optimizer/expressions/ScalarLiteral.cpp | 5 +- query_optimizer/expressions/ScalarLiteral.hpp | 5 +- query_optimizer/expressions/SearchedCase.cpp | 17 ++-- query_optimizer/expressions/SearchedCase.hpp | 5 +- query_optimizer/expressions/SimpleCase.cpp | 7 +- query_optimizer/expressions/SimpleCase.hpp | 5 +- .../expressions/SubqueryExpression.cpp | 5 +- .../expressions/SubqueryExpression.hpp | 5 +- query_optimizer/expressions/UnaryExpression.cpp | 7 +- query_optimizer/expressions/UnaryExpression.hpp | 5 +- .../tests/execution_generator/Select.test | 56 +++++++++++- relational_operators/HashJoinOperator.cpp | 90 +++++++------------- .../NestedLoopsJoinOperator.cpp | 9 +- .../tests/HashJoinOperator_unittest.cpp | 34 ++++---- 71 files changed, 536 insertions(+), 467 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/ExpressionFactories.cpp ---------------------------------------------------------------------- diff --git a/expressions/ExpressionFactories.cpp b/expressions/ExpressionFactories.cpp index 871db50..cab99fd 100644 --- a/expressions/ExpressionFactories.cpp +++ b/expressions/ExpressionFactories.cpp @@ -52,6 +52,8 @@ namespace quickstep { +namespace S = serialization; + class Type; Predicate* PredicateFactory::ReconstructFromProto(const serialization::Predicate &proto, @@ -163,9 +165,22 @@ Scalar* ScalarFactory::ReconstructFromProto(const serialization::Scalar &proto, case serialization::Scalar::ATTRIBUTE: { const relation_id rel_id = proto.GetExtension(serialization::ScalarAttribute::relation_id); + Scalar::JoinSide join_side; + switch (proto.GetExtension(S::ScalarAttribute::join_side)) { + case S::ScalarAttribute::NONE: + join_side = Scalar::kNone; + break; + case S::ScalarAttribute::LEFT_SIDE: + join_side = Scalar::kLeftSide; + break; + case S::ScalarAttribute::RIGHT_SIDE: + join_side = Scalar::kRightSide; + break; + } + DCHECK(database.hasRelationWithId(rel_id)); return new ScalarAttribute(*database.getRelationSchemaById(rel_id).getAttributeById( - proto.GetExtension(serialization::ScalarAttribute::attribute_id))); + proto.GetExtension(serialization::ScalarAttribute::attribute_id)), join_side); } case serialization::Scalar::UNARY_EXPRESSION: { return new ScalarUnaryExpression( http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/Expressions.proto ---------------------------------------------------------------------- diff --git a/expressions/Expressions.proto b/expressions/Expressions.proto index 8b4611e..aabb707 100644 --- a/expressions/Expressions.proto +++ b/expressions/Expressions.proto @@ -95,9 +95,16 @@ message ScalarLiteral { } message ScalarAttribute { + enum JoinSide { + NONE = 0; + LEFT_SIDE = 1; + RIGHT_SIDE = 2; + } + extend Scalar { optional int32 relation_id = 64; optional int32 attribute_id = 65; + optional JoinSide join_side = 66; } } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/ComparisonPredicate.cpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/ComparisonPredicate.cpp b/expressions/predicate/ComparisonPredicate.cpp index 2f7b84b..0417170 100644 --- a/expressions/predicate/ComparisonPredicate.cpp +++ b/expressions/predicate/ComparisonPredicate.cpp @@ -94,28 +94,22 @@ bool ComparisonPredicate::matchesForSingleTuple(const ValueAccessor &accessor, bool ComparisonPredicate::matchesForJoinedTuples( 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 { if (fast_comparator_.get() == nullptr) { return static_result_; - } else { - return fast_comparator_->compareTypedValues( - left_operand_->getValueForJoinedTuples(left_accessor, - left_relation_id, - left_tuple_id, - right_accessor, - right_relation_id, - right_tuple_id), - right_operand_->getValueForJoinedTuples(left_accessor, - left_relation_id, - left_tuple_id, - right_accessor, - right_relation_id, - right_tuple_id)); } + + return fast_comparator_->compareTypedValues( + left_operand_->getValueForJoinedTuples(left_accessor, + left_tuple_id, + right_accessor, + right_tuple_id), + right_operand_->getValueForJoinedTuples(left_accessor, + left_tuple_id, + right_accessor, + right_tuple_id)); } TupleIdSequence* ComparisonPredicate::getAllMatches( http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/ComparisonPredicate.hpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/ComparisonPredicate.hpp b/expressions/predicate/ComparisonPredicate.hpp index 1ef2cb1..014e378 100644 --- a/expressions/predicate/ComparisonPredicate.hpp +++ b/expressions/predicate/ComparisonPredicate.hpp @@ -83,10 +83,8 @@ class ComparisonPredicate : public Predicate { bool matchesForJoinedTuples( 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; TupleIdSequence* getAllMatches(ValueAccessor *accessor, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/ConjunctionPredicate.cpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/ConjunctionPredicate.cpp b/expressions/predicate/ConjunctionPredicate.cpp index 4f5cc77..39d9e58 100644 --- a/expressions/predicate/ConjunctionPredicate.cpp +++ b/expressions/predicate/ConjunctionPredicate.cpp @@ -85,10 +85,8 @@ bool ConjunctionPredicate::matchesForSingleTuple(const ValueAccessor &accessor, bool ConjunctionPredicate::matchesForJoinedTuples( 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 { if (has_static_result_) { return static_result_; @@ -97,10 +95,8 @@ bool ConjunctionPredicate::matchesForJoinedTuples( it != dynamic_operand_list_.end(); ++it) { if (!it->matchesForJoinedTuples(left_accessor, - left_relation_id, left_tuple_id, right_accessor, - right_relation_id, right_tuple_id)) { return false; } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/ConjunctionPredicate.hpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/ConjunctionPredicate.hpp b/expressions/predicate/ConjunctionPredicate.hpp index b24036a..07148a7 100644 --- a/expressions/predicate/ConjunctionPredicate.hpp +++ b/expressions/predicate/ConjunctionPredicate.hpp @@ -63,10 +63,8 @@ class ConjunctionPredicate : public PredicateWithList { bool matchesForJoinedTuples( 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; TupleIdSequence* getAllMatches(ValueAccessor *accessor, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/DisjunctionPredicate.cpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/DisjunctionPredicate.cpp b/expressions/predicate/DisjunctionPredicate.cpp index e117c99..4ac3bd7 100644 --- a/expressions/predicate/DisjunctionPredicate.cpp +++ b/expressions/predicate/DisjunctionPredicate.cpp @@ -85,10 +85,8 @@ bool DisjunctionPredicate::matchesForSingleTuple(const ValueAccessor &accessor, bool DisjunctionPredicate::matchesForJoinedTuples( 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 { if (has_static_result_) { return static_result_; @@ -97,10 +95,8 @@ bool DisjunctionPredicate::matchesForJoinedTuples( it != dynamic_operand_list_.end(); ++it) { if (it->matchesForJoinedTuples(left_accessor, - left_relation_id, left_tuple_id, right_accessor, - right_relation_id, right_tuple_id)) { return true; } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/DisjunctionPredicate.hpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/DisjunctionPredicate.hpp b/expressions/predicate/DisjunctionPredicate.hpp index 2127573..2b237e6 100644 --- a/expressions/predicate/DisjunctionPredicate.hpp +++ b/expressions/predicate/DisjunctionPredicate.hpp @@ -63,10 +63,8 @@ class DisjunctionPredicate : public PredicateWithList { bool matchesForJoinedTuples( 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; TupleIdSequence* getAllMatches(ValueAccessor *accessor, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/NegationPredicate.cpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/NegationPredicate.cpp b/expressions/predicate/NegationPredicate.cpp index 92a8411..ad3238a 100644 --- a/expressions/predicate/NegationPredicate.cpp +++ b/expressions/predicate/NegationPredicate.cpp @@ -54,19 +54,15 @@ bool NegationPredicate::matchesForSingleTuple(const ValueAccessor &accessor, bool NegationPredicate::matchesForJoinedTuples( 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 { if (has_static_result_) { return static_result_; } else { return !(operand_->matchesForJoinedTuples(left_accessor, - left_relation_id, left_tuple_id, right_accessor, - right_relation_id, right_tuple_id)); } } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/NegationPredicate.hpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/NegationPredicate.hpp b/expressions/predicate/NegationPredicate.hpp index ec005ea..7afcf1c 100644 --- a/expressions/predicate/NegationPredicate.hpp +++ b/expressions/predicate/NegationPredicate.hpp @@ -91,10 +91,8 @@ class NegationPredicate : public Predicate { bool matchesForJoinedTuples( 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; TupleIdSequence* getAllMatches(ValueAccessor *accessor, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/Predicate.hpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/Predicate.hpp b/expressions/predicate/Predicate.hpp index df04644..31fbb9a 100644 --- a/expressions/predicate/Predicate.hpp +++ b/expressions/predicate/Predicate.hpp @@ -123,15 +123,11 @@ class Predicate : public Expression { * @param left_accessor The ValueAccessor that the first of the joined tuples * will be read from (this does NOT necessarily correspond to the left * operand of a binary operation). - * @param left_relation_id The ID of the relation that left_accessor provides - * access to. * @param left_tuple_id The ID of the tuple (the absolute position) from * left_accessor to evaluate this Predicate for. * @param right_accessor The ValueAccessor that the second of the joined * tuples will be read from (this does NOT necessarily correspond to * the right operand of a binary operation). - * @param right_relation_id The ID of the relation that right_accessor - * provides access to. * @param right_tuple_id The ID of the tuple (the absolute position) from * right_accessor to evaluate this Predicate for. * @return Whether this predicate is true for the given tuples. @@ -144,10 +140,8 @@ class Predicate : public Expression { // a smallish set of matches from a hash-join by a residual predicate). virtual bool matchesForJoinedTuples( 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 = 0; /** http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/predicate/TrivialPredicates.hpp ---------------------------------------------------------------------- diff --git a/expressions/predicate/TrivialPredicates.hpp b/expressions/predicate/TrivialPredicates.hpp index 4e44976..e313cd5 100644 --- a/expressions/predicate/TrivialPredicates.hpp +++ b/expressions/predicate/TrivialPredicates.hpp @@ -84,10 +84,8 @@ class TruePredicate : public TrivialPredicate { bool matchesForJoinedTuples( 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 true; } @@ -137,10 +135,8 @@ class FalsePredicate : public TrivialPredicate { bool matchesForJoinedTuples( 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 false; } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/Scalar.hpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/Scalar.hpp b/expressions/scalar/Scalar.hpp index 6e482c2..0c1cba1 100644 --- a/expressions/scalar/Scalar.hpp +++ b/expressions/scalar/Scalar.hpp @@ -51,6 +51,15 @@ struct SubBlocksReference; class Scalar : public Expression { public: /** + * @brief The possible binary join side of Scalar values. + **/ + enum JoinSide { + kNone = 0, + kLeftSide, + kRightSide + }; + + /** * @brief The possible provenance of Scalar values. **/ enum ScalarDataSource { @@ -128,28 +137,35 @@ class Scalar : public Expression { * @param left_accessor The ValueAccessor that the first of the joined * tuples can be read from (this does NOT necessarily correspond to * the left operand of a binary operation). - * @param left_relation_id The ID of the relation that left_tuple_store - * belongs to. * @param left_tuple_id The ID of the tuple in left_tuple_store to evaluate * this Scalar for. * @param right_accessor The ValueAccessor that the second of the joined * tuples can be read from (this does NOT necessarily correspond to * the right operand of a binary operation). - * @param right_relation_id The ID of the relation that right_tuple_store - * belongs to. * @param right_tuple_id The ID of the tuple in right_tuple_store to evaluate * this Scalar for. * @return The value of this scalar for the given tuples. **/ virtual 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 = 0; /** + * @brief If it is possible to get this Scalar's values directly from a + * ValueAccessor, return the binary join side of the ValueAccessor + * should belong to. + * + * @return The binary join side for ValueAccessors that can directly produce + * this Scalar's values, or kNone if values can not be obtained + * directly from a ValueAccessor. + **/ + JoinSide join_side() const { + return join_side_; + } + + /** * @brief Determine whether this Scalar's value is static (i.e. whether it is * the same regardless of tuple). * @@ -181,19 +197,6 @@ class Scalar : public Expression { } /** - * @brief If it is possible to get this Scalar's values directly from a - * ValueAccessor, return the ID of the relation that such a - * ValueAccessor should belong to. - * - * @return The relation_id for ValueAccessors that can directly produce this - * Scalar's values, or -1 if values can not be obtained directly from - * a ValueAccessor. - **/ - virtual relation_id getRelationIdForValueAccessor() const { - return -1; - } - - /** * @brief Get this Scalar's values for all tuples accesible via a * ValueAccessor. * @@ -217,10 +220,8 @@ class Scalar : public Expression { * @brief Get this Scalar's value for all specified joined tuples from two * ValueAccessors. * - * @param left_relation_id The ID of the left relation in the join. * @param left_accessor A ValueAccessor which will be used to access tuples * from the left relation. - * @param right_relation_id The ID of the right relation in the join. * @param right_accessor A ValueAccessor which will be used to access tuples * from the right relation. * @param joined_tuple_ids A series of pairs of tuple ids from the left and @@ -231,9 +232,7 @@ class Scalar : public Expression { * specified by joined_tuple_ids. **/ virtual 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, ColumnVectorCache *cv_cache) const = 0; @@ -247,10 +246,11 @@ class Scalar : public Expression { std::vector<std::string> *container_child_field_names, std::vector<std::vector<const Expression*>> *container_child_fields) const override; - explicit Scalar(const Type &type) - : Expression(), type_(type) {} + explicit Scalar(const Type &type, const JoinSide join_side = kNone) + : Expression(), type_(type), join_side_(join_side) {} const Type &type_; + const JoinSide join_side_; private: DISALLOW_COPY_AND_ASSIGN(Scalar); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarAttribute.cpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarAttribute.cpp b/expressions/scalar/ScalarAttribute.cpp index 944dc35..8a75bb0 100644 --- a/expressions/scalar/ScalarAttribute.cpp +++ b/expressions/scalar/ScalarAttribute.cpp @@ -28,6 +28,7 @@ #include "catalog/CatalogRelationSchema.hpp" #include "catalog/CatalogTypedefs.hpp" #include "expressions/Expressions.pb.h" +#include "expressions/scalar/Scalar.hpp" #include "storage/StorageBlockInfo.hpp" #include "storage/ValueAccessor.hpp" #include "storage/ValueAccessorUtil.hpp" @@ -40,8 +41,11 @@ namespace quickstep { -ScalarAttribute::ScalarAttribute(const CatalogAttribute &attribute) - : Scalar(attribute.getType()), +namespace S = serialization; + +ScalarAttribute::ScalarAttribute(const CatalogAttribute &attribute, + const JoinSide join_side) + : Scalar(attribute.getType(), join_side), attribute_(attribute) { } @@ -51,11 +55,25 @@ serialization::Scalar ScalarAttribute::getProto() const { proto.SetExtension(serialization::ScalarAttribute::relation_id, attribute_.getParent().getID()); proto.SetExtension(serialization::ScalarAttribute::attribute_id, attribute_.getID()); + S::ScalarAttribute::JoinSide join_side_proto; + switch (join_side_) { + case kNone: + join_side_proto = S::ScalarAttribute::NONE; + break; + case kLeftSide: + join_side_proto = S::ScalarAttribute::LEFT_SIDE; + break; + case kRightSide: + join_side_proto = S::ScalarAttribute::RIGHT_SIDE; + break; + } + proto.SetExtension(S::ScalarAttribute::join_side, join_side_proto); + return proto; } Scalar* ScalarAttribute::clone() const { - return new ScalarAttribute(attribute_); + return new ScalarAttribute(attribute_, join_side_); } TypedValue ScalarAttribute::getValueForSingleTuple(const ValueAccessor &accessor, @@ -65,18 +83,16 @@ TypedValue ScalarAttribute::getValueForSingleTuple(const ValueAccessor &accessor TypedValue ScalarAttribute::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 { - // FIXME(chasseur): This can get confused and break for self-joins. - DCHECK((attribute_.getParent().getID() == left_relation_id) - || (attribute_.getParent().getID() == right_relation_id)); - if (attribute_.getParent().getID() == left_relation_id) { + DCHECK(join_side_ != kNone); + + if (join_side_ == kLeftSide) { return left_accessor.getTypedValueAtAbsolutePositionVirtual(attribute_.getID(), left_tuple_id); } else { + DCHECK(join_side_ == kRightSide); return right_accessor.getTypedValueAtAbsolutePositionVirtual(attribute_.getID(), right_tuple_id); } @@ -86,10 +102,6 @@ attribute_id ScalarAttribute::getAttributeIdForValueAccessor() const { return attribute_.getID(); } -relation_id ScalarAttribute::getRelationIdForValueAccessor() const { - return attribute_.getParent().getID(); -} - ColumnVectorPtr ScalarAttribute::getAllValues( ValueAccessor *accessor, const SubBlocksReference *sub_blocks_ref, @@ -157,19 +169,16 @@ ColumnVectorPtr ScalarAttribute::getAllValues( } ColumnVectorPtr ScalarAttribute::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, ColumnVectorCache *cv_cache) const { - DCHECK((attribute_.getParent().getID() == left_relation_id) - || (attribute_.getParent().getID() == right_relation_id)); + DCHECK(join_side_ != kNone); const attribute_id attr_id = attribute_.getID(); const Type &result_type = attribute_.getType(); - const bool using_left_relation = (attribute_.getParent().getID() == left_relation_id); + const bool using_left_relation = (join_side_ == kLeftSide); ValueAccessor *accessor = using_left_relation ? left_accessor : right_accessor; @@ -232,6 +241,19 @@ void ScalarAttribute::getFieldStringItems( inline_field_names->emplace_back("attribute"); inline_field_values->emplace_back(std::to_string(attribute_.getID())); + + switch (join_side_) { + case kNone: + break; + case kLeftSide: + inline_field_names->emplace_back("join_side"); + inline_field_values->push_back("left_side"); + break; + case kRightSide: + inline_field_names->emplace_back("join_side"); + inline_field_values->push_back("right_side"); + break; + } } } // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarAttribute.hpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarAttribute.hpp b/expressions/scalar/ScalarAttribute.hpp index 4d30fe9..cd718c8 100644 --- a/expressions/scalar/ScalarAttribute.hpp +++ b/expressions/scalar/ScalarAttribute.hpp @@ -53,8 +53,10 @@ class ScalarAttribute : public Scalar { * @brief Constructor. * * @param attribute The attribute to use. + * @param join_side The join side of which this attribute belongs to. **/ - explicit ScalarAttribute(const CatalogAttribute &attribute); + explicit ScalarAttribute(const CatalogAttribute &attribute, + const JoinSide join_side = kNone); serialization::Scalar getProto() const override; @@ -69,24 +71,18 @@ class ScalarAttribute : public Scalar { 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; attribute_id getAttributeIdForValueAccessor() const override; - relation_id getRelationIdForValueAccessor() const override; - ColumnVectorPtr getAllValues(ValueAccessor *accessor, const SubBlocksReference *sub_blocks_ref, ColumnVectorCache *cv_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, ColumnVectorCache *cv_cache) const override; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarBinaryExpression.cpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarBinaryExpression.cpp b/expressions/scalar/ScalarBinaryExpression.cpp index b3568f8..ecbe84f 100644 --- a/expressions/scalar/ScalarBinaryExpression.cpp +++ b/expressions/scalar/ScalarBinaryExpression.cpp @@ -79,26 +79,20 @@ TypedValue ScalarBinaryExpression::getValueForSingleTuple(const ValueAccessor &a TypedValue ScalarBinaryExpression::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 { if (fast_operator_.get() == nullptr) { return static_value_.makeReferenceToThis(); } else { return fast_operator_->applyToTypedValues( left_operand_->getValueForJoinedTuples(left_accessor, - left_relation_id, left_tuple_id, right_accessor, - right_relation_id, right_tuple_id), right_operand_->getValueForJoinedTuples(left_accessor, - left_relation_id, left_tuple_id, right_accessor, - right_relation_id, right_tuple_id)); } } @@ -199,9 +193,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValues( } ColumnVectorPtr ScalarBinaryExpression::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, ColumnVectorCache *cv_cache) const { @@ -216,12 +208,9 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin( const attribute_id right_operand_attr_id = right_operand_->getAttributeIdForValueAccessor(); if (right_operand_attr_id != -1) { - const relation_id right_operand_relation_id - = right_operand_->getRelationIdForValueAccessor(); - DCHECK_NE(right_operand_relation_id, -1); - DCHECK((right_operand_relation_id == left_relation_id) - || (right_operand_relation_id == right_relation_id)); - const bool using_left_relation = (right_operand_relation_id == left_relation_id); + const JoinSide join_side = right_operand_->join_side(); + DCHECK(join_side != kNone); + const bool using_left_relation = (join_side == kLeftSide); ValueAccessor *right_operand_accessor = using_left_relation ? left_accessor : right_accessor; return ColumnVectorPtr( @@ -235,9 +224,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin( #endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN ColumnVectorPtr right_result( - right_operand_->getAllValuesForJoin(left_relation_id, - left_accessor, - right_relation_id, + right_operand_->getAllValuesForJoin(left_accessor, right_accessor, joined_tuple_ids, cv_cache)); @@ -250,12 +237,9 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin( const attribute_id left_operand_attr_id = left_operand_->getAttributeIdForValueAccessor(); if (left_operand_attr_id != -1) { - const relation_id left_operand_relation_id - = left_operand_->getRelationIdForValueAccessor(); - DCHECK_NE(left_operand_relation_id, -1); - DCHECK((left_operand_relation_id == left_relation_id) - || (left_operand_relation_id == right_relation_id)); - const bool using_left_relation = (left_operand_relation_id == left_relation_id); + const JoinSide join_side = left_operand_->join_side(); + DCHECK(join_side != kNone); + const bool using_left_relation = (join_side == kLeftSide); ValueAccessor *left_operand_accessor = using_left_relation ? left_accessor : right_accessor; return ColumnVectorPtr( @@ -269,9 +253,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin( #endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN ColumnVectorPtr left_result( - left_operand_->getAllValuesForJoin(left_relation_id, - left_accessor, - right_relation_id, + left_operand_->getAllValuesForJoin(left_accessor, right_accessor, joined_tuple_ids, cv_cache)); @@ -286,25 +268,17 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin( const attribute_id right_operand_attr_id = right_operand_->getAttributeIdForValueAccessor(); if (left_operand_attr_id != -1) { - const relation_id left_operand_relation_id - = left_operand_->getRelationIdForValueAccessor(); - DCHECK_NE(left_operand_relation_id, -1); - DCHECK((left_operand_relation_id == left_relation_id) - || (left_operand_relation_id == right_relation_id)); - const bool using_left_relation_for_left_operand - = (left_operand_relation_id == left_relation_id); + const JoinSide join_side = left_operand_->join_side(); + DCHECK(join_side != kNone); + const bool using_left_relation_for_left_operand = (join_side == kLeftSide); ValueAccessor *left_operand_accessor = using_left_relation_for_left_operand ? left_accessor : right_accessor; #ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN_WITH_BINARY_EXPRESSIONS if (right_operand_attr_id != -1) { - const relation_id right_operand_relation_id - = right_operand_->getRelationIdForValueAccessor(); - DCHECK_NE(right_operand_relation_id, -1); - DCHECK((right_operand_relation_id == left_relation_id) - || (right_operand_relation_id == right_relation_id)); - const bool using_left_relation_for_right_operand - = (right_operand_relation_id == left_relation_id); + const JoinSide join_side = right_operand_->join_side(); + DCHECK(join_side != kNone); + const bool using_left_relation_for_right_operand = (join_side == kLeftSide); ValueAccessor *right_operand_accessor = using_left_relation_for_right_operand ? left_accessor : right_accessor; return ColumnVectorPtr( @@ -318,9 +292,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin( } #endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN_WITH_BINARY_EXPRESSIONS ColumnVectorPtr right_result( - right_operand_->getAllValuesForJoin(left_relation_id, - left_accessor, - right_relation_id, + right_operand_->getAllValuesForJoin(left_accessor, right_accessor, joined_tuple_ids, cv_cache)); @@ -333,20 +305,14 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin( *right_result, joined_tuple_ids)); } else if (right_operand_attr_id != -1) { - const relation_id right_operand_relation_id - = right_operand_->getRelationIdForValueAccessor(); - DCHECK_NE(right_operand_relation_id, -1); - DCHECK((right_operand_relation_id == left_relation_id) - || (right_operand_relation_id == right_relation_id)); - const bool using_left_relation_for_right_operand - = (right_operand_relation_id == left_relation_id); + const JoinSide join_side = right_operand_->join_side(); + DCHECK(join_side != kNone); + const bool using_left_relation_for_right_operand = (join_side == kLeftSide); ValueAccessor *right_operand_accessor = using_left_relation_for_right_operand ? left_accessor : right_accessor; ColumnVectorPtr left_result( - left_operand_->getAllValuesForJoin(left_relation_id, - left_accessor, - right_relation_id, + left_operand_->getAllValuesForJoin(left_accessor, right_accessor, joined_tuple_ids, cv_cache)); @@ -361,16 +327,12 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin( #endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN ColumnVectorPtr left_result( - left_operand_->getAllValuesForJoin(left_relation_id, - left_accessor, - right_relation_id, + left_operand_->getAllValuesForJoin(left_accessor, right_accessor, joined_tuple_ids, cv_cache)); ColumnVectorPtr right_result( - right_operand_->getAllValuesForJoin(left_relation_id, - left_accessor, - right_relation_id, + right_operand_->getAllValuesForJoin(left_accessor, right_accessor, joined_tuple_ids, cv_cache)); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarBinaryExpression.hpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarBinaryExpression.hpp b/expressions/scalar/ScalarBinaryExpression.hpp index 4ac1f62..6f9c41d 100644 --- a/expressions/scalar/ScalarBinaryExpression.hpp +++ b/expressions/scalar/ScalarBinaryExpression.hpp @@ -84,10 +84,8 @@ class ScalarBinaryExpression : public Scalar { 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; bool hasStaticValue() const override { @@ -104,9 +102,7 @@ class ScalarBinaryExpression : public Scalar { ColumnVectorCache *cv_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, ColumnVectorCache *cv_cache) const override; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarCaseExpression.cpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarCaseExpression.cpp b/expressions/scalar/ScalarCaseExpression.cpp index c2af83b..39e19c6 100644 --- a/expressions/scalar/ScalarCaseExpression.cpp +++ b/expressions/scalar/ScalarCaseExpression.cpp @@ -247,47 +247,27 @@ TypedValue ScalarCaseExpression::getValueForSingleTuple( TypedValue ScalarCaseExpression::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 { if (has_static_value_) { return static_value_.makeReferenceToThis(); } else if (fixed_result_expression_ != nullptr) { - return fixed_result_expression_->getValueForJoinedTuples(left_accessor, - left_relation_id, - left_tuple_id, - right_accessor, - right_relation_id, - right_tuple_id); + return fixed_result_expression_->getValueForJoinedTuples( + left_accessor, left_tuple_id, right_accessor, right_tuple_id); } for (std::vector<std::unique_ptr<Predicate>>::size_type case_idx = 0; case_idx < when_predicates_.size(); ++case_idx) { - if (when_predicates_[case_idx]->matchesForJoinedTuples(left_accessor, - left_relation_id, - left_tuple_id, - right_accessor, - right_relation_id, - right_tuple_id)) { + if (when_predicates_[case_idx]->matchesForJoinedTuples( + left_accessor, left_tuple_id, right_accessor, right_tuple_id)) { return result_expressions_[case_idx]->getValueForJoinedTuples( - left_accessor, - left_relation_id, - left_tuple_id, - right_accessor, - right_relation_id, - right_tuple_id); + left_accessor, left_tuple_id, right_accessor, right_tuple_id); } } return else_result_expression_->getValueForJoinedTuples( - left_accessor, - left_relation_id, - left_tuple_id, - right_accessor, - right_relation_id, - right_tuple_id); + left_accessor, left_tuple_id, right_accessor, right_tuple_id); } ColumnVectorPtr ScalarCaseExpression::getAllValues( @@ -370,9 +350,7 @@ ColumnVectorPtr ScalarCaseExpression::getAllValues( } ColumnVectorPtr ScalarCaseExpression::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, ColumnVectorCache *cv_cache) const { @@ -381,9 +359,7 @@ ColumnVectorPtr ScalarCaseExpression::getAllValuesForJoin( ColumnVector::MakeVectorOfValue(type_, static_value_, joined_tuple_ids.size())); } else if (fixed_result_expression_) { return fixed_result_expression_->getAllValuesForJoin( - left_relation_id, left_accessor, - right_relation_id, right_accessor, - joined_tuple_ids, cv_cache); + left_accessor, right_accessor, joined_tuple_ids, cv_cache); } // Slice 'joined_tuple_ids' apart by case. @@ -418,13 +394,9 @@ ColumnVectorPtr ScalarCaseExpression::getAllValuesForJoin( const Predicate &case_predicate = *when_predicates_[case_idx]; for (tuple_id pos : else_positions) { - const std::pair<tuple_id, tuple_id> check_pair = joined_tuple_ids[pos]; - if (case_predicate.matchesForJoinedTuples(*left_accessor, - left_relation_id, - check_pair.first, - *right_accessor, - right_relation_id, - check_pair.second)) { + const std::pair<tuple_id, tuple_id> &check_pair = joined_tuple_ids[pos]; + if (case_predicate.matchesForJoinedTuples( + *left_accessor, check_pair.first, *right_accessor, check_pair.second)) { current_case_positions->set(pos); current_case_matches.emplace_back(check_pair); } @@ -439,12 +411,7 @@ ColumnVectorPtr ScalarCaseExpression::getAllValuesForJoin( case_idx < case_matches.size(); ++case_idx) { case_results.emplace_back(result_expressions_[case_idx]->getAllValuesForJoin( - left_relation_id, - left_accessor, - right_relation_id, - right_accessor, - case_matches[case_idx], - cv_cache)); + left_accessor, right_accessor, case_matches[case_idx], cv_cache)); } ColumnVectorPtr else_results; @@ -455,12 +422,7 @@ ColumnVectorPtr ScalarCaseExpression::getAllValuesForJoin( } else_results = else_result_expression_->getAllValuesForJoin( - left_relation_id, - left_accessor, - right_relation_id, - right_accessor, - else_matches, - cv_cache); + left_accessor, right_accessor, else_matches, cv_cache); } // Multiplex per-case results into a single ColumnVector with values in the http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarCaseExpression.hpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarCaseExpression.hpp b/expressions/scalar/ScalarCaseExpression.hpp index 22acfa8..14a2666 100644 --- a/expressions/scalar/ScalarCaseExpression.hpp +++ b/expressions/scalar/ScalarCaseExpression.hpp @@ -101,10 +101,8 @@ class ScalarCaseExpression : public Scalar { 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; bool hasStaticValue() const override { @@ -129,9 +127,7 @@ class ScalarCaseExpression : public Scalar { ColumnVectorCache *cv_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, ColumnVectorCache *cv_cache) const override; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarLiteral.cpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarLiteral.cpp b/expressions/scalar/ScalarLiteral.cpp index 808953d..b5f5d17 100644 --- a/expressions/scalar/ScalarLiteral.cpp +++ b/expressions/scalar/ScalarLiteral.cpp @@ -59,9 +59,7 @@ ColumnVectorPtr ScalarLiteral::getAllValues( } ColumnVectorPtr ScalarLiteral::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, ColumnVectorCache *cv_cache) const { http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarLiteral.hpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarLiteral.hpp b/expressions/scalar/ScalarLiteral.hpp index 2a4c396..3b3b994 100644 --- a/expressions/scalar/ScalarLiteral.hpp +++ b/expressions/scalar/ScalarLiteral.hpp @@ -87,10 +87,8 @@ class ScalarLiteral : public Scalar { 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 internal_literal_.makeReferenceToThis(); } @@ -108,9 +106,7 @@ class ScalarLiteral : public Scalar { ColumnVectorCache *cv_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, ColumnVectorCache *cv_cache) const override; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarSharedExpression.cpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarSharedExpression.cpp b/expressions/scalar/ScalarSharedExpression.cpp index e301116..64bfb3f 100644 --- a/expressions/scalar/ScalarSharedExpression.cpp +++ b/expressions/scalar/ScalarSharedExpression.cpp @@ -55,16 +55,12 @@ TypedValue ScalarSharedExpression::getValueForSingleTuple(const ValueAccessor &a TypedValue ScalarSharedExpression::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 { return operand_->getValueForJoinedTuples(left_accessor, - left_relation_id, left_tuple_id, right_accessor, - right_relation_id, right_tuple_id); } @@ -87,16 +83,12 @@ ColumnVectorPtr ScalarSharedExpression::getAllValues( } ColumnVectorPtr ScalarSharedExpression::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, ColumnVectorCache *cv_cache) const { if (cv_cache == nullptr) { - return operand_->getAllValuesForJoin(left_relation_id, - left_accessor, - right_relation_id, + return operand_->getAllValuesForJoin(left_accessor, right_accessor, joined_tuple_ids, cv_cache); @@ -106,9 +98,7 @@ ColumnVectorPtr ScalarSharedExpression::getAllValuesForJoin( if (cv_cache->contains(share_id_)) { result = cv_cache->get(share_id_); } else { - result = operand_->getAllValuesForJoin(left_relation_id, - left_accessor, - right_relation_id, + result = operand_->getAllValuesForJoin(left_accessor, right_accessor, joined_tuple_ids, cv_cache); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarSharedExpression.hpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarSharedExpression.hpp b/expressions/scalar/ScalarSharedExpression.hpp index f39c45b..ba9f32e 100644 --- a/expressions/scalar/ScalarSharedExpression.hpp +++ b/expressions/scalar/ScalarSharedExpression.hpp @@ -83,10 +83,8 @@ class ScalarSharedExpression : public Scalar { 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; bool hasStaticValue() const override { @@ -102,9 +100,7 @@ class ScalarSharedExpression : public Scalar { ColumnVectorCache *cv_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, ColumnVectorCache *cv_cache) const override; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarUnaryExpression.cpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarUnaryExpression.cpp b/expressions/scalar/ScalarUnaryExpression.cpp index c51e38f..be47d43 100644 --- a/expressions/scalar/ScalarUnaryExpression.cpp +++ b/expressions/scalar/ScalarUnaryExpression.cpp @@ -76,19 +76,15 @@ TypedValue ScalarUnaryExpression::getValueForSingleTuple(const ValueAccessor &ac TypedValue ScalarUnaryExpression::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 { if (fast_operator_.get() == nullptr) { return static_value_.makeReferenceToThis(); } else { return fast_operator_->applyToTypedValue(operand_->getValueForJoinedTuples(left_accessor, - left_relation_id, left_tuple_id, right_accessor, - right_relation_id, right_tuple_id)); } } @@ -119,9 +115,7 @@ ColumnVectorPtr ScalarUnaryExpression::getAllValues( } ColumnVectorPtr ScalarUnaryExpression::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, ColumnVectorCache *cv_cache) const { @@ -134,11 +128,9 @@ ColumnVectorPtr ScalarUnaryExpression::getAllValuesForJoin( #ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN const attribute_id operand_attr_id = operand_->getAttributeIdForValueAccessor(); if (operand_attr_id != -1) { - const relation_id operand_relation_id = operand_->getRelationIdForValueAccessor(); - DCHECK_NE(operand_relation_id, -1); - DCHECK((operand_relation_id == left_relation_id) - || (operand_relation_id == right_relation_id)); - const bool using_left_relation = (operand_relation_id == left_relation_id); + const JoinSide join_side = operand_->join_side(); + DCHECK(join_side != kNone); + const bool using_left_relation = (join_side == kLeftSide); ValueAccessor *operand_accessor = using_left_relation ? left_accessor : right_accessor; return ColumnVectorPtr( @@ -150,9 +142,7 @@ ColumnVectorPtr ScalarUnaryExpression::getAllValuesForJoin( #endif // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN ColumnVectorPtr operand_result( - operand_->getAllValuesForJoin(left_relation_id, - left_accessor, - right_relation_id, + operand_->getAllValuesForJoin(left_accessor, right_accessor, joined_tuple_ids, cv_cache)); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/ScalarUnaryExpression.hpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarUnaryExpression.hpp b/expressions/scalar/ScalarUnaryExpression.hpp index 52edea7..a628bd0 100644 --- a/expressions/scalar/ScalarUnaryExpression.hpp +++ b/expressions/scalar/ScalarUnaryExpression.hpp @@ -79,10 +79,8 @@ class ScalarUnaryExpression : public Scalar { 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; bool hasStaticValue() const override { @@ -99,9 +97,7 @@ class ScalarUnaryExpression : public Scalar { ColumnVectorCache *cv_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, ColumnVectorCache *cv_cache) const override; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/expressions/scalar/tests/ScalarCaseExpression_unittest.cpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/tests/ScalarCaseExpression_unittest.cpp b/expressions/scalar/tests/ScalarCaseExpression_unittest.cpp index f385b74..b9b2b38 100644 --- a/expressions/scalar/tests/ScalarCaseExpression_unittest.cpp +++ b/expressions/scalar/tests/ScalarCaseExpression_unittest.cpp @@ -916,8 +916,8 @@ TEST_F(ScalarCaseExpressionTest, JoinStaticBranchConstantTest) { new ScalarLiteral(TypedValue(static_cast<int>(2)), int_type))); result_expressions.emplace_back(new ScalarBinaryExpression( BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd), - new ScalarAttribute(*sample_relation_->getAttributeById(0)), - new ScalarAttribute(*other_relation.getAttributeById(1)))); + new ScalarAttribute(*sample_relation_->getAttributeById(0), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(1), Scalar::kRightSide))); const int kConstant = 72; // WHEN 1 < 2 THEN kConstant @@ -931,8 +931,8 @@ TEST_F(ScalarCaseExpressionTest, JoinStaticBranchConstantTest) { // WHEN double_attr = other_double THEN 0 when_predicates.emplace_back(new ComparisonPredicate( ComparisonFactory::GetComparison(ComparisonID::kEqual), - new ScalarAttribute(*sample_relation_->getAttributeById(1)), - new ScalarAttribute(*other_relation.getAttributeById(0)))); + new ScalarAttribute(*sample_relation_->getAttributeById(1), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(0), Scalar::kRightSide))); result_expressions.emplace_back(new ScalarLiteral(TypedValue(0), TypeFactory::GetType(kInt))); const Type &int_nullable_type = TypeFactory::GetType(kInt, true); @@ -947,14 +947,13 @@ TEST_F(ScalarCaseExpressionTest, JoinStaticBranchConstantTest) { // Create a list of joined tuple-id pairs (just the cross-product of tuples). std::vector<std::pair<tuple_id, tuple_id>> joined_tuple_ids; for (std::size_t tuple_num = 0; tuple_num < kNumSampleTuples; ++tuple_num) { + // <LeftSide-tid, RightSide-tid>. joined_tuple_ids.emplace_back(tuple_num, 0); joined_tuple_ids.emplace_back(tuple_num, 1); } ColumnVectorPtr result_cv(case_expr.getAllValuesForJoin( - 0, &sample_data_value_accessor_, - 1, &other_accessor, joined_tuple_ids, nullptr /* cv_cache */)); @@ -1012,8 +1011,8 @@ TEST_F(ScalarCaseExpressionTest, JoinStaticBranchOnScalarAttributeTest) { new ScalarLiteral(TypedValue(static_cast<int>(2)), int_type))); result_expressions.emplace_back(new ScalarBinaryExpression( BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd), - new ScalarAttribute(*sample_relation_->getAttributeById(0)), - new ScalarAttribute(*other_relation.getAttributeById(1)))); + new ScalarAttribute(*sample_relation_->getAttributeById(0), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(1), Scalar::kRightSide))); // WHEN 1 < 2 THEN int_attr when_predicates.emplace_back(new ComparisonPredicate( @@ -1021,13 +1020,13 @@ TEST_F(ScalarCaseExpressionTest, JoinStaticBranchOnScalarAttributeTest) { new ScalarLiteral(TypedValue(static_cast<int>(1)), int_type), new ScalarLiteral(TypedValue(static_cast<int>(2)), int_type))); result_expressions.emplace_back( - new ScalarAttribute(*sample_relation_->getAttributeById(0))); + new ScalarAttribute(*sample_relation_->getAttributeById(0), Scalar::kLeftSide)); // WHEN double_attr = other_double THEN 0 when_predicates.emplace_back(new ComparisonPredicate( ComparisonFactory::GetComparison(ComparisonID::kEqual), - new ScalarAttribute(*sample_relation_->getAttributeById(1)), - new ScalarAttribute(*other_relation.getAttributeById(0)))); + new ScalarAttribute(*sample_relation_->getAttributeById(1), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(0), Scalar::kRightSide))); result_expressions.emplace_back(new ScalarLiteral(TypedValue(0), TypeFactory::GetType(kInt))); const Type &int_nullable_type = TypeFactory::GetType(kInt, true); @@ -1042,14 +1041,13 @@ TEST_F(ScalarCaseExpressionTest, JoinStaticBranchOnScalarAttributeTest) { // Create a list of joined tuple-id pairs (just the cross-product of tuples). std::vector<std::pair<tuple_id, tuple_id>> joined_tuple_ids; for (std::size_t tuple_num = 0; tuple_num < kNumSampleTuples; ++tuple_num) { + // <LeftSide-tid, RightSide-tid>. joined_tuple_ids.emplace_back(tuple_num, 0); joined_tuple_ids.emplace_back(tuple_num, 1); } ColumnVectorPtr result_cv(case_expr.getAllValuesForJoin( - 0, &sample_data_value_accessor_, - 1, &other_accessor, joined_tuple_ids, nullptr /* cv_cache */)); @@ -1116,8 +1114,8 @@ TEST_F(ScalarCaseExpressionTest, JoinStaticBranchTest) { new ScalarLiteral(TypedValue(static_cast<int>(2)), int_type))); result_expressions.emplace_back(new ScalarBinaryExpression( BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd), - new ScalarAttribute(*sample_relation_->getAttributeById(0)), - new ScalarAttribute(*other_relation.getAttributeById(1)))); + new ScalarAttribute(*sample_relation_->getAttributeById(0), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(1), Scalar::kRightSide))); // WHEN 1 < 2 THEN int_attr * other_int when_predicates.emplace_back(new ComparisonPredicate( @@ -1126,14 +1124,14 @@ TEST_F(ScalarCaseExpressionTest, JoinStaticBranchTest) { new ScalarLiteral(TypedValue(static_cast<int>(2)), int_type))); result_expressions.emplace_back(new ScalarBinaryExpression( BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kMultiply), - new ScalarAttribute(*sample_relation_->getAttributeById(0)), - new ScalarAttribute(*other_relation.getAttributeById(1)))); + new ScalarAttribute(*sample_relation_->getAttributeById(0), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(1), Scalar::kRightSide))); // WHEN double_attr = other_double THEN 0 when_predicates.emplace_back(new ComparisonPredicate( ComparisonFactory::GetComparison(ComparisonID::kEqual), - new ScalarAttribute(*sample_relation_->getAttributeById(1)), - new ScalarAttribute(*other_relation.getAttributeById(0)))); + new ScalarAttribute(*sample_relation_->getAttributeById(1), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(0), Scalar::kRightSide))); result_expressions.emplace_back(new ScalarLiteral(TypedValue(0), TypeFactory::GetType(kInt))); const Type &int_nullable_type = TypeFactory::GetType(kInt, true); @@ -1148,14 +1146,13 @@ TEST_F(ScalarCaseExpressionTest, JoinStaticBranchTest) { // Create a list of joined tuple-id pairs (just the cross-product of tuples). std::vector<std::pair<tuple_id, tuple_id>> joined_tuple_ids; for (std::size_t tuple_num = 0; tuple_num < kNumSampleTuples; ++tuple_num) { + // <LeftSide-tid, RightSide-tid>. joined_tuple_ids.emplace_back(tuple_num, 0); joined_tuple_ids.emplace_back(tuple_num, 1); } ColumnVectorPtr result_cv(case_expr.getAllValuesForJoin( - 0, &sample_data_value_accessor_, - 1, &other_accessor, joined_tuple_ids, nullptr /* cv_cache */)); @@ -1217,22 +1214,22 @@ TEST_F(ScalarCaseExpressionTest, JoinTest) { // WHEN double_attr > other_double THEN int_attr + other_int when_predicates.emplace_back(new ComparisonPredicate( ComparisonFactory::GetComparison(ComparisonID::kGreater), - new ScalarAttribute(*sample_relation_->getAttributeById(1)), - new ScalarAttribute(*other_relation.getAttributeById(0)))); + new ScalarAttribute(*sample_relation_->getAttributeById(1), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(0), Scalar::kRightSide))); result_expressions.emplace_back(new ScalarBinaryExpression( BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd), - new ScalarAttribute(*sample_relation_->getAttributeById(0)), - new ScalarAttribute(*other_relation.getAttributeById(1)))); + new ScalarAttribute(*sample_relation_->getAttributeById(0), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(1), Scalar::kRightSide))); // WHEN double_attr < other_double THEN int_attr * other_int when_predicates.emplace_back(new ComparisonPredicate( ComparisonFactory::GetComparison(ComparisonID::kLess), - new ScalarAttribute(*sample_relation_->getAttributeById(1)), - new ScalarAttribute(*other_relation.getAttributeById(0)))); + new ScalarAttribute(*sample_relation_->getAttributeById(1), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(0), Scalar::kRightSide))); result_expressions.emplace_back(new ScalarBinaryExpression( BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kMultiply), - new ScalarAttribute(*sample_relation_->getAttributeById(0)), - new ScalarAttribute(*other_relation.getAttributeById(1)))); + new ScalarAttribute(*sample_relation_->getAttributeById(0), Scalar::kLeftSide), + new ScalarAttribute(*other_relation.getAttributeById(1), Scalar::kRightSide))); // ELSE 0 ScalarCaseExpression case_expr( @@ -1244,14 +1241,13 @@ TEST_F(ScalarCaseExpressionTest, JoinTest) { // Create a list of joined tuple-id pairs (just the cross-product of tuples). std::vector<std::pair<tuple_id, tuple_id>> joined_tuple_ids; for (std::size_t tuple_num = 0; tuple_num < kNumSampleTuples; ++tuple_num) { + // <LeftSide-tid, RightSide-tid>. joined_tuple_ids.emplace_back(tuple_num, 0); joined_tuple_ids.emplace_back(tuple_num, 1); } ColumnVectorPtr result_cv(case_expr.getAllValuesForJoin( - 0, &sample_data_value_accessor_, - 1, &other_accessor, joined_tuple_ids, nullptr /* cv_cache */)); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/query_optimizer/ExecutionGenerator.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/ExecutionGenerator.cpp b/query_optimizer/ExecutionGenerator.cpp index cc1319c..b413a97 100644 --- a/query_optimizer/ExecutionGenerator.cpp +++ b/query_optimizer/ExecutionGenerator.cpp @@ -29,16 +29,12 @@ #include <string> #include <type_traits> #include <unordered_map> - -#include "query_optimizer/QueryOptimizerConfig.h" // For QUICKSTEP_DISTRIBUTED. - -#ifdef QUICKSTEP_DISTRIBUTED #include <unordered_set> -#endif - #include <utility> #include <vector> +#include "query_optimizer/QueryOptimizerConfig.h" // For QUICKSTEP_DISTRIBUTED. + #ifdef QUICKSTEP_DISTRIBUTED #include "catalog/Catalog.pb.h" #endif @@ -72,6 +68,7 @@ #include "query_optimizer/expressions/Alias.hpp" #include "query_optimizer/expressions/AttributeReference.hpp" #include "query_optimizer/expressions/ComparisonExpression.hpp" +#include "query_optimizer/expressions/ExprId.hpp" #include "query_optimizer/expressions/ExpressionType.hpp" #include "query_optimizer/expressions/PatternMatcher.hpp" #include "query_optimizer/expressions/Scalar.hpp" @@ -573,7 +570,9 @@ void ExecutionGenerator::dropAllTemporaryRelations() { void ExecutionGenerator::convertNamedExpressions( const std::vector<E::NamedExpressionPtr> &named_expressions, - S::QueryContext::ScalarGroup *scalar_group_proto) { + S::QueryContext::ScalarGroup *scalar_group_proto, + const std::unordered_set<E::ExprId> &left_expr_ids, + const std::unordered_set<E::ExprId> &right_expr_ids) { for (const E::NamedExpressionPtr &project_expression : named_expressions) { unique_ptr<const Scalar> execution_scalar; E::AliasPtr alias; @@ -583,9 +582,11 @@ void ExecutionGenerator::convertNamedExpressions( // so all child expressions of an Alias should be a Scalar. CHECK(E::SomeScalar::MatchesWithConditionalCast(alias->expression(), &scalar)) << alias->toString(); - execution_scalar.reset(scalar->concretize(attribute_substitution_map_)); + execution_scalar.reset( + scalar->concretize(attribute_substitution_map_, left_expr_ids, right_expr_ids)); } else { - execution_scalar.reset(project_expression->concretize(attribute_substitution_map_)); + execution_scalar.reset( + project_expression->concretize(attribute_substitution_map_, left_expr_ids, right_expr_ids)); } scalar_group_proto->add_scalars()->MergeFrom(execution_scalar->getProto()); @@ -593,8 +594,10 @@ void ExecutionGenerator::convertNamedExpressions( } Predicate* ExecutionGenerator::convertPredicate( - const expressions::PredicatePtr &optimizer_predicate) const { - return optimizer_predicate->concretize(attribute_substitution_map_); + const expressions::PredicatePtr &optimizer_predicate, + const std::unordered_set<E::ExprId> &left_expr_ids, + const std::unordered_set<E::ExprId> &right_expr_ids) const { + return optimizer_predicate->concretize(attribute_substitution_map_, left_expr_ids, right_expr_ids); } void ExecutionGenerator::convertTableReference( @@ -941,12 +944,27 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) { key_types.push_back(&left_attribute_type); } + std::unordered_set<E::ExprId> probe_expr_ids; + const auto probe_output_attributes = probe_physical->getOutputAttributes(); + probe_expr_ids.reserve(probe_output_attributes.size()); + for (const auto &probe_output_attribute : probe_output_attributes) { + probe_expr_ids.insert(probe_output_attribute->id()); + } + + std::unordered_set<E::ExprId> build_expr_ids; + const auto build_output_attributes = build_physical->getOutputAttributes(); + build_expr_ids.reserve(build_output_attributes.size()); + for (const auto &build_output_attribute : build_output_attributes) { + build_expr_ids.insert(build_output_attribute->id()); + } + // Convert the residual predicate proto. QueryContext::predicate_id residual_predicate_index = QueryContext::kInvalidPredicateId; if (physical_plan->residual_predicate()) { residual_predicate_index = query_context_proto_->predicates_size(); - unique_ptr<const Predicate> residual_predicate(convertPredicate(physical_plan->residual_predicate())); + unique_ptr<const Predicate> residual_predicate( + convertPredicate(physical_plan->residual_predicate(), probe_expr_ids, build_expr_ids)); query_context_proto_->add_predicates()->MergeFrom(residual_predicate->getProto()); } @@ -955,7 +973,8 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) { if (physical_plan->build_predicate()) { build_predicate_index = query_context_proto_->predicates_size(); - unique_ptr<const Predicate> build_predicate(convertPredicate(physical_plan->build_predicate())); + unique_ptr<const Predicate> build_predicate( + convertPredicate(physical_plan->build_predicate(), probe_expr_ids, build_expr_ids)); query_context_proto_->add_predicates()->MergeFrom(build_predicate->getProto()); } @@ -963,7 +982,7 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) { const QueryContext::scalar_group_id project_expressions_group_index = query_context_proto_->scalar_groups_size(); convertNamedExpressions(physical_plan->project_expressions(), - query_context_proto_->add_scalar_groups()); + query_context_proto_->add_scalar_groups(), probe_expr_ids, build_expr_ids); const CatalogRelationInfo *build_relation_info = findRelationInfoOutputByPhysical(build_physical); @@ -979,19 +998,12 @@ void ExecutionGenerator::convertHashJoin(const P::HashJoinPtr &physical_plan) { new std::vector<bool>( E::MarkExpressionsReferingAnyAttribute( physical_plan->project_expressions(), - build_physical->getOutputAttributes()))); + build_output_attributes))); } const CatalogRelation *build_relation = build_relation_info->relation; const CatalogRelation *probe_relation = probe_relation_info->relation; - // FIXME(quickstep-team): Add support for self-join. - // We check to see if the build_predicate is null as certain queries that - // support hash-select fuse will result in the first check being true. - if (build_relation == probe_relation && physical_plan->build_predicate() == nullptr) { - THROW_SQL_ERROR() << "Self-join is not supported"; - } - // Create join hash table proto. const QueryContext::join_hash_table_id join_hash_table_index = query_context_proto_->join_hash_tables_size(); @@ -1129,10 +1141,28 @@ void ExecutionGenerator::convertNestedLoopsJoin( const P::NestedLoopsJoinPtr &physical_plan) { // NestedLoopsJoin is converted to a NestedLoopsJoin operator. + const P::PhysicalPtr &left_physical = physical_plan->left(); + const P::PhysicalPtr &right_physical = physical_plan->right(); + + std::unordered_set<E::ExprId> left_expr_ids; + const auto left_output_attributes = left_physical->getOutputAttributes(); + left_expr_ids.reserve(left_output_attributes.size()); + for (const auto &left_output_attribute : left_output_attributes) { + left_expr_ids.insert(left_output_attribute->id()); + } + + std::unordered_set<E::ExprId> right_expr_ids; + const auto right_output_attributes = right_physical->getOutputAttributes(); + right_expr_ids.reserve(right_output_attributes.size()); + for (const auto &right_output_attribute : right_output_attributes) { + right_expr_ids.insert(right_output_attribute->id()); + } + // Convert the join predicate proto. const QueryContext::predicate_id execution_join_predicate_index = query_context_proto_->predicates_size(); if (physical_plan->join_predicate()) { - unique_ptr<const Predicate> execution_join_predicate(convertPredicate(physical_plan->join_predicate())); + unique_ptr<const Predicate> execution_join_predicate( + convertPredicate(physical_plan->join_predicate(), left_expr_ids, right_expr_ids)); query_context_proto_->add_predicates()->MergeFrom(execution_join_predicate->getProto()); } else { query_context_proto_->add_predicates()->set_predicate_type(S::Predicate::TRUE); @@ -1142,20 +1172,16 @@ void ExecutionGenerator::convertNestedLoopsJoin( const QueryContext::scalar_group_id project_expressions_group_index = query_context_proto_->scalar_groups_size(); convertNamedExpressions(physical_plan->project_expressions(), - query_context_proto_->add_scalar_groups()); + query_context_proto_->add_scalar_groups(), + left_expr_ids, right_expr_ids); const CatalogRelationInfo *left_relation_info = - findRelationInfoOutputByPhysical(physical_plan->left()); + findRelationInfoOutputByPhysical(left_physical); const CatalogRelation &left_relation = *left_relation_info->relation; const CatalogRelationInfo *right_relation_info = - findRelationInfoOutputByPhysical(physical_plan->right()); + findRelationInfoOutputByPhysical(right_physical); const CatalogRelation &right_relation = *right_relation_info->relation; - // FIXME(quickstep-team): Add support for self-join. - if (left_relation.getID() == right_relation.getID()) { - THROW_SQL_ERROR() << "NestedLoopsJoin does not support self-join yet"; - } - const std::size_t num_partitions = left_relation.getNumPartitions(); #ifdef QUICKSTEP_DEBUG http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/query_optimizer/ExecutionGenerator.hpp ---------------------------------------------------------------------- diff --git a/query_optimizer/ExecutionGenerator.hpp b/query_optimizer/ExecutionGenerator.hpp index bc9f88b..1385757 100644 --- a/query_optimizer/ExecutionGenerator.hpp +++ b/query_optimizer/ExecutionGenerator.hpp @@ -24,11 +24,7 @@ #include <memory> #include <string> #include <unordered_map> - -#ifdef QUICKSTEP_DISTRIBUTED #include <unordered_set> -#endif - #include <vector> #include "catalog/CatalogTypedefs.hpp" @@ -388,10 +384,16 @@ class ExecutionGenerator { * @param named_expressions The list of NamedExpressions to be converted. * @param scalar_group_proto The corresponding scalars proto in QueryContext * proto. + * @param left_expr_ids The ExprIds from the left hand side. + * @param right_expr_ids The ExprIds from the right hand side. */ void convertNamedExpressions( const std::vector<expressions::NamedExpressionPtr> &named_expressions, - serialization::QueryContext::ScalarGroup *scalar_group_proto); + serialization::QueryContext::ScalarGroup *scalar_group_proto, + const std::unordered_set<expressions::ExprId> &left_expr_ids = + std::unordered_set<expressions::ExprId>(), + const std::unordered_set<expressions::ExprId> &right_expr_ids = + std::unordered_set<expressions::ExprId>()); /** * @brief Converts a Predicate in the optimizer expression system to a @@ -399,9 +401,16 @@ class ExecutionGenerator { * takes ownership of the returned pointer. * * @param optimizer_predicate The Predicate to be converted. + * @param left_expr_ids The ExprIds from the left hand side. + * @param right_expr_ids The ExprIds from the right hand side. * @return The corresponding Predicate in the execution expression system. */ - Predicate* convertPredicate(const expressions::PredicatePtr &optimizer_predicate) const; + Predicate* convertPredicate( + const expressions::PredicatePtr &optimizer_predicate, + const std::unordered_set<expressions::ExprId> &left_expr_ids = + std::unordered_set<expressions::ExprId>(), + const std::unordered_set<expressions::ExprId> &right_expr_ids = + std::unordered_set<expressions::ExprId>()) const; /** * @brief Drops all temporary relations created by the generator http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/query_optimizer/expressions/Alias.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/Alias.cpp b/query_optimizer/expressions/Alias.cpp index f2b2795..0e3541d 100644 --- a/query_optimizer/expressions/Alias.cpp +++ b/query_optimizer/expressions/Alias.cpp @@ -21,6 +21,7 @@ #include <string> #include <unordered_map> +#include <unordered_set> #include <vector> #include "catalog/CatalogTypedefs.hpp" @@ -65,7 +66,9 @@ ExpressionPtr Alias::copyWithNewChildren( } ::quickstep::Scalar *Alias::concretize( - const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const { + const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map, + const std::unordered_set<ExprId> &left_expr_ids, + const std::unordered_set<ExprId> &right_expr_ids) const { // Alias should be converted to a CatalogAttribute. LOG(FATAL) << "Cannot concretize Alias to a scalar for evaluation"; } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/query_optimizer/expressions/Alias.hpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/Alias.hpp b/query_optimizer/expressions/Alias.hpp index e0ee959..16d3715 100644 --- a/query_optimizer/expressions/Alias.hpp +++ b/query_optimizer/expressions/Alias.hpp @@ -23,6 +23,7 @@ #include <memory> #include <string> #include <unordered_map> +#include <unordered_set> #include <vector> #include "query_optimizer/OptimizerTree.hpp" @@ -81,7 +82,9 @@ class Alias : public NamedExpression { } ::quickstep::Scalar *concretize( - const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const override; + const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map, + const std::unordered_set<ExprId> &left_expr_ids = std::unordered_set<ExprId>(), + const std::unordered_set<ExprId> &right_expr_ids = std::unordered_set<ExprId>()) const override; /** * @brief Creates an immutable Alias. If \p expression is also an Alias, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/query_optimizer/expressions/AttributeReference.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/AttributeReference.cpp b/query_optimizer/expressions/AttributeReference.cpp index facfb39..86a1711 100644 --- a/query_optimizer/expressions/AttributeReference.cpp +++ b/query_optimizer/expressions/AttributeReference.cpp @@ -23,8 +23,10 @@ #include <functional> #include <string> #include <unordered_map> +#include <unordered_set> #include <vector> +#include "expressions/scalar/Scalar.hpp" #include "expressions/scalar/ScalarAttribute.hpp" #include "query_optimizer/expressions/ExprId.hpp" #include "query_optimizer/expressions/Expression.hpp" @@ -53,11 +55,22 @@ std::vector<AttributeReferencePtr> AttributeReference::getReferencedAttributes() } ::quickstep::Scalar *AttributeReference::concretize( - const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const { + const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map, + const std::unordered_set<ExprId> &left_expr_ids, + const std::unordered_set<ExprId> &right_expr_ids) const { + const ExprId expr_id = id(); const std::unordered_map<ExprId, const CatalogAttribute*>::const_iterator found_it = - substitution_map.find(id()); + substitution_map.find(expr_id); DCHECK(found_it != substitution_map.end()) << toString(); - return new ::quickstep::ScalarAttribute(*found_it->second); + + ::quickstep::Scalar::JoinSide join_side = ::quickstep::Scalar::kNone; + if (left_expr_ids.find(expr_id) != left_expr_ids.end()) { + join_side = ::quickstep::Scalar::kLeftSide; + } else if (right_expr_ids.find(expr_id) != right_expr_ids.end()) { + join_side = ::quickstep::Scalar::kRightSide; + } + + return new ::quickstep::ScalarAttribute(*found_it->second, join_side); } std::size_t AttributeReference::computeHash() const { http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/8b7c3801/query_optimizer/expressions/AttributeReference.hpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/AttributeReference.hpp b/query_optimizer/expressions/AttributeReference.hpp index ca796ba..0a8b855 100644 --- a/query_optimizer/expressions/AttributeReference.hpp +++ b/query_optimizer/expressions/AttributeReference.hpp @@ -24,6 +24,7 @@ #include <memory> #include <string> #include <unordered_map> +#include <unordered_set> #include <vector> #include "catalog/CatalogTypedefs.hpp" @@ -88,7 +89,9 @@ class AttributeReference : public NamedExpression { std::vector<AttributeReferencePtr> getReferencedAttributes() const override; ::quickstep::Scalar* concretize( - const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const override; + const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map, + const std::unordered_set<ExprId> &left_expr_ids = std::unordered_set<ExprId>(), + const std::unordered_set<ExprId> &right_expr_ids = std::unordered_set<ExprId>()) const override; bool equals(const ScalarPtr &other) const override;