2021-02-10 14:12:49 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <Core/Types.h>
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
#include <vector>
|
|
|
|
#include <Interpreters/ExpressionActions.h>
|
2021-04-26 16:06:18 +00:00
|
|
|
#include <Interpreters/AggregateDescription.h>
|
2021-02-10 14:12:49 +00:00
|
|
|
#include <Parsers/IAST_fwd.h>
|
|
|
|
#include <Storages/ColumnsDescription.h>
|
|
|
|
|
|
|
|
#include <boost/multi_index/member.hpp>
|
|
|
|
#include <boost/multi_index/ordered_index.hpp>
|
|
|
|
#include <boost/multi_index/sequenced_index.hpp>
|
|
|
|
#include <boost/multi_index_container.hpp>
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
struct StorageInMemoryMetadata;
|
|
|
|
using StorageMetadataPtr = std::shared_ptr<const StorageInMemoryMetadata>;
|
|
|
|
|
|
|
|
/// Description of projections for Storage
|
|
|
|
struct ProjectionDescription
|
|
|
|
{
|
2021-04-26 11:48:51 +00:00
|
|
|
enum class Type
|
|
|
|
{
|
|
|
|
Normal,
|
|
|
|
Aggregate,
|
|
|
|
};
|
|
|
|
|
2021-08-27 18:35:13 +00:00
|
|
|
static constexpr const char * MINMAX_COUNT_PROJECTION_NAME = "_minmax_count_projection";
|
|
|
|
|
2021-02-10 14:12:49 +00:00
|
|
|
/// Definition AST of projection
|
|
|
|
ASTPtr definition_ast;
|
|
|
|
|
|
|
|
/// Subquery AST for projection calculation
|
|
|
|
ASTPtr query_ast;
|
|
|
|
|
|
|
|
/// Projection name
|
|
|
|
String name;
|
|
|
|
|
|
|
|
/// Projection type (normal, aggregate, etc.)
|
2021-04-26 11:48:51 +00:00
|
|
|
Type type = Type::Normal;
|
2021-02-10 14:12:49 +00:00
|
|
|
|
2021-04-26 16:06:18 +00:00
|
|
|
/// Columns which are required for query_ast.
|
2021-02-10 14:12:49 +00:00
|
|
|
Names required_columns;
|
|
|
|
|
|
|
|
Names getRequiredColumns() const { return required_columns; }
|
|
|
|
|
|
|
|
/// Sample block with projection columns. (NOTE: columns in block are empty, but not nullptr)
|
|
|
|
Block sample_block;
|
|
|
|
|
2021-04-29 07:38:47 +00:00
|
|
|
Block sample_block_for_keys;
|
|
|
|
|
2021-02-10 14:12:49 +00:00
|
|
|
StorageMetadataPtr metadata;
|
|
|
|
|
|
|
|
size_t key_size = 0;
|
|
|
|
|
2021-08-27 18:35:13 +00:00
|
|
|
bool is_minmax_count_projection = false;
|
|
|
|
|
2021-10-16 10:13:11 +00:00
|
|
|
/// If a primary key expression is used in the minmax_count projection, store the name of max expression.
|
|
|
|
String primary_key_max_column_name;
|
2021-10-09 09:00:39 +00:00
|
|
|
|
2021-02-10 14:12:49 +00:00
|
|
|
/// Parse projection from definition AST
|
|
|
|
static ProjectionDescription
|
|
|
|
getProjectionFromAST(const ASTPtr & definition_ast, const ColumnsDescription & columns, ContextPtr query_context);
|
|
|
|
|
2021-10-09 09:00:39 +00:00
|
|
|
static ProjectionDescription getMinMaxCountProjection(
|
2021-11-17 14:05:57 +00:00
|
|
|
const ColumnsDescription & columns,
|
|
|
|
const ASTPtr & partition_columns,
|
|
|
|
const Names & minmax_columns,
|
|
|
|
const ASTs & primary_key_asts,
|
|
|
|
ContextPtr query_context);
|
2021-08-27 18:35:13 +00:00
|
|
|
|
2021-02-10 14:12:49 +00:00
|
|
|
ProjectionDescription() = default;
|
|
|
|
|
|
|
|
/// We need custom copy constructors because we don't want
|
2021-04-26 16:06:18 +00:00
|
|
|
/// unintentionally share AST variables and modify them.
|
|
|
|
ProjectionDescription(const ProjectionDescription & other) = delete;
|
|
|
|
ProjectionDescription(ProjectionDescription && other) = default;
|
|
|
|
ProjectionDescription & operator=(const ProjectionDescription & other) = delete;
|
|
|
|
ProjectionDescription & operator=(ProjectionDescription && other) = default;
|
|
|
|
|
|
|
|
ProjectionDescription clone() const;
|
2021-02-10 14:12:49 +00:00
|
|
|
|
|
|
|
bool operator==(const ProjectionDescription & other) const;
|
|
|
|
bool operator!=(const ProjectionDescription & other) const { return !(*this == other); }
|
|
|
|
|
|
|
|
/// Recalculate projection with new columns because projection expression may change
|
|
|
|
/// if something change in columns.
|
|
|
|
void recalculateWithNewColumns(const ColumnsDescription & new_columns, ContextPtr query_context);
|
|
|
|
|
|
|
|
bool isPrimaryKeyColumnPossiblyWrappedInFunctions(const ASTPtr & node) const;
|
2021-08-26 11:01:15 +00:00
|
|
|
|
|
|
|
Block calculate(const Block & block, ContextPtr context) const;
|
2021-08-27 18:35:13 +00:00
|
|
|
|
|
|
|
String getDirectoryName() const { return name + ".proj"; }
|
2021-02-10 14:12:49 +00:00
|
|
|
};
|
|
|
|
|
2021-08-27 18:35:13 +00:00
|
|
|
using ProjectionDescriptionRawPtr = const ProjectionDescription *;
|
|
|
|
|
2021-02-10 14:12:49 +00:00
|
|
|
/// All projections in storage
|
|
|
|
struct ProjectionsDescription
|
|
|
|
{
|
2021-04-26 16:06:18 +00:00
|
|
|
ProjectionsDescription() = default;
|
|
|
|
ProjectionsDescription(ProjectionsDescription && other) = default;
|
|
|
|
ProjectionsDescription & operator=(ProjectionsDescription && other) = default;
|
|
|
|
|
|
|
|
ProjectionsDescription clone() const;
|
|
|
|
|
2021-02-10 14:12:49 +00:00
|
|
|
/// Convert description to string
|
|
|
|
String toString() const;
|
|
|
|
/// Parse description from string
|
|
|
|
static ProjectionsDescription parse(const String & str, const ColumnsDescription & columns, ContextPtr query_context);
|
|
|
|
|
|
|
|
/// Return common expression for all stored projections
|
|
|
|
ExpressionActionsPtr getSingleExpressionForProjections(const ColumnsDescription & columns, ContextPtr query_context) const;
|
|
|
|
|
|
|
|
bool operator==(const ProjectionsDescription & other) const { return projections == other.projections; }
|
|
|
|
bool operator!=(const ProjectionsDescription & other) const { return !(*this == other); }
|
|
|
|
|
|
|
|
auto begin() const { return projections.begin(); }
|
|
|
|
auto end() const { return projections.end(); }
|
|
|
|
|
|
|
|
size_t size() const { return projections.size(); }
|
|
|
|
bool empty() const { return projections.empty(); }
|
|
|
|
|
|
|
|
bool has(const String & projection_name) const;
|
|
|
|
const ProjectionDescription & get(const String & projection_name) const;
|
|
|
|
|
|
|
|
void
|
|
|
|
add(ProjectionDescription && projection, const String & after_projection = String(), bool first = false, bool if_not_exists = false);
|
2021-05-28 13:27:36 +00:00
|
|
|
void remove(const String & projection_name, bool if_exists);
|
2021-02-10 14:12:49 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
/// Keep the sequence of columns and allow to lookup by name.
|
2021-04-26 16:06:18 +00:00
|
|
|
using Container = std::list<ProjectionDescription>;
|
|
|
|
using Map = std::unordered_map<std::string, Container::iterator>;
|
2021-02-10 14:12:49 +00:00
|
|
|
|
|
|
|
Container projections;
|
2021-04-26 16:06:18 +00:00
|
|
|
Map map;
|
2021-02-10 14:12:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|