QUICKSTEP-121: Added the self-join support.
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 @@
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(
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 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;
}
}
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::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(
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 @@
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,
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::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 @@
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;
}
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 @@
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,
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::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 @@
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;
}
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 @@
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,
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::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));
}
}
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 @@
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,
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 @@
* @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 @@
// 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;
/**
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 @@
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 @@
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;
}
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 @@
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 @@
* @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 @@
}
/**
- * @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 @@
* @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 @@
* 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 @@
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);
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 @@
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::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 @@
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::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 @@
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
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 @@
* @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 @@
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;
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::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::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 @@
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 @@
#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 @@
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 @@
#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 @@
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 @@
}
#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 @@
*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 @@
#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));
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 @@
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 @@
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;
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::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::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 @@
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 @@
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 @@
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 @@
}
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
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 @@
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 @@
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;
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::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 {
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 @@
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 @@
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;
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::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::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 @@
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);
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 @@
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 @@
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;
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::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::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 @@
#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 @@
#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));
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 @@
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 @@
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;
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
// 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 @@
// 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 @@
// 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 */));
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::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 @@
// 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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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
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 @@
* @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 @@
* 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
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 @@
}
::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";
}
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 @@
}
::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,
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 @@
}
::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 {
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 @@
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;
diff --git a/query_optimizer/expressions/BinaryExpression.cpp b/query_optimizer/expressions/BinaryExpression.cpp
index 07eb5ff..af4929c 100644
--- a/query_optimizer/expressions/BinaryExpression.cpp
+++ b/query_optimizer/expressions/BinaryExpression.cpp
@@ -23,6 +23,7 @@
#include <cstddef>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
@@ -101,11 +102,13 @@
}
::quickstep::Scalar *BinaryExpression::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 {
return new ::quickstep::ScalarBinaryExpression(
operation_,
- left_->concretize(substitution_map),
- right_->concretize(substitution_map));
+ left_->concretize(substitution_map, left_expr_ids, right_expr_ids),
+ right_->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
std::size_t BinaryExpression::computeHash() const {
diff --git a/query_optimizer/expressions/BinaryExpression.hpp b/query_optimizer/expressions/BinaryExpression.hpp
index df7454c..92419f6 100644
--- a/query_optimizer/expressions/BinaryExpression.hpp
+++ b/query_optimizer/expressions/BinaryExpression.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -88,7 +89,9 @@
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;
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index 7032f05..03a8247 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -79,6 +79,7 @@
target_link_libraries(quickstep_queryoptimizer_expressions_AttributeReference
glog
quickstep_catalog_CatalogTypedefs
+ quickstep_expressions_scalar_Scalar
quickstep_expressions_scalar_ScalarAttribute
quickstep_queryoptimizer_expressions_ExprId
quickstep_queryoptimizer_expressions_Expression
diff --git a/query_optimizer/expressions/Cast.cpp b/query_optimizer/expressions/Cast.cpp
index e6eb1bd..c5d8f94 100644
--- a/query_optimizer/expressions/Cast.cpp
+++ b/query_optimizer/expressions/Cast.cpp
@@ -22,6 +22,7 @@
#include <cstddef>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/scalar/Scalar.hpp"
@@ -52,9 +53,12 @@
}
::quickstep::Scalar *Cast::concretize(
- const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
- return new ::quickstep::ScalarUnaryExpression(::quickstep::NumericCastOperation::Instance(target_type_),
- operand_->concretize(substitution_map));
+ 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 {
+ return new ::quickstep::ScalarUnaryExpression(
+ ::quickstep::NumericCastOperation::Instance(target_type_),
+ operand_->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
std::size_t Cast::computeHash() const {
diff --git a/query_optimizer/expressions/Cast.hpp b/query_optimizer/expressions/Cast.hpp
index fa40242..2e7ea96 100644
--- a/query_optimizer/expressions/Cast.hpp
+++ b/query_optimizer/expressions/Cast.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -76,7 +77,9 @@
const std::vector<ExpressionPtr> &new_children) 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;
diff --git a/query_optimizer/expressions/CommonSubexpression.cpp b/query_optimizer/expressions/CommonSubexpression.cpp
index 4b13a0e..dcd3f1f 100644
--- a/query_optimizer/expressions/CommonSubexpression.cpp
+++ b/query_optimizer/expressions/CommonSubexpression.cpp
@@ -22,6 +22,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/scalar/ScalarSharedExpression.hpp"
@@ -47,10 +48,12 @@
}
::quickstep::Scalar* CommonSubexpression::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 {
return new ::quickstep::ScalarSharedExpression(
static_cast<int>(common_subexpression_id_),
- operand_->concretize(substitution_map));
+ operand_->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
void CommonSubexpression::getFieldStringItems(
diff --git a/query_optimizer/expressions/CommonSubexpression.hpp b/query_optimizer/expressions/CommonSubexpression.hpp
index 2c2d86c..f0482c9 100644
--- a/query_optimizer/expressions/CommonSubexpression.hpp
+++ b/query_optimizer/expressions/CommonSubexpression.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/expressions/AttributeReference.hpp"
@@ -93,7 +94,9 @@
}
::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 CommonSubexpression.
diff --git a/query_optimizer/expressions/ComparisonExpression.cpp b/query_optimizer/expressions/ComparisonExpression.cpp
index 8d93794..5529eef 100644
--- a/query_optimizer/expressions/ComparisonExpression.cpp
+++ b/query_optimizer/expressions/ComparisonExpression.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/predicate/ComparisonPredicate.hpp"
@@ -80,11 +81,13 @@
}
::quickstep::Predicate* ComparisonExpression::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 {
return new ::quickstep::ComparisonPredicate(
comparison_,
- left_->concretize(substitution_map),
- right_->concretize(substitution_map));
+ left_->concretize(substitution_map, left_expr_ids, right_expr_ids),
+ right_->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
void ComparisonExpression::getFieldStringItems(
diff --git a/query_optimizer/expressions/ComparisonExpression.hpp b/query_optimizer/expressions/ComparisonExpression.hpp
index f119f71..26d44fc 100644
--- a/query_optimizer/expressions/ComparisonExpression.hpp
+++ b/query_optimizer/expressions/ComparisonExpression.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -89,7 +90,9 @@
std::vector<AttributeReferencePtr> getReferencedAttributes() const override;
::quickstep::Predicate* 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 ComparisonExpression.
diff --git a/query_optimizer/expressions/Exists.cpp b/query_optimizer/expressions/Exists.cpp
index bf4cb72..792704b 100644
--- a/query_optimizer/expressions/Exists.cpp
+++ b/query_optimizer/expressions/Exists.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
@@ -38,7 +39,9 @@
namespace expressions {
::quickstep::Predicate* Exists::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 {
LOG(FATAL) << "Exists predicate should not be concretized";
return nullptr;
}
diff --git a/query_optimizer/expressions/Exists.hpp b/query_optimizer/expressions/Exists.hpp
index e90348e..7f1046d 100644
--- a/query_optimizer/expressions/Exists.hpp
+++ b/query_optimizer/expressions/Exists.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -86,7 +87,9 @@
}
::quickstep::Predicate* 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 Create an Exists predicate expression.
diff --git a/query_optimizer/expressions/InTableQuery.cpp b/query_optimizer/expressions/InTableQuery.cpp
index 79018e5..29d8a4e 100644
--- a/query_optimizer/expressions/InTableQuery.cpp
+++ b/query_optimizer/expressions/InTableQuery.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -33,7 +34,9 @@
namespace expressions {
::quickstep::Predicate* InTableQuery::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 {
LOG(FATAL) << "InTableQuery predicate should not be concretized";
}
diff --git a/query_optimizer/expressions/InTableQuery.hpp b/query_optimizer/expressions/InTableQuery.hpp
index 245ff0d..bb659fb 100644
--- a/query_optimizer/expressions/InTableQuery.hpp
+++ b/query_optimizer/expressions/InTableQuery.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -96,7 +97,9 @@
}
::quickstep::Predicate* 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 Create an IN predicate with a subquery.
diff --git a/query_optimizer/expressions/InValueList.cpp b/query_optimizer/expressions/InValueList.cpp
index d968d48..55f65b1 100644
--- a/query_optimizer/expressions/InValueList.cpp
+++ b/query_optimizer/expressions/InValueList.cpp
@@ -22,6 +22,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/predicate/DisjunctionPredicate.hpp"
@@ -40,7 +41,9 @@
namespace expressions {
::quickstep::Predicate* InValueList::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 {
std::unique_ptr<quickstep::DisjunctionPredicate>
disjunction_predicate(new quickstep::DisjunctionPredicate());
for (const ScalarPtr &match_expression : match_expressions_) {
@@ -51,7 +54,7 @@
match_expression);
disjunction_predicate->addPredicate(
- match_predicate->concretize(substitution_map));
+ match_predicate->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
return disjunction_predicate.release();
}
diff --git a/query_optimizer/expressions/InValueList.hpp b/query_optimizer/expressions/InValueList.hpp
index e0f1f57..3d37352 100644
--- a/query_optimizer/expressions/InValueList.hpp
+++ b/query_optimizer/expressions/InValueList.hpp
@@ -24,6 +24,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -109,7 +110,9 @@
}
::quickstep::Predicate* 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 Create an IN predicate with a value list.
diff --git a/query_optimizer/expressions/LogicalAnd.cpp b/query_optimizer/expressions/LogicalAnd.cpp
index a3908bd..9bcc02c 100644
--- a/query_optimizer/expressions/LogicalAnd.cpp
+++ b/query_optimizer/expressions/LogicalAnd.cpp
@@ -22,6 +22,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/predicate/ConjunctionPredicate.hpp"
@@ -86,13 +87,15 @@
}
::quickstep::Predicate* LogicalAnd::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 {
if (operands_.empty()) {
return new TruePredicate();
}
if (operands_.size() == 1u) {
- return operands_[0]->concretize(substitution_map);
+ return operands_[0]->concretize(substitution_map, left_expr_ids, right_expr_ids);
}
std::unique_ptr<::quickstep::ConjunctionPredicate> concretized_predicate;
@@ -100,7 +103,7 @@
for (const PredicatePtr &operand : operands_) {
concretized_predicate->addPredicate(
- operand->concretize(substitution_map));
+ operand->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
return concretized_predicate.release();
diff --git a/query_optimizer/expressions/LogicalAnd.hpp b/query_optimizer/expressions/LogicalAnd.hpp
index 8785fc8..93dc39c 100644
--- a/query_optimizer/expressions/LogicalAnd.hpp
+++ b/query_optimizer/expressions/LogicalAnd.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -88,7 +89,9 @@
std::vector<AttributeReferencePtr> getReferencedAttributes() const override;
::quickstep::Predicate* 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 LogicalAnd. If any operand is also a LogicalAnd,
diff --git a/query_optimizer/expressions/LogicalNot.cpp b/query_optimizer/expressions/LogicalNot.cpp
index dce13a9..a6ccbd2 100644
--- a/query_optimizer/expressions/LogicalNot.cpp
+++ b/query_optimizer/expressions/LogicalNot.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/predicate/NegationPredicate.hpp"
@@ -44,9 +45,11 @@
}
::quickstep::Predicate* LogicalNot::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 {
return new ::quickstep::NegationPredicate(
- operand_->concretize(substitution_map));
+ operand_->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
void LogicalNot::getFieldStringItems(
diff --git a/query_optimizer/expressions/LogicalNot.hpp b/query_optimizer/expressions/LogicalNot.hpp
index 7c4e660..9d773c5 100644
--- a/query_optimizer/expressions/LogicalNot.hpp
+++ b/query_optimizer/expressions/LogicalNot.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -73,7 +74,9 @@
}
::quickstep::Predicate* 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 LogicalNot.
diff --git a/query_optimizer/expressions/LogicalOr.cpp b/query_optimizer/expressions/LogicalOr.cpp
index c89fd5a..4126493 100644
--- a/query_optimizer/expressions/LogicalOr.cpp
+++ b/query_optimizer/expressions/LogicalOr.cpp
@@ -22,6 +22,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/predicate/DisjunctionPredicate.hpp"
@@ -84,13 +85,15 @@
}
::quickstep::Predicate* LogicalOr::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 {
if (operands_.empty()) {
return new FalsePredicate();
}
if (operands_.size() == 1u) {
- return operands_[0]->concretize(substitution_map);
+ return operands_[0]->concretize(substitution_map, left_expr_ids, right_expr_ids);
}
std::unique_ptr<::quickstep::DisjunctionPredicate> concretized_predicate;
@@ -98,7 +101,7 @@
for (const PredicatePtr &operand : operands_) {
concretized_predicate->addPredicate(
- operand->concretize(substitution_map));
+ operand->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
return concretized_predicate.release();
diff --git a/query_optimizer/expressions/LogicalOr.hpp b/query_optimizer/expressions/LogicalOr.hpp
index 2e40c56..52f9ad3 100644
--- a/query_optimizer/expressions/LogicalOr.hpp
+++ b/query_optimizer/expressions/LogicalOr.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -88,7 +89,9 @@
std::vector<AttributeReferencePtr> getReferencedAttributes() const override;
::quickstep::Predicate* 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 LogicalOr. If any operand is also a LogicalOr,
diff --git a/query_optimizer/expressions/Predicate.hpp b/query_optimizer/expressions/Predicate.hpp
index 444af6b..a0918e6 100644
--- a/query_optimizer/expressions/Predicate.hpp
+++ b/query_optimizer/expressions/Predicate.hpp
@@ -22,6 +22,7 @@
#include <memory>
#include <unordered_map>
+#include <unordered_set>
#include "query_optimizer/expressions/ExprId.hpp"
#include "query_optimizer/expressions/Expression.hpp"
@@ -70,10 +71,14 @@
*
* @param substitution_map Map from ExprId to CatalogAttribute for use in
* replacing AttributeReference.
+ * @param left_expr_ids The ExprIds from the left hand side.
+ * @param right_expr_ids The ExprIds from the right hand side.
* @return A concretized predicate for evaluation.
*/
virtual ::quickstep::Predicate* concretize(
- const std::unordered_map<ExprId, const CatalogAttribute*>& substitution_map) const = 0;
+ 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 = 0;
protected:
Predicate() {}
diff --git a/query_optimizer/expressions/PredicateLiteral.cpp b/query_optimizer/expressions/PredicateLiteral.cpp
index 724458e..fb48eb3 100644
--- a/query_optimizer/expressions/PredicateLiteral.cpp
+++ b/query_optimizer/expressions/PredicateLiteral.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/predicate/TrivialPredicates.hpp"
@@ -40,7 +41,9 @@
}
::quickstep::Predicate* PredicateLiteral::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 {
if (is_true()) {
return new TruePredicate();
} else {
diff --git a/query_optimizer/expressions/PredicateLiteral.hpp b/query_optimizer/expressions/PredicateLiteral.hpp
index f354a83..f53b6e3 100644
--- a/query_optimizer/expressions/PredicateLiteral.hpp
+++ b/query_optimizer/expressions/PredicateLiteral.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -70,7 +71,9 @@
}
::quickstep::Predicate* 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 PredicateLiteral.
diff --git a/query_optimizer/expressions/Scalar.hpp b/query_optimizer/expressions/Scalar.hpp
index a163b21..5635a10 100644
--- a/query_optimizer/expressions/Scalar.hpp
+++ b/query_optimizer/expressions/Scalar.hpp
@@ -23,6 +23,7 @@
#include <cstddef>
#include <memory>
#include <unordered_map>
+#include <unordered_set>
#include "query_optimizer/expressions/Expression.hpp"
#include "query_optimizer/expressions/ExprId.hpp"
@@ -61,11 +62,14 @@
* @param substitution_map Map from ExprId to CatalogAttribute for use in
* substituting CatalogAttribute for
* AttributeReference.
+ * @param left_expr_ids The ExprIds from the left hand side.
+ * @param right_expr_ids The ExprIds from the right hand side.
* @return Concretized expression for evaluation.
*/
virtual ::quickstep::Scalar* concretize(
- const std::unordered_map<ExprId, const CatalogAttribute*>& substitution_map)
- const = 0;
+ 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 = 0;
/**
* @brief Check whether this scalar is semantically equivalent to \p other.
diff --git a/query_optimizer/expressions/ScalarLiteral.cpp b/query_optimizer/expressions/ScalarLiteral.cpp
index d2ab527..3b1bef5 100644
--- a/query_optimizer/expressions/ScalarLiteral.cpp
+++ b/query_optimizer/expressions/ScalarLiteral.cpp
@@ -22,6 +22,7 @@
#include <cstddef>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/scalar/ScalarLiteral.hpp"
@@ -50,7 +51,9 @@
}
::quickstep::Scalar *ScalarLiteral::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 {
return new ::quickstep::ScalarLiteral(value_, value_type_);
}
diff --git a/query_optimizer/expressions/ScalarLiteral.hpp b/query_optimizer/expressions/ScalarLiteral.hpp
index 7fab1d0..fc5e09d 100644
--- a/query_optimizer/expressions/ScalarLiteral.hpp
+++ b/query_optimizer/expressions/ScalarLiteral.hpp
@@ -24,6 +24,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -80,7 +81,9 @@
}
::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;
diff --git a/query_optimizer/expressions/SearchedCase.cpp b/query_optimizer/expressions/SearchedCase.cpp
index c53e030..8e40b7b 100644
--- a/query_optimizer/expressions/SearchedCase.cpp
+++ b/query_optimizer/expressions/SearchedCase.cpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
@@ -114,15 +115,21 @@
}
::quickstep::Scalar* SearchedCase::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 {
std::vector<std::unique_ptr<quickstep::Predicate>> when_predicates;
+ when_predicates.reserve(condition_predicates_.size());
for (const PredicatePtr &predicate : condition_predicates_) {
- when_predicates.emplace_back(predicate->concretize(substitution_map));
+ when_predicates.emplace_back(
+ predicate->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
std::vector<std::unique_ptr<quickstep::Scalar>> result_expressions;
+ result_expressions.reserve(conditional_result_expressions_.size());
for (const ScalarPtr &expression : conditional_result_expressions_) {
- result_expressions.emplace_back(expression->concretize(substitution_map));
+ result_expressions.emplace_back(
+ expression->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
std::unique_ptr<quickstep::Scalar> else_result_expression;
@@ -131,14 +138,14 @@
new quickstep::ScalarLiteral(value_type_.makeNullValue(), value_type_));
} else {
else_result_expression.reset(
- else_result_expression_->concretize(substitution_map));
+ else_result_expression_->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
return new quickstep::ScalarCaseExpression(
value_type_,
std::move(when_predicates),
std::move(result_expressions),
- else_result_expression_->concretize(substitution_map));
+ else_result_expression_->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
void SearchedCase::getFieldStringItems(
diff --git a/query_optimizer/expressions/SearchedCase.hpp b/query_optimizer/expressions/SearchedCase.hpp
index 3466396..8744642 100644
--- a/query_optimizer/expressions/SearchedCase.hpp
+++ b/query_optimizer/expressions/SearchedCase.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/scalar/Scalar.hpp"
@@ -101,7 +102,9 @@
const std::vector<ExpressionPtr> &new_children) 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;
/**
* @brief Creates an immutable SearchedCase.
diff --git a/query_optimizer/expressions/SimpleCase.cpp b/query_optimizer/expressions/SimpleCase.cpp
index f11c8c8..21ee244 100644
--- a/query_optimizer/expressions/SimpleCase.cpp
+++ b/query_optimizer/expressions/SimpleCase.cpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
@@ -133,8 +134,11 @@
}
::quickstep::Scalar* SimpleCase::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 {
std::vector<std::unique_ptr<quickstep::Predicate>> when_predicates;
+ when_predicates.reserve(condition_operands_.size());
for (const ScalarPtr &condition_operand : condition_operands_) {
const PredicatePtr predicate =
ComparisonExpression::Create(
@@ -145,6 +149,7 @@
}
std::vector<std::unique_ptr<quickstep::Scalar>> result_expressions;
+ result_expressions.reserve(conditional_result_expressions_.size());
for (const ScalarPtr &expression : conditional_result_expressions_) {
result_expressions.emplace_back(expression->concretize(substitution_map));
}
diff --git a/query_optimizer/expressions/SimpleCase.hpp b/query_optimizer/expressions/SimpleCase.hpp
index b42c034..e05c4ef 100644
--- a/query_optimizer/expressions/SimpleCase.hpp
+++ b/query_optimizer/expressions/SimpleCase.hpp
@@ -24,6 +24,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/scalar/Scalar.hpp"
@@ -109,7 +110,9 @@
const std::vector<ExpressionPtr> &new_children) 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;
diff --git a/query_optimizer/expressions/SubqueryExpression.cpp b/query_optimizer/expressions/SubqueryExpression.cpp
index bc5a6d3..b6c4772 100644
--- a/query_optimizer/expressions/SubqueryExpression.cpp
+++ b/query_optimizer/expressions/SubqueryExpression.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/OptimizerTree.hpp"
@@ -38,7 +39,9 @@
namespace expressions {
::quickstep::Scalar* SubqueryExpression::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 {
LOG(FATAL) << "SubqueryExpression should not be concretized";
}
diff --git a/query_optimizer/expressions/SubqueryExpression.hpp b/query_optimizer/expressions/SubqueryExpression.hpp
index 184bc8c..96bf204 100644
--- a/query_optimizer/expressions/SubqueryExpression.hpp
+++ b/query_optimizer/expressions/SubqueryExpression.hpp
@@ -23,6 +23,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/expressions/AttributeReference.hpp"
@@ -87,7 +88,9 @@
}
::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 a subquery expression.
diff --git a/query_optimizer/expressions/UnaryExpression.cpp b/query_optimizer/expressions/UnaryExpression.cpp
index b448553..4d91e03 100644
--- a/query_optimizer/expressions/UnaryExpression.cpp
+++ b/query_optimizer/expressions/UnaryExpression.cpp
@@ -22,6 +22,7 @@
#include <cstddef>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expressions/scalar/ScalarUnaryExpression.hpp"
@@ -53,9 +54,11 @@
}
::quickstep::Scalar* UnaryExpression::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 {
return new ::quickstep::ScalarUnaryExpression(
- operation_, operand_->concretize(substitution_map));
+ operation_, operand_->concretize(substitution_map, left_expr_ids, right_expr_ids));
}
std::size_t UnaryExpression::computeHash() const {
diff --git a/query_optimizer/expressions/UnaryExpression.hpp b/query_optimizer/expressions/UnaryExpression.hpp
index 9b99377..314ad5d 100644
--- a/query_optimizer/expressions/UnaryExpression.hpp
+++ b/query_optimizer/expressions/UnaryExpression.hpp
@@ -24,6 +24,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "query_optimizer/expressions/AttributeReference.hpp"
@@ -84,7 +85,9 @@
}
::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;
diff --git a/query_optimizer/tests/execution_generator/Select.test b/query_optimizer/tests/execution_generator/Select.test
index 494e759..ee9c18e 100644
--- a/query_optimizer/tests/execution_generator/Select.test
+++ b/query_optimizer/tests/execution_generator/Select.test
@@ -269,7 +269,6 @@
+-----------+--------------------+
==
-# The execution engine currently does not support self-join.
SELECT a.int_col,
a.int_col*b.int_col,
b.long_col
@@ -277,7 +276,32 @@
test AS b
WHERE a.int_col*b.int_col = b.long_col;
--
-ERROR: NestedLoopsJoin does not support self-join yet
++-----------+---------------------+--------------------+
+|int_col |(a.int_col*b.int_col)|long_col |
++-----------+---------------------+--------------------+
+| -1| 1| 1|
+| 2| 4| 4|
+| -3| 9| 9|
+| 4| 16| 16|
+| -5| 25| 25|
+| 6| 36| 36|
+| -7| 49| 49|
+| 8| 64| 64|
+| -9| 81| 81|
+| -11| 121| 121|
+| 12| 144| 144|
+| -13| 169| 169|
+| 14| 196| 196|
+| -15| 225| 225|
+| 16| 256| 256|
+| -17| 289| 289|
+| 18| 324| 324|
+| -19| 361| 361|
+| -21| 441| 441|
+| 22| 484| 484|
+| -23| 529| 529|
+| 24| 576| 576|
++-----------+---------------------+--------------------+
==
# The nested loops join is not a self-join, because the predicate "a.int_col<10" is pushed under the join, which results
@@ -305,14 +329,38 @@
+-----------+---------------------+--------------------+
==
-# Hash join does not support the self-join.
SELECT a.int_col,
b.int_col
FROM test AS a,
test AS b
WHERE a.int_col = b.int_col;
--
-ERROR: Self-join is not supported
++-----------+-----------+
+|int_col |int_col |
++-----------+-----------+
+| -1| -1|
+| 2| 2|
+| -3| -3|
+| 4| 4|
+| -5| -5|
+| 6| 6|
+| -7| -7|
+| 8| 8|
+| -9| -9|
+| -11| -11|
+| 12| 12|
+| -13| -13|
+| 14| 14|
+| -15| -15|
+| 16| 16|
+| -17| -17|
+| 18| 18|
+| -19| -19|
+| -21| -21|
+| 22| 22|
+| -23| -23|
+| 24| 24|
++-----------+-----------+
==
# This is not a self-join, because there is a Select under the HashJoin for "a.long_col < 50".
diff --git a/relational_operators/HashJoinOperator.cpp b/relational_operators/HashJoinOperator.cpp
index 4083bd3..f08de9d 100644
--- a/relational_operators/HashJoinOperator.cpp
+++ b/relational_operators/HashJoinOperator.cpp
@@ -72,7 +72,7 @@
// Functor passed to HashTable::getAllFromValueAccessor() to collect matching
// tuples from the inner relation. It stores matching tuple ID pairs
// in an unordered_map keyed by inner block ID and a vector of
-// pairs of (build-tupleID, probe-tuple-ID).
+// pairs of (probe-tupleID, build-tuple-ID).
class VectorsOfPairsJoinedTuplesCollector {
public:
VectorsOfPairsJoinedTuplesCollector() {
@@ -81,7 +81,7 @@
template <typename ValueAccessorT>
inline void operator()(const ValueAccessorT &accessor,
const TupleReference &tref) {
- joined_tuples_[tref.block].emplace_back(tref.tuple, accessor.getCurrentPosition());
+ joined_tuples_[tref.block].emplace_back(accessor.getCurrentPosition(), tref.tuple);
}
// Get a mutable pointer to the collected map of joined tuple ID pairs. The
@@ -102,7 +102,7 @@
};
// Another collector using an unordered_map keyed on inner block just like above,
-// except that it uses of a pair of (build-tupleIDs-vector, probe-tuple-IDs-vector).
+// except that it uses of a pair of (probe-tupleIDs-vector, build-tuple-IDs-vector).
class PairsOfVectorsJoinedTuplesCollector {
public:
PairsOfVectorsJoinedTuplesCollector() {
@@ -112,8 +112,8 @@
inline void operator()(const ValueAccessorT &accessor,
const TupleReference &tref) {
auto &entry = joined_tuples_[tref.block];
- entry.first.emplace_back(tref.tuple);
- entry.second.emplace_back(accessor.getCurrentPosition());
+ entry.first.emplace_back(accessor.getCurrentPosition());
+ entry.second.emplace_back(tref.tuple);
}
// Get a mutable pointer to the collected map of joined tuple ID pairs. The
@@ -151,7 +151,8 @@
template <typename ValueAccessorT>
inline void operator()(const ValueAccessorT &accessor,
const TupleReference &tref) {
- joined_tuples_[tref.block].emplace_back(tref.tuple, accessor.getCurrentPosition());
+ // <probe-tid, build-tid>.
+ joined_tuples_[tref.block].emplace_back(accessor.getCurrentPosition(), tref.tuple);
}
template <typename ValueAccessorT>
@@ -165,7 +166,7 @@
}
private:
- std::unordered_map<block_id, std::vector<std::pair<tuple_id, tuple_id>>> joined_tuples_;
+ std::unordered_map<block_id, VectorOfTupleIdPair> joined_tuples_;
// BitVector on the probe relation. 1 if the corresponding tuple has no match.
TupleIdSequence *filter_;
};
@@ -490,9 +491,6 @@
&collector);
}
- const relation_id build_relation_id = build_relation_.getID();
- const relation_id probe_relation_id = probe_relation_.getID();
-
for (std::pair<const block_id, VectorOfTupleIdPair>
&build_block_entry : *collector.getJoinedTuples()) {
BlockReference build_block =
@@ -515,11 +513,9 @@
for (const std::pair<tuple_id, tuple_id> &hash_match
: build_block_entry.second) {
- if (residual_predicate_->matchesForJoinedTuples(*build_accessor,
- build_relation_id,
+ if (residual_predicate_->matchesForJoinedTuples(*probe_accessor,
hash_match.first,
- *probe_accessor,
- probe_relation_id,
+ *build_accessor,
hash_match.second)) {
filtered_matches.emplace_back(hash_match);
}
@@ -533,10 +529,8 @@
for (auto selection_cit = selection_.begin();
selection_cit != selection_.end();
++selection_cit) {
- temp_result.addColumn((*selection_cit)->getAllValuesForJoin(build_relation_id,
+ temp_result.addColumn((*selection_cit)->getAllValuesForJoin(probe_accessor,
build_accessor.get(),
- probe_relation_id,
- probe_accessor,
build_block_entry.second,
cv_cache.get()));
}
@@ -562,9 +556,6 @@
&collector);
}
- const relation_id build_relation_id = build_relation_.getID();
- const relation_id probe_relation_id = probe_relation_.getID();
-
constexpr std::size_t kNumIndexes = 3u;
constexpr std::size_t kBuildIndex = 0, kProbeIndex = 1u, kTempIndex = 2u;
@@ -584,11 +575,15 @@
accessor_attribute_map[kTempIndex].second[dest_attr] = non_trivial_expressions.size();
non_trivial_expressions.emplace_back(scalar.get());
} else {
- const CatalogAttribute &attr = static_cast<const ScalarAttribute *>(scalar.get())->getAttribute();
- const attribute_id attr_id = attr.getID();
- if (attr.getParent().getID() == build_relation_id) {
+ const Scalar::JoinSide join_side = scalar->join_side();
+ DCHECK(join_side != Scalar::kNone);
+
+ const attribute_id attr_id =
+ static_cast<const ScalarAttribute *>(scalar.get())->getAttribute().getID();
+ if (join_side == Scalar::kRightSide) {
accessor_attribute_map[kBuildIndex].second[dest_attr] = attr_id;
} else {
+ DCHECK(join_side == Scalar::kLeftSide);
accessor_attribute_map[kProbeIndex].second[dest_attr] = attr_id;
}
}
@@ -601,8 +596,8 @@
storage_manager_->getBlock(build_block_entry.first, build_relation_);
const TupleStorageSubBlock &build_store = build_block->getTupleStorageSubBlock();
std::unique_ptr<ValueAccessor> build_accessor(build_store.createValueAccessor());
- const std::vector<tuple_id> &build_tids = build_block_entry.second.first;
- const std::vector<tuple_id> &probe_tids = build_block_entry.second.second;
+ const std::vector<tuple_id> &build_tids = build_block_entry.second.second;
+ const std::vector<tuple_id> &probe_tids = build_block_entry.second.first;
// Evaluate '*residual_predicate_', if any.
//
@@ -618,14 +613,12 @@
PairOfTupleIdVector filtered_matches;
for (std::size_t i = 0; i < build_tids.size(); ++i) {
- if (residual_predicate_->matchesForJoinedTuples(*build_accessor,
- build_relation_id,
- build_tids[i],
- *probe_accessor,
- probe_relation_id,
- probe_tids[i])) {
- filtered_matches.first.emplace_back(build_tids[i]);
- filtered_matches.second.emplace_back(probe_tids[i]);
+ if (residual_predicate_->matchesForJoinedTuples(*probe_accessor,
+ probe_tids[i],
+ *build_accessor,
+ build_tids[i])) {
+ filtered_matches.first.emplace_back(probe_tids[i]);
+ filtered_matches.second.emplace_back(build_tids[i]);
}
}
@@ -646,15 +639,13 @@
// zip our two vectors together.
VectorOfTupleIdPair zipped_joined_tuple_ids;
for (std::size_t i = 0; i < build_tids.size(); ++i) {
- zipped_joined_tuple_ids.emplace_back(build_tids[i], probe_tids[i]);
+ zipped_joined_tuple_ids.emplace_back(probe_tids[i], build_tids[i]);
}
ColumnVectorCache cv_cache;
for (const Scalar *scalar : non_trivial_expressions) {
- temp_result.addColumn(scalar->getAllValuesForJoin(build_relation_id,
+ temp_result.addColumn(scalar->getAllValuesForJoin(probe_accessor,
build_accessor.get(),
- probe_relation_id,
- probe_accessor,
zipped_joined_tuple_ids,
&cv_cache));
}
@@ -690,9 +681,6 @@
}
void HashSemiJoinWorkOrder::executeWithResidualPredicate() {
- const relation_id build_relation_id = build_relation_.getID();
- const relation_id probe_relation_id = probe_relation_.getID();
-
BlockReference probe_block = storage_manager_->getBlock(block_id_,
probe_relation_);
const TupleStorageSubBlock &probe_store = probe_block->getTupleStorageSubBlock();
@@ -752,11 +740,9 @@
// probe side, skip it.
continue;
}
- if (residual_predicate_->matchesForJoinedTuples(*build_accessor,
- build_relation_id,
+ if (residual_predicate_->matchesForJoinedTuples(*probe_accessor,
hash_match.first,
- *probe_accessor,
- probe_relation_id,
+ *build_accessor,
hash_match.second)) {
filter.set(hash_match.second);
}
@@ -910,9 +896,6 @@
}
void HashAntiJoinWorkOrder::executeWithResidualPredicate() {
- const relation_id build_relation_id = build_relation_.getID();
- const relation_id probe_relation_id = probe_relation_.getID();
-
BlockReference probe_block = storage_manager_->getBlock(block_id_,
probe_relation_);
const TupleStorageSubBlock &probe_store = probe_block->getTupleStorageSubBlock();
@@ -970,11 +953,9 @@
// We have already seen this tuple, skip it.
continue;
}
- if (residual_predicate_->matchesForJoinedTuples(*build_accessor,
- build_relation_id,
+ if (residual_predicate_->matchesForJoinedTuples(*probe_accessor,
hash_match.first,
- *probe_accessor,
- probe_relation_id,
+ *build_accessor,
hash_match.second)) {
// Note that the existence map marks a match as false, as needed by the
// anti join definition.
@@ -1008,9 +989,6 @@
void HashOuterJoinWorkOrder::execute() {
output_destination_->setInputPartitionId(partition_id_);
- const relation_id build_relation_id = build_relation_.getID();
- const relation_id probe_relation_id = probe_relation_.getID();
-
const BlockReference probe_block = storage_manager_->getBlock(block_id_,
probe_relation_);
const TupleStorageSubBlock &probe_store = probe_block->getTupleStorageSubBlock();
@@ -1061,10 +1039,8 @@
++selection_it) {
temp_result.addColumn(
(*selection_it)->getAllValuesForJoin(
- build_relation_id,
- build_accessor.get(),
- probe_relation_id,
probe_accessor.get(),
+ build_accessor.get(),
build_block_entry.second,
cv_cache.get()));
}
diff --git a/relational_operators/NestedLoopsJoinOperator.cpp b/relational_operators/NestedLoopsJoinOperator.cpp
index 658f84b..8be9cb3 100644
--- a/relational_operators/NestedLoopsJoinOperator.cpp
+++ b/relational_operators/NestedLoopsJoinOperator.cpp
@@ -407,9 +407,6 @@
template <bool LEFT_PACKED, bool RIGHT_PACKED>
void NestedLoopsJoinWorkOrder::executeHelper(const TupleStorageSubBlock &left_store,
const TupleStorageSubBlock &right_store) {
- const relation_id left_input_relation_id = left_input_relation_.getID();
- const relation_id right_input_relation_id = right_input_relation_.getID();
-
const tuple_id left_max_tid = left_store.getMaxTupleID();
const tuple_id right_max_tid = right_store.getMaxTupleID();
@@ -428,10 +425,8 @@
if (RIGHT_PACKED || right_store.hasTupleWithID(right_tid)) {
// For each tuple in the right block...
if (join_predicate_->matchesForJoinedTuples(*left_accessor,
- left_input_relation_id,
left_tid,
*right_accessor,
- right_input_relation_id,
right_tid)) {
joined_tuple_ids.emplace_back(left_tid, right_tid);
}
@@ -460,9 +455,7 @@
for (vector<unique_ptr<const Scalar>>::const_iterator selection_cit = selection_.begin();
selection_cit != selection_.end();
++selection_cit) {
- temp_result.addColumn((*selection_cit)->getAllValuesForJoin(left_input_relation_id,
- left_accessor.get(),
- right_input_relation_id,
+ temp_result.addColumn((*selection_cit)->getAllValuesForJoin(left_accessor.get(),
right_accessor.get(),
joined_tuple_ids,
cv_cache.get()));
diff --git a/relational_operators/tests/HashJoinOperator_unittest.cpp b/relational_operators/tests/HashJoinOperator_unittest.cpp
index eeeca4b..1ea1a37 100644
--- a/relational_operators/tests/HashJoinOperator_unittest.cpp
+++ b/relational_operators/tests/HashJoinOperator_unittest.cpp
@@ -432,7 +432,7 @@
// Create the prober operator with one selection attribute.
const QueryContext::scalar_group_id selection_index = query_context_proto.scalar_groups_size();
- ScalarAttribute scalar_attr(dim_col_long);
+ ScalarAttribute scalar_attr(dim_col_long, Scalar::kRightSide);
query_context_proto.add_scalar_groups()->add_scalars()->MergeFrom(scalar_attr.getProto());
// Create result_table, owned by db_.
@@ -581,9 +581,9 @@
const QueryContext::scalar_group_id selection_index = query_context_proto.scalar_groups_size();
serialization::QueryContext::ScalarGroup *scalar_group_proto = query_context_proto.add_scalar_groups();
- ScalarAttribute scalar_attr_dim(dim_col_long);
+ ScalarAttribute scalar_attr_dim(dim_col_long, Scalar::kRightSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_dim.getProto());
- ScalarAttribute scalar_attr_fact(fact_col_long);
+ ScalarAttribute scalar_attr_fact(fact_col_long, Scalar::kLeftSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_fact.getProto());
// Create result_table, owned by db_.
@@ -745,7 +745,7 @@
// Create prober operator with one selection attribute.
const QueryContext::scalar_group_id selection_index = query_context_proto.scalar_groups_size();
- ScalarAttribute scalar_attr(dim_col_long);
+ ScalarAttribute scalar_attr(dim_col_long, Scalar::kRightSide);
query_context_proto.add_scalar_groups()->add_scalars()->MergeFrom(scalar_attr.getProto());
// Create result_table, owned by db_.
@@ -887,9 +887,9 @@
const QueryContext::scalar_group_id selection_index = query_context_proto.scalar_groups_size();
serialization::QueryContext::ScalarGroup *scalar_group_proto = query_context_proto.add_scalar_groups();
- ScalarAttribute scalar_attr_dim(dim_col_long);
+ ScalarAttribute scalar_attr_dim(dim_col_long, Scalar::kRightSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_dim.getProto());
- ScalarAttribute scalar_attr_fact(fact_col_long);
+ ScalarAttribute scalar_attr_fact(fact_col_long, Scalar::kLeftSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_fact.getProto());
// Create result_table, owned by db_.
@@ -1063,9 +1063,9 @@
const QueryContext::scalar_group_id selection_index = query_context_proto.scalar_groups_size();
serialization::QueryContext::ScalarGroup *scalar_group_proto = query_context_proto.add_scalar_groups();
- ScalarAttribute scalar_attr_dim(dim_col_long);
+ ScalarAttribute scalar_attr_dim(dim_col_long, Scalar::kRightSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_dim.getProto());
- ScalarAttribute scalar_attr_fact(fact_col_long);
+ ScalarAttribute scalar_attr_fact(fact_col_long, Scalar::kLeftSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_fact.getProto());
// Create result_table, owned by db_.
@@ -1244,9 +1244,9 @@
const QueryContext::scalar_group_id selection_index = query_context_proto.scalar_groups_size();
serialization::QueryContext::ScalarGroup *scalar_group_proto = query_context_proto.add_scalar_groups();
- ScalarAttribute scalar_attr_dim(dim_col_long);
+ ScalarAttribute scalar_attr_dim(dim_col_long, Scalar::kRightSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_dim.getProto());
- ScalarAttribute scalar_attr_fact(fact_col_long);
+ ScalarAttribute scalar_attr_fact(fact_col_long, Scalar::kLeftSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_fact.getProto());
// Create result_table, owned by db_.
@@ -1269,7 +1269,7 @@
unique_ptr<Predicate> residual_pred(new ComparisonPredicate(
ComparisonFactory::GetComparison(
ComparisonID::kLess),
- new ScalarAttribute(dim_col_long),
+ new ScalarAttribute(dim_col_long, Scalar::kRightSide),
new ScalarLiteral(TypedValue(static_cast<std::int64_t>(15)), LongType::InstanceNonNullable())));
std::vector<attribute_id> fact_key_attrs;
@@ -1436,7 +1436,7 @@
// Create the prober operator with one selection attribute.
const QueryContext::scalar_group_id selection_index = query_context_proto.scalar_groups_size();
- ScalarAttribute scalar_attr(dim_col_long);
+ ScalarAttribute scalar_attr(dim_col_long, Scalar::kRightSide);
query_context_proto.add_scalar_groups()->add_scalars()->MergeFrom(scalar_attr.getProto());
// Create result_table, owned by db_.
@@ -1580,9 +1580,9 @@
const QueryContext::scalar_group_id selection_index = query_context_proto.scalar_groups_size();
serialization::QueryContext::ScalarGroup *scalar_group_proto = query_context_proto.add_scalar_groups();
- ScalarAttribute scalar_attr_dim(dim_col_long);
+ ScalarAttribute scalar_attr_dim(dim_col_long, Scalar::kRightSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_dim.getProto());
- ScalarAttribute scalar_attr_fact(fact_col_long);
+ ScalarAttribute scalar_attr_fact(fact_col_long, Scalar::kLeftSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_fact.getProto());
// Create result_table, owned by db_.
@@ -1752,9 +1752,9 @@
const QueryContext::scalar_group_id selection_index = query_context_proto.scalar_groups_size();
serialization::QueryContext::ScalarGroup *scalar_group_proto = query_context_proto.add_scalar_groups();
- ScalarAttribute scalar_attr_dim(dim_col_long);
+ ScalarAttribute scalar_attr_dim(dim_col_long, Scalar::kRightSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_dim.getProto());
- ScalarAttribute scalar_attr_fact(fact_col_long);
+ ScalarAttribute scalar_attr_fact(fact_col_long, Scalar::kLeftSide);
scalar_group_proto->add_scalars()->MergeFrom(scalar_attr_fact.getProto());
// Create result_table, owned by db_.
@@ -1777,7 +1777,7 @@
unique_ptr<Predicate> residual_pred(new ComparisonPredicate(
ComparisonFactory::GetComparison(
ComparisonID::kLess),
- new ScalarAttribute(dim_col_long),
+ new ScalarAttribute(dim_col_long, Scalar::kRightSide),
new ScalarLiteral(TypedValue(static_cast<std::int64_t>(15)), LongType::InstanceNonNullable())));
const QueryContext::predicate_id residual_pred_index = query_context_proto.predicates_size();