Fixed review comments and updated FunctionParameterValuesVisitor to use visitFunction - 40907 Parameterized views as table functions

This commit is contained in:
Smita Kulkarni 2022-12-23 17:57:17 +01:00
parent 5001cf9fa2
commit a6f860f24e
3 changed files with 22 additions and 15 deletions

View File

@ -510,9 +510,10 @@ InterpreterSelectQuery::InterpreterSelectQuery(
if (view)
{
query_info.is_parameterized_view = view->isParameterizedView();
/// We need to fetch the parameters set for SELECT parameterized view before the query is replaced.
/// We need to fetch the parameters set for SELECT ... FROM parameterized_view(<params>) before the query is replaced.
/// replaceWithSubquery replaces the function child and adds the subquery in its place.
/// the parameters are children of function child, if function is replaced the parameters are also gone from tree
/// the parameters are children of function child, if function (which corresponds to parametrised view and has
/// parameters in its arguments: `parametrised_view(<params>)`) is replaced the parameters are also gone from tree
/// So we need to get the parameters before they are removed from the tree
/// and after query is replaced, we use these parameters to substitute in the parameterized view query
if (query_info.is_parameterized_view)

View File

@ -27,8 +27,8 @@ public:
void visit(const ASTPtr & ast)
{
if (const auto * expression = ast->as<ASTExpressionList>())
visitExpressionList(*expression);
if (const auto * function = ast->as<ASTFunction>())
visitFunction(*function);
for (const auto & child : ast->children)
visit(child);
}
@ -36,18 +36,23 @@ public:
private:
NameToNameMap & parameter_values;
void visitExpressionList(const ASTExpressionList & expression_list)
void visitFunction(const ASTFunction & parameter_function)
{
if (expression_list.children.size() != 2)
if (parameter_function.name != "equals" && parameter_function.children.size() != 1)
return;
if (const auto * identifier = expression_list.children[0]->as<ASTIdentifier>())
const auto * expression_list = parameter_function.children[0]->as<ASTExpressionList>();
if (expression_list && expression_list->children.size() != 2)
return;
if (const auto * identifier = expression_list->children[0]->as<ASTIdentifier>())
{
if (const auto * literal = expression_list.children[1]->as<ASTLiteral>())
if (const auto * literal = expression_list->children[1]->as<ASTLiteral>())
{
parameter_values[identifier->name()] = convertFieldToString(literal->value);
}
else if (const auto * function = expression_list.children[1]->as<ASTFunction>())
else if (const auto * function = expression_list->children[1]->as<ASTFunction>())
{
if (isFunctionCast(function))
{

View File

@ -117,10 +117,11 @@ Block StorageSnapshot::getSampleBlockForColumns(const Names & column_names,const
Block res;
const auto & columns = getMetadataForQuery()->getColumns();
for (const auto & name : column_names)
for (const auto & column_name : column_names)
{
const std::string & column_name = name;
std::string substituted_column_name = name;
/// substituted_column_name is used for parameterized view (which are created using query parameters
/// and SELECT is used with substitution of these query parameters )
std::string substituted_column_name = column_name;
std::string::size_type pos = 0u;
for (const auto & parameter : parameter_values)
{
@ -141,17 +142,17 @@ Block StorageSnapshot::getSampleBlockForColumns(const Names & column_names,const
{
res.insert({object_column->type->createColumn(), object_column->type, column_name});
}
else if (auto it = virtual_columns.find(name); it != virtual_columns.end())
else if (auto it = virtual_columns.find(column_name); it != virtual_columns.end())
{
/// Virtual columns must be appended after ordinary, because user can
/// override them.
const auto & type = it->second;
res.insert({type->createColumn(), type, name});
res.insert({type->createColumn(), type, column_name});
}
else
{
throw Exception(ErrorCodes::NOT_FOUND_COLUMN_IN_BLOCK,
"Column {} not found in table {}", backQuote(name), storage.getStorageID().getNameForLogs());
"Column {} not found in table {}", backQuote(substituted_column_name), storage.getStorageID().getNameForLogs());
}
}
return res;