blob: 417bc1708c3139e6b667d53a287feae442afcfab [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* License); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "expression.h"
#include "reader/filter/and_filter.h"
#include "reader/filter/or_filter.h"
namespace storage {
void QueryExpression::add_time_filter_to_series_filter(
Filter *time_filter, Expression *single_series_expr) {
Filter *filter = new AndFilter(single_series_expr->filter_, time_filter);
single_series_expr->filter_ = filter;
my_filters_.push_back(filter);
}
void QueryExpression::add_time_filter_to_query_filter(Filter *time_filter,
Expression *expression) {
if (expression->type_ == SERIES_EXPR) {
add_time_filter_to_series_filter(time_filter, expression);
} else if ((expression->type_ == AND_EXPR) ||
(expression->type_ == OR_EXPR)) {
add_time_filter_to_query_filter(time_filter, expression->left_);
add_time_filter_to_query_filter(time_filter, expression->right_);
} else {
std::cout << "Expression should contains only SingleSeriesExpression "
"but other type is found"
<< std::endl;
}
}
Expression *QueryExpression::combine_two_global_time_filter(
Expression *left, Expression *right, ExpressionType type) {
if (type == AND_EXPR) {
Filter *filter = new AndFilter(left->filter_, right->filter_);
Expression *expr = new Expression(GLOBALTIME_EXPR, filter);
my_filters_.push_back(filter);
my_exprs_.push_back(expr);
return expr;
} else if (type == OR_EXPR) {
Filter *filter = new OrFilter(left->filter_, right->filter_);
Expression *expr = new Expression(GLOBALTIME_EXPR, filter);
my_filters_.push_back(filter);
my_exprs_.push_back(expr);
return expr;
}
std::cout << "unrecognized QueryFilterOperatorType :" << type << std::endl;
return nullptr;
}
bool QueryExpression::update_filter_with_or(Expression *expression,
Filter *filter, Path &path) {
if (expression->type_ == SERIES_EXPR && expression->series_path_ == path) {
Filter *node_filter = expression->filter_;
node_filter = new OrFilter(node_filter, filter);
my_filters_.push_back(node_filter);
expression->filter_ = node_filter;
return true;
} else if (expression->type_ == OR_EXPR) {
Expression *left = expression->left_;
Expression *right = expression->right_;
return update_filter_with_or(left, filter, path) ||
update_filter_with_or(right, filter, path);
} else {
return false;
}
}
Expression *QueryExpression::merge_second_tree_to_first_tree(
Expression *left_expression, Expression *right_expression) {
if (right_expression->type_ == SERIES_EXPR) {
Expression *leaf = right_expression;
update_filter_with_or(left_expression, leaf->filter_,
leaf->series_path_);
return left_expression;
} else if (right_expression->type_ == OR_EXPR) {
Expression *left_child = right_expression->left_;
Expression *right_child = right_expression->right_;
left_expression =
merge_second_tree_to_first_tree(left_expression, left_child);
left_expression =
merge_second_tree_to_first_tree(left_expression, right_child);
return left_expression;
} else {
Expression *expr =
new Expression(OR_EXPR, left_expression, right_expression);
my_exprs_.push_back(expr);
return expr;
}
}
Expression *QueryExpression::push_global_time_filter_to_all_series(
Expression *time_filter, std::vector<Path> &selected_series) {
if (selected_series.size() == 0) {
std::cout << "size of selectSeries could not be 0" << std::endl;
}
Expression *expression = new Expression(SERIES_EXPR, selected_series.at(0),
time_filter->filter_);
my_exprs_.push_back(expression);
for (uint32_t i = 1; i < selected_series.size(); i++) {
Expression *r = new Expression(SERIES_EXPR, selected_series.at(i),
time_filter->filter_);
expression = new Expression(OR_EXPR, expression, r);
my_exprs_.push_back(r);
my_exprs_.push_back(expression);
}
return expression;
}
Expression *QueryExpression::handle_one_global_time_filter(
Expression *left, Expression *expression,
std::vector<Path> &selected_series, ExpressionType type) {
Expression *expr = optimize(expression, selected_series);
if (expr->type_ == GLOBALTIME_EXPR) {
return combine_two_global_time_filter(left, expr, type);
}
if (type == AND_EXPR) {
add_time_filter_to_query_filter(left->filter_, expr);
return expr;
} else if (type == OR_EXPR) {
Expression *after_transform =
push_global_time_filter_to_all_series(left, selected_series);
return merge_second_tree_to_first_tree(after_transform, expr);
}
std::cout << "unknown relation in Expression:" << type << std::endl;
return nullptr;
}
Expression *QueryExpression::optimize(Expression *expression,
std::vector<Path> &series_paths) {
ExpressionType type = expression->type_;
if (type == GLOBALTIME_EXPR || type == SERIES_EXPR) {
return expression;
} else if (type == AND_EXPR || type == OR_EXPR) {
Expression *left = expression->left_;
Expression *right = expression->right_;
if (left->type_ == GLOBALTIME_EXPR && right->type_ == GLOBALTIME_EXPR) {
return combine_two_global_time_filter(left, right, type);
} else if (left->type_ == GLOBALTIME_EXPR &&
right->type_ != GLOBALTIME_EXPR) {
return handle_one_global_time_filter(left, right, series_paths,
type);
} else if (left->type_ != GLOBALTIME_EXPR &&
right->type_ == GLOBALTIME_EXPR) {
return handle_one_global_time_filter(right, left, series_paths,
type);
} else if (left->type_ != GLOBALTIME_EXPR &&
right->type_ != GLOBALTIME_EXPR) {
Expression *regular_left = optimize(left, series_paths);
Expression *regular_right = optimize(right, series_paths);
Expression *mid_ret = nullptr;
if (type == AND_EXPR) {
mid_ret = new Expression(AND_EXPR, regular_left, regular_right);
my_exprs_.push_back(mid_ret);
} else if (type == OR_EXPR) {
mid_ret = new Expression(OR_EXPR, regular_left, regular_right);
my_exprs_.push_back(mid_ret);
} else {
std::cout << "unsupported Expression type:" << type
<< std::endl;
}
if (mid_ret->left_->type_ == GLOBALTIME_EXPR ||
mid_ret->right_->type_ == GLOBALTIME_EXPR) {
return optimize(mid_ret, series_paths);
} else {
return mid_ret;
}
}
} else {
std::cout << "unknown Expression type:" << type << std::endl;
}
return nullptr;
}
void QueryExpression::destory() {
for (size_t i = 0; i < my_exprs_.size(); i++) {
delete my_exprs_[i];
my_exprs_[i] = nullptr;
}
my_exprs_.clear();
for (size_t i = 0; i < my_filters_.size(); i++) {
delete my_filters_[i];
my_filters_[i] = nullptr;
}
if (expression_ != nullptr) {
delete expression_;
expression_ = nullptr;
}
my_filters_.clear();
}
} // namespace storage