25 const std::shared_ptr<RelFilter>& filter,
26 std::vector<std::shared_ptr<const RelAlgNode>> inputs,
27 std::vector<std::shared_ptr<const RelJoin>>& original_joins)
28 : condition_(filter ? filter->getAndReleaseCondition() : nullptr)
29 , original_filter_(filter)
30 , original_joins_(original_joins) {
31 std::vector<std::unique_ptr<const RexScalar>> operands;
32 bool is_notnull =
true;
35 outer_conditions_per_level_.resize(original_joins.size());
36 for (
size_t nesting_level = 0; nesting_level < original_joins.size(); ++nesting_level) {
37 const auto& original_join = original_joins[nesting_level];
38 const auto condition_true =
39 dynamic_cast<const RexLiteral*
>(original_join->getCondition());
40 if (!condition_true || !condition_true->getVal<
bool>()) {
41 if (dynamic_cast<const RexOperator*>(original_join->getCondition())) {
43 is_notnull &&
dynamic_cast<const RexOperator*
>(original_join->getCondition())
47 switch (original_join->getJoinType()) {
51 if (original_join->getCondition()) {
52 operands.emplace_back(original_join->getAndReleaseCondition());
57 if (original_join->getCondition()) {
58 outer_conditions_per_level_[nesting_level].reset(
59 original_join->getAndReleaseCondition());
68 if (!operands.empty()) {
70 CHECK(dynamic_cast<const RexOperator*>(condition_.get()));
73 static_cast<const RexOperator*
>(condition_.get())->getType().get_notnull();
74 operands.emplace_back(std::move(condition_));
76 if (operands.size() > 1) {
80 condition_ = std::move(operands.front());
86 for (
const auto& input : inputs) {
87 addManagedInput(input);
96 const size_t nesting_level)
const {
114 for (
const auto& input :
inputs_) {
115 ret +=
" " + input->toString(config);
118 ret +=
", input node id={";
133 boost::hash_combine(*
hash_, expr ? expr->toHash() :
HASH_N);
137 boost::hash_combine(*
hash_, node->toHash());
144 size_t total_size = 0;
145 for (
const auto& input :
inputs_) {
146 total_size += input->size();
161 if (original_join.get() == node) {
174 std::vector<std::shared_ptr<const RelJoin>> original_joins;
176 return original_joins;
182 std::deque<std::shared_ptr<const RelAlgNode>>& inputs,
183 std::vector<std::shared_ptr<const RelJoin>>& original_joins,
184 const std::shared_ptr<const RelJoin>&
join) {
185 original_joins.push_back(join);
186 CHECK_EQ(
size_t(2), join->inputCount());
187 const auto left_input_join =
188 std::dynamic_pointer_cast<
const RelJoin>(join->getAndOwnInput(0));
189 if (left_input_join) {
190 inputs.push_front(join->getAndOwnInput(1));
193 inputs.push_front(join->getAndOwnInput(1));
194 inputs.push_front(join->getAndOwnInput(0));
198 std::pair<std::shared_ptr<RelLeftDeepInnerJoin>, std::shared_ptr<const RelAlgNode>>
202 return {
nullptr,
nullptr};
204 std::deque<std::shared_ptr<const RelAlgNode>> inputs_deque;
205 const auto left_deep_join_filter =
206 std::dynamic_pointer_cast<
RelFilter>(left_deep_join_root);
208 std::dynamic_pointer_cast<
const RelJoin>(left_deep_join_root->getAndOwnInput(0));
210 std::vector<std::shared_ptr<const RelJoin>> original_joins;
212 std::vector<std::shared_ptr<const RelAlgNode>> inputs(inputs_deque.begin(),
214 return {std::make_shared<RelLeftDeepInnerJoin>(
215 left_deep_join_filter, inputs, original_joins),
222 : left_deep_join_(left_deep_join) {
223 std::vector<size_t> input_sizes;
225 for (
size_t i = 0; i < left_deep_join->
inputCount(); ++i) {
226 input_sizes.push_back(left_deep_join->
getInput(i)->
size());
228 input_size_prefix_sums_.resize(input_sizes.size());
230 input_sizes.begin(), input_sizes.end(), input_size_prefix_sums_.begin());
235 if (left_deep_join_->coversOriginalNode(source_node)) {
237 input_size_prefix_sums_.end(),
239 std::less_equal<size_t>());
240 CHECK(it != input_size_prefix_sums_.end());
241 const auto input_node =
242 left_deep_join_->getInput(std::distance(input_size_prefix_sums_.begin(), it));
243 if (it != input_size_prefix_sums_.begin()) {
244 const auto prev_input_count = *(it - 1);
246 const auto input_index = rex_input->
getIndex() - prev_input_count;
255 std::vector<size_t> input_size_prefix_sums_;
265 const std::shared_ptr<RelAlgNode>& node) {
266 const auto left_deep_join_filter =
dynamic_cast<const RelFilter*
>(node.get());
267 if (left_deep_join_filter) {
268 const auto join =
dynamic_cast<const RelJoin*
>(left_deep_join_filter->getInput(0));
277 if (!node || node->inputCount() != 1) {
280 const auto join =
dynamic_cast<const RelJoin*
>(node->getInput(0));
289 RebindRexInputsFromLeftDeepJoin rebind_rex_inputs_from_left_deep_join(left_deep_join);
290 rebind_rex_inputs_from_left_deep_join.visit(rex);
294 std::list<std::shared_ptr<RelAlgNode>> new_nodes;
295 for (
auto& left_deep_join_candidate : nodes) {
296 std::shared_ptr<RelLeftDeepInnerJoin> left_deep_join;
297 std::shared_ptr<const RelAlgNode> old_root;
299 if (!left_deep_join) {
302 CHECK_GE(left_deep_join->inputCount(), size_t(2));
303 for (
size_t nesting_level = 1; nesting_level <= left_deep_join->inputCount() - 1;
305 const auto outer_condition = left_deep_join->getOuterCondition(nesting_level);
306 if (outer_condition) {
311 left_deep_join.get());
312 for (
auto& node : nodes) {
313 if (node && node->hasInput(old_root.get())) {
314 node->replaceInput(left_deep_join_candidate, left_deep_join);
315 std::shared_ptr<const RelJoin> old_join;
316 if (std::dynamic_pointer_cast<const RelJoin>(left_deep_join_candidate)) {
317 old_join = std::static_pointer_cast<
const RelJoin>(left_deep_join_candidate);
319 CHECK_EQ(
size_t(1), left_deep_join_candidate->inputCount());
320 old_join = std::dynamic_pointer_cast<
const RelJoin>(
321 left_deep_join_candidate->getAndOwnInput(0));
326 std::dynamic_pointer_cast<
const RelJoin>(old_join->getAndOwnInput(0));
331 new_nodes.emplace_back(std::move(left_deep_join));
337 nodes.insert(nodes.begin(), new_nodes.begin(), new_nodes.end());
std::vector< std::unique_ptr< const RexScalar > > outer_conditions_per_level_
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
size_t size() const override
std::shared_ptr< const RelAlgNode > get_left_deep_join_root(const std::shared_ptr< RelAlgNode > &node)
bool coversOriginalNode(const RelAlgNode *node) const
std::pair< std::shared_ptr< RelLeftDeepInnerJoin >, std::shared_ptr< const RelAlgNode > > create_left_deep_join(const std::shared_ptr< RelAlgNode > &left_deep_join_root)
const RexScalar * getOuterCondition(const size_t nesting_level) const
std::shared_ptr< RelFilter > original_filter_
std::vector< std::shared_ptr< const RelJoin > > original_joins_
std::shared_ptr< const RelAlgNode > getAndOwnInput(const size_t idx) const
RelLeftDeepInnerJoin()=default
std::shared_ptr< RelAlgNode > deepCopy() const override
DEVICE void partial_sum(ARGS &&...args)
const RelAlgNode * getInput(const size_t idx) const
std::vector< std::shared_ptr< const RelJoin > > getOriginalJoins() const
std::optional< size_t > hash_
DEVICE auto lower_bound(ARGS &&...args)
virtual size_t size() const =0
const RelFilter * getOriginalFilter() const
std::string typeName(const T *v)
std::unique_ptr< const RexScalar > condition_
const JoinType getJoinType(const size_t nesting_level) const
const RexScalar * getInnerCondition() const
void collect_left_deep_join_inputs(std::deque< std::shared_ptr< const RelAlgNode >> &inputs, std::vector< std::shared_ptr< const RelJoin >> &original_joins, const std::shared_ptr< const RelJoin > &join)
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
const size_t inputCount() const
void rebind_inputs_from_left_deep_join(const RexScalar *rex, const RelLeftDeepInnerJoin *left_deep_join)
size_t toHash() const override