2014-09-23 16:02:04 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <DB/Interpreters/Context.h>
|
|
|
|
#include <DB/Interpreters/ExpressionAnalyzer.h>
|
|
|
|
#include <DB/DataTypes/DataTypeString.h>
|
|
|
|
#include <DB/Parsers/ASTIdentifier.h>
|
|
|
|
#include <DB/Parsers/ASTLiteral.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
ASTPtr reinterpretAsIdentifierImpl(const ASTPtr & expr, const Context & context)
|
|
|
|
{
|
|
|
|
/// for string literal return its value
|
|
|
|
if (const auto literal = typeid_cast<const ASTLiteral *>(expr.get()))
|
|
|
|
return new ASTIdentifier{{}, safeGet<const String &>(literal->value)};
|
|
|
|
|
|
|
|
/// otherwise evaluate the expression
|
|
|
|
Block block{};
|
2015-02-27 21:05:56 +00:00
|
|
|
/** pass a dummy column name because ExpressionAnalyzer
|
2014-09-23 16:02:04 +00:00
|
|
|
* does not work with no columns so far. */
|
|
|
|
ExpressionAnalyzer{
|
2015-07-15 01:26:35 +00:00
|
|
|
expr, context, {},
|
2014-09-23 16:02:04 +00:00
|
|
|
{ { "", new DataTypeString } }
|
|
|
|
}.getActions(false)->execute(block);
|
|
|
|
|
|
|
|
const auto & column_name_type = block.getByName(expr->getColumnName());
|
|
|
|
|
|
|
|
/// ensure the result of evaluation has String type
|
|
|
|
if (!typeid_cast<const DataTypeString *>(column_name_type.type.get()))
|
|
|
|
throw Exception{"Expression must evaluate to a String"};
|
|
|
|
|
|
|
|
return new ASTIdentifier{{}, column_name_type.column->getDataAt(0).toString()};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief if `expr` is not already ASTIdentifier evaluates it
|
|
|
|
* and replaces by a new ASTIdentifier with the result of evaluation as its name.
|
|
|
|
* `expr` must evaluate to a String type */
|
|
|
|
inline ASTIdentifier & reinterpretAsIdentifier(ASTPtr & expr, const Context & context)
|
|
|
|
{
|
|
|
|
/// for identifier just return its name
|
|
|
|
if (!typeid_cast<const ASTIdentifier *>(expr.get()))
|
|
|
|
expr = reinterpretAsIdentifierImpl(expr, context);
|
|
|
|
|
|
|
|
return static_cast<ASTIdentifier &>(*expr);
|
|
|
|
}
|
|
|
|
}
|