Save join_use_nulls in SETTINGS section for storage View

This commit is contained in:
vdimir 2021-05-20 16:47:09 +03:00
parent 7e39e8474f
commit 346dc65140
No known key found for this signature in database
GPG Key ID: F57B3E10A21DBB31
4 changed files with 83 additions and 9 deletions

View File

@ -29,6 +29,57 @@ namespace ErrorCodes
extern const int LOGICAL_ERROR;
}
namespace
{
void addSettingsChanges(ASTPtr ast, const Settings & settings)
{
auto * settings_ast = ast->as<ASTSetQuery>();
if (!settings_ast)
throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "ASTSetQuery expected");
settings_ast->is_standalone = false;
if (settings_ast->changes.tryGet("join_use_nulls") == nullptr)
settings_ast->changes.emplace_back("join_use_nulls", Field(settings.join_use_nulls));
}
/// Save to AST settings from context that affects view behaviour.
void saveSettingsToAst(ASTSelectWithUnionQuery * select, const Settings & settings)
{
/// Check SETTINGS section on the top level
if (select->settings_ast)
{
addSettingsChanges(select->settings_ast, settings);
return;
}
/// We cannot add SETTINGS on the top level because it will clash with section from inner SELECT
/// and will got query: SELECT ... SETTINGS ... SETTINGS ...
/// Process every select in ast and add SETTINGS section to each
for (const auto & child : select->list_of_selects->children)
{
auto * child_select = child->as<ASTSelectQuery>();
if (!child_select)
continue;
ASTPtr ast_set_query = child_select->settings();
if (ast_set_query)
{
/// Modify existing SETTINGS section
addSettingsChanges(ast_set_query, settings);
}
else
{
/// Add SETTINGS section to query
ast_set_query = std::make_shared<ASTSetQuery>();
addSettingsChanges(ast_set_query, settings);
child_select->setExpression(ASTSelectQuery::Expression::SETTINGS, std::move(ast_set_query));
}
}
}
}
StorageView::StorageView(
const StorageID & table_id_,
@ -37,7 +88,6 @@ StorageView::StorageView(
const String & comment,
const Settings & settings)
: IStorage(table_id_)
, settings_changes(settings.changes())
{
StorageInMemoryMetadata storage_metadata;
storage_metadata.setColumns(columns_);
@ -46,6 +96,7 @@ StorageView::StorageView(
if (!query.select)
throw Exception("SELECT query is not specified for " + getName(), ErrorCodes::INCORRECT_QUERY);
saveSettingsToAst(query.select, settings);
SelectQueryDescription description;
description.inner_query = query.select->ptr();
@ -89,10 +140,7 @@ void StorageView::read(
current_inner_query = query_info.view_query->clone();
}
auto modified_context = Context::createCopy(context);
modified_context->applySettingsChanges(settings_changes);
InterpreterSelectWithUnionQuery interpreter(current_inner_query, modified_context, {}, column_names);
InterpreterSelectWithUnionQuery interpreter(current_inner_query, context, {}, column_names);
interpreter.buildQueryPlan(query_plan);
/// It's expected that the columns read from storage are not constant.

View File

@ -55,8 +55,6 @@ protected:
const ColumnsDescription & columns_,
const String & comment,
const Settings & settings);
SettingsChanges settings_changes;
};
}

View File

@ -1,3 +1,27 @@
SELECT
a,
b,
c
FROM
(
SELECT *
FROM
(
SELECT
number + 1 AS a,
number + 11 AS b
FROM numbers(2)
) AS t1
FULL OUTER JOIN
(
SELECT
number + 2 AS a,
number + 22 AS c
FROM numbers(2)
) AS t2 USING (a)
ORDER BY a ASC
SETTINGS max_block_size = 666, join_use_nulls = 0
) AS view_no_nulls
1 11 0
2 12 22
3 0 23

View File

@ -8,13 +8,17 @@ SET join_use_nulls = 0;
CREATE OR REPLACE VIEW view_no_nulls AS
SELECT * FROM ( SELECT number + 1 AS a, number + 11 AS b FROM numbers(2) ) AS t1
FULL JOIN ( SELECT number + 2 AS a, number + 22 AS c FROM numbers(2) ) AS t2
USING a ORDER BY a;
USING a ORDER BY a
SETTINGS max_block_size = 666;
-- check that max_block_size not rewriten
EXPLAIN SYNTAX SELECT * FROM view_no_nulls;
CREATE OR REPLACE VIEW view_nulls_set AS
SELECT * FROM ( SELECT number + 1 AS a, number + 11 AS b FROM numbers(2) ) AS t1
FULL JOIN ( SELECT number + 2 AS a, number + 22 AS c FROM numbers(2) ) AS t2
USING a ORDER BY a
SETTINGS join_use_nulls = 1;
SETTINGS join_use_nulls = 1, max_block_size = 666;
SET join_use_nulls = 1;