mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Merge pull request #22657 from amosbird/ctefix3
Fix CTE usage in view definition
This commit is contained in:
commit
9b546f3b89
@ -13,28 +13,7 @@ namespace DB
|
|||||||
void ApplyWithSubqueryVisitor::visit(ASTPtr & ast, const Data & data)
|
void ApplyWithSubqueryVisitor::visit(ASTPtr & ast, const Data & data)
|
||||||
{
|
{
|
||||||
if (auto * node_select = ast->as<ASTSelectQuery>())
|
if (auto * node_select = ast->as<ASTSelectQuery>())
|
||||||
{
|
visit(*node_select, data);
|
||||||
std::optional<Data> new_data;
|
|
||||||
if (auto with = node_select->with())
|
|
||||||
{
|
|
||||||
for (auto & child : with->children)
|
|
||||||
{
|
|
||||||
visit(child, new_data ? *new_data : data);
|
|
||||||
if (auto * ast_with_elem = child->as<ASTWithElement>())
|
|
||||||
{
|
|
||||||
if (!new_data)
|
|
||||||
new_data = data;
|
|
||||||
new_data->subqueries[ast_with_elem->name] = ast_with_elem->subquery;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto & child : node_select->children)
|
|
||||||
{
|
|
||||||
if (child != node_select->with())
|
|
||||||
visit(child, new_data ? *new_data : data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (auto & child : ast->children)
|
for (auto & child : ast->children)
|
||||||
@ -46,6 +25,36 @@ void ApplyWithSubqueryVisitor::visit(ASTPtr & ast, const Data & data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplyWithSubqueryVisitor::visit(ASTSelectQuery & ast, const Data & data)
|
||||||
|
{
|
||||||
|
std::optional<Data> new_data;
|
||||||
|
if (auto with = ast.with())
|
||||||
|
{
|
||||||
|
for (auto & child : with->children)
|
||||||
|
{
|
||||||
|
visit(child, new_data ? *new_data : data);
|
||||||
|
if (auto * ast_with_elem = child->as<ASTWithElement>())
|
||||||
|
{
|
||||||
|
if (!new_data)
|
||||||
|
new_data = data;
|
||||||
|
new_data->subqueries[ast_with_elem->name] = ast_with_elem->subquery;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & child : ast.children)
|
||||||
|
{
|
||||||
|
if (child != ast.with())
|
||||||
|
visit(child, new_data ? *new_data : data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyWithSubqueryVisitor::visit(ASTSelectWithUnionQuery & ast, const Data & data)
|
||||||
|
{
|
||||||
|
for (auto & child : ast.children)
|
||||||
|
visit(child, data);
|
||||||
|
}
|
||||||
|
|
||||||
void ApplyWithSubqueryVisitor::visit(ASTTableExpression & table, const Data & data)
|
void ApplyWithSubqueryVisitor::visit(ASTTableExpression & table, const Data & data)
|
||||||
{
|
{
|
||||||
if (table.database_and_table_name)
|
if (table.database_and_table_name)
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
class ASTFunction;
|
class ASTFunction;
|
||||||
|
class ASTSelectQuery;
|
||||||
|
class ASTSelectWithUnionQuery;
|
||||||
struct ASTTableExpression;
|
struct ASTTableExpression;
|
||||||
|
|
||||||
class ApplyWithSubqueryVisitor
|
class ApplyWithSubqueryVisitor
|
||||||
@ -18,9 +20,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void visit(ASTPtr & ast) { visit(ast, {}); }
|
static void visit(ASTPtr & ast) { visit(ast, {}); }
|
||||||
|
static void visit(ASTSelectQuery & select) { visit(select, {}); }
|
||||||
|
static void visit(ASTSelectWithUnionQuery & select) { visit(select, {}); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void visit(ASTPtr & ast, const Data & data);
|
static void visit(ASTPtr & ast, const Data & data);
|
||||||
|
static void visit(ASTSelectQuery & ast, const Data & data);
|
||||||
|
static void visit(ASTSelectWithUnionQuery & ast, const Data & data);
|
||||||
static void visit(ASTTableExpression & table, const Data & data);
|
static void visit(ASTTableExpression & table, const Data & data);
|
||||||
static void visit(ASTFunction & func, const Data & data);
|
static void visit(ASTFunction & func, const Data & data);
|
||||||
};
|
};
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
#include <Interpreters/QueryLog.h>
|
#include <Interpreters/QueryLog.h>
|
||||||
#include <Interpreters/addTypeConversionToAST.h>
|
#include <Interpreters/addTypeConversionToAST.h>
|
||||||
#include <Interpreters/FunctionNameNormalizer.h>
|
#include <Interpreters/FunctionNameNormalizer.h>
|
||||||
|
#include <Interpreters/ApplyWithSubqueryVisitor.h>
|
||||||
|
|
||||||
#include <TableFunctions/TableFunctionFactory.h>
|
#include <TableFunctions/TableFunctionFactory.h>
|
||||||
#include <common/logger_useful.h>
|
#include <common/logger_useful.h>
|
||||||
@ -890,6 +891,8 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create)
|
|||||||
|
|
||||||
if (create.select && create.isView())
|
if (create.select && create.isView())
|
||||||
{
|
{
|
||||||
|
// Expand CTE before filling default database
|
||||||
|
ApplyWithSubqueryVisitor().visit(*create.select);
|
||||||
AddDefaultDatabaseVisitor visitor(current_database);
|
AddDefaultDatabaseVisitor visitor(current_database);
|
||||||
visitor.visit(*create.select);
|
visitor.visit(*create.select);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
drop table if exists t;
|
drop table if exists t;
|
||||||
create table t engine = Memory as with cte as (select * from numbers(10)) select * from cte;
|
create table t engine = Memory as with cte as (select * from numbers(10)) select * from cte;
|
||||||
drop table t;
|
drop table t;
|
||||||
|
|
||||||
|
drop table if exists view1;
|
||||||
|
create view view1 as with t as (select number n from numbers(3)) select n from t;
|
||||||
|
drop table view1;
|
||||||
|
Loading…
Reference in New Issue
Block a user