2022-07-14 11:20:16 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <re2/re2.h>
|
|
|
|
|
|
|
|
#include <Analyzer/Identifier.h>
|
|
|
|
#include <Analyzer/IQueryTreeNode.h>
|
|
|
|
#include <Analyzer/ColumnTransformers.h>
|
|
|
|
#include <Parsers/ASTAsterisk.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
/** Matcher query tree node.
|
|
|
|
* Matcher can be unqualified with identifier and qualified with identifier.
|
|
|
|
* It can be asterisk or COLUMNS('regexp') or COLUMNS(column_name_1, ...).
|
|
|
|
* In result we have 6 possible options:
|
|
|
|
* Unqualified
|
|
|
|
* 1. *
|
|
|
|
* 2. COLUMNS('regexp')
|
|
|
|
* 3. COLUMNS(column_name_1, ...)
|
|
|
|
*
|
|
|
|
* Qualified:
|
|
|
|
* 1. identifier.*
|
|
|
|
* 2. identifier.COLUMNS('regexp')
|
|
|
|
* 3. identifier.COLUMNS(column_name_1, ...)
|
|
|
|
*
|
2022-10-19 10:25:27 +00:00
|
|
|
* Matcher must be resolved during query analysis pass.
|
2022-07-14 11:20:16 +00:00
|
|
|
*
|
2022-10-19 10:25:27 +00:00
|
|
|
* Matchers can be applied to compound expressions.
|
2022-07-14 11:20:16 +00:00
|
|
|
* Example: SELECT compound_column AS a, a.* FROM test_table.
|
|
|
|
* Example: SELECT compound_column.* FROM test_table.
|
|
|
|
*
|
2022-10-19 10:25:27 +00:00
|
|
|
* Example: SELECT * FROM test_table;
|
2022-07-14 11:20:16 +00:00
|
|
|
* Example: SELECT test_table.* FROM test_table.
|
|
|
|
* Example: SELECT a.* FROM test_table AS a.
|
|
|
|
*
|
2022-09-06 16:46:30 +00:00
|
|
|
* Additionally each matcher can contain transformers, check ColumnTransformers.h.
|
2022-07-14 11:20:16 +00:00
|
|
|
* In query tree matchers column transformers are represended as ListNode.
|
|
|
|
*/
|
|
|
|
enum class MatcherNodeType
|
|
|
|
{
|
|
|
|
ASTERISK,
|
|
|
|
COLUMNS_REGEXP,
|
|
|
|
COLUMNS_LIST
|
|
|
|
};
|
|
|
|
|
|
|
|
const char * toString(MatcherNodeType matcher_node_type);
|
|
|
|
|
|
|
|
class MatcherNode;
|
|
|
|
using MatcherNodePtr = std::shared_ptr<MatcherNode>;
|
|
|
|
|
|
|
|
class MatcherNode final : public IQueryTreeNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/// Variant unqualified asterisk
|
|
|
|
explicit MatcherNode(ColumnTransformersNodes column_transformers_ = {});
|
|
|
|
|
|
|
|
/// Variant qualified asterisk
|
|
|
|
explicit MatcherNode(Identifier qualified_identifier_, ColumnTransformersNodes column_transformers_ = {});
|
|
|
|
|
|
|
|
/// Variant unqualified COLUMNS('regexp')
|
|
|
|
explicit MatcherNode(std::shared_ptr<re2::RE2> columns_matcher_, ColumnTransformersNodes column_transformers_ = {});
|
|
|
|
|
|
|
|
/// Variant qualified COLUMNS('regexp')
|
|
|
|
explicit MatcherNode(Identifier qualified_identifier_, std::shared_ptr<re2::RE2> columns_matcher_, ColumnTransformersNodes column_transformers_ = {});
|
|
|
|
|
|
|
|
/// Variant unqualified COLUMNS(column_name_1, ...)
|
|
|
|
explicit MatcherNode(Identifiers columns_identifiers_, ColumnTransformersNodes column_transformers_ = {});
|
|
|
|
|
|
|
|
/// Variant qualified COLUMNS(column_name_1, ...)
|
|
|
|
explicit MatcherNode(Identifier qualified_identifier_, Identifiers columns_identifiers_, ColumnTransformersNodes column_transformers_ = {});
|
|
|
|
|
|
|
|
/// Get matcher type
|
|
|
|
MatcherNodeType getMatcherType() const
|
|
|
|
{
|
|
|
|
return matcher_type;
|
|
|
|
}
|
|
|
|
|
2022-10-19 10:25:27 +00:00
|
|
|
/// Returns true if matcher is asterisk matcher, false otherwise
|
2022-07-14 11:20:16 +00:00
|
|
|
bool isAsteriskMatcher() const
|
|
|
|
{
|
|
|
|
return matcher_type == MatcherNodeType::ASTERISK;
|
|
|
|
}
|
|
|
|
|
2022-10-19 10:25:27 +00:00
|
|
|
/// Returns true if matcher is columns regexp or columns list matcher, false otherwise
|
2022-07-14 11:20:16 +00:00
|
|
|
bool isColumnsMatcher() const
|
|
|
|
{
|
|
|
|
return matcher_type == MatcherNodeType::COLUMNS_REGEXP || matcher_type == MatcherNodeType::COLUMNS_LIST;
|
|
|
|
}
|
|
|
|
|
2022-10-19 10:25:27 +00:00
|
|
|
/// Returns true if matcher is qualified, false otherwise
|
2022-07-14 11:20:16 +00:00
|
|
|
bool isQualified() const
|
|
|
|
{
|
|
|
|
return !qualified_identifier.empty();
|
|
|
|
}
|
|
|
|
|
2022-10-19 10:25:27 +00:00
|
|
|
/// Returns true if matcher is not qualified, false otherwise
|
2022-08-31 15:21:17 +00:00
|
|
|
bool isUnqualified() const
|
|
|
|
{
|
|
|
|
return qualified_identifier.empty();
|
|
|
|
}
|
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
/// Get qualified identifier
|
|
|
|
const Identifier & getQualifiedIdentifier() const
|
|
|
|
{
|
|
|
|
return qualified_identifier;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get columns matcher. Valid only if this matcher has type COLUMNS_REGEXP.
|
|
|
|
const std::shared_ptr<re2::RE2> & getColumnsMatcher() const
|
|
|
|
{
|
|
|
|
return columns_matcher;
|
|
|
|
}
|
|
|
|
|
2022-10-19 10:25:27 +00:00
|
|
|
/// Get columns identifiers. Valid only if this matcher has type COLUMNS_LIST.
|
2022-07-14 11:20:16 +00:00
|
|
|
const Identifiers & getColumnsIdentifiers() const
|
|
|
|
{
|
|
|
|
return columns_identifiers;
|
|
|
|
}
|
|
|
|
|
2022-10-19 10:25:27 +00:00
|
|
|
/// Get column transformers
|
2022-07-14 11:20:16 +00:00
|
|
|
const ListNode & getColumnTransformers() const
|
|
|
|
{
|
|
|
|
return children[column_transformers_child_index]->as<const ListNode &>();
|
|
|
|
}
|
|
|
|
|
2022-10-19 10:25:27 +00:00
|
|
|
/// Get column transformers
|
2022-07-14 11:20:16 +00:00
|
|
|
const QueryTreeNodePtr & getColumnTransformersNode() const
|
|
|
|
{
|
|
|
|
return children[column_transformers_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns true if matcher match column name, false otherwise
|
|
|
|
bool isMatchingColumn(const std::string & column_name);
|
|
|
|
|
|
|
|
QueryTreeNodeType getNodeType() const override
|
|
|
|
{
|
2022-07-20 15:25:24 +00:00
|
|
|
return QueryTreeNodeType::MATCHER;
|
2022-07-14 11:20:16 +00:00
|
|
|
}
|
|
|
|
|
2022-07-19 10:54:45 +00:00
|
|
|
void dumpTreeImpl(WriteBuffer & buffer, FormatState & format_state, size_t indent) const override;
|
|
|
|
|
2022-10-10 10:25:58 +00:00
|
|
|
protected:
|
2022-07-15 13:32:53 +00:00
|
|
|
bool isEqualImpl(const IQueryTreeNode & rhs) const override;
|
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
void updateTreeHashImpl(HashState & hash_state) const override;
|
|
|
|
|
|
|
|
QueryTreeNodePtr cloneImpl() const override;
|
|
|
|
|
2023-03-14 09:14:58 +00:00
|
|
|
ASTPtr toASTImpl(const ConvertToASTOptions & options) const override;
|
2022-10-10 10:25:58 +00:00
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
private:
|
|
|
|
explicit MatcherNode(MatcherNodeType matcher_type_,
|
|
|
|
Identifier qualified_identifier_,
|
|
|
|
Identifiers columns_identifiers_,
|
|
|
|
std::shared_ptr<re2::RE2> columns_matcher_,
|
|
|
|
ColumnTransformersNodes column_transformers_);
|
|
|
|
|
|
|
|
MatcherNodeType matcher_type;
|
|
|
|
Identifier qualified_identifier;
|
|
|
|
Identifiers columns_identifiers;
|
|
|
|
std::shared_ptr<re2::RE2> columns_matcher;
|
|
|
|
std::unordered_set<std::string> columns_identifiers_set;
|
|
|
|
|
|
|
|
static constexpr size_t column_transformers_child_index = 0;
|
2022-10-07 10:44:28 +00:00
|
|
|
static constexpr size_t children_size = column_transformers_child_index + 1;
|
2022-07-14 11:20:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|