ExpressionAnalyzer.cpp 93.9 KB
Newer Older
1 2
#include <Poco/Util/Application.h>

3 4 5 6 7 8 9 10 11 12
#include <DB/DataTypes/FieldToDataType.h>

#include <DB/Parsers/ASTFunction.h>
#include <DB/Parsers/ASTIdentifier.h>
#include <DB/Parsers/ASTLiteral.h>
#include <DB/Parsers/ASTAsterisk.h>
#include <DB/Parsers/ASTExpressionList.h>
#include <DB/Parsers/ASTSelectQuery.h>
#include <DB/Parsers/ASTSubquery.h>
#include <DB/Parsers/ASTSet.h>
13
#include <DB/Parsers/ASTOrderByElement.h>
14 15 16 17

#include <DB/DataTypes/DataTypeSet.h>
#include <DB/DataTypes/DataTypeTuple.h>
#include <DB/DataTypes/DataTypeExpression.h>
18
#include <DB/DataTypes/DataTypeNested.h>
19

20 21 22 23 24
#include <DB/Columns/ColumnSet.h>
#include <DB/Columns/ColumnExpression.h>

#include <DB/Interpreters/InterpreterSelectQuery.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
25
#include <DB/Interpreters/ExpressionActions.h>
A
Merge  
Alexey Arno 已提交
26
#include <DB/Interpreters/InJoinSubqueriesPreprocessor.h>
27
#include <DB/Interpreters/LogicalExpressionsOptimizer.h>
28
#include <DB/Interpreters/ExternalDictionaries.h>
29

30 31
#include <DB/AggregateFunctions/AggregateFunctionFactory.h>

32
#include <DB/Storages/StorageDistributed.h>
33
#include <DB/Storages/StorageMemory.h>
34
#include <DB/Storages/StorageSet.h>
35
#include <DB/Storages/StorageJoin.h>
36

37
#include <DB/DataStreams/LazyBlockInputStream.h>
38 39
#include <DB/DataStreams/copyData.h>

40 41
#include <DB/Dictionaries/IDictionary.h>

42 43
#include <DB/Common/typeid_cast.h>

44
#include <DB/Parsers/formatAST.h>
45

A
Andrey Mironov 已提交
46
#include <DB/Functions/FunctionFactory.h>
A
Merge  
Alexey Arno 已提交
47 48 49
#include <DB/Functions/FunctionsTransform.h>
#include <DB/Functions/FunctionsConditional.h>
#include <DB/Functions/FunctionsArray.h>
A
Andrey Mironov 已提交
50

A
Alexey Milovidov 已提交
51
#include <ext/range.hpp>
52
#include <DB/DataTypes/DataTypeFactory.h>
53

54 55 56 57

namespace DB
{

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
namespace ErrorCodes
{
	extern const int MULTIPLE_EXPRESSIONS_FOR_ALIAS;
	extern const int UNKNOWN_IDENTIFIER;
	extern const int CYCLIC_ALIASES;
	extern const int INCORRECT_RESULT_OF_SCALAR_SUBQUERY;
	extern const int TOO_MUCH_ROWS;
	extern const int NOT_FOUND_COLUMN_IN_BLOCK;
	extern const int INCORRECT_ELEMENT_OF_SET;
	extern const int ALIAS_REQUIRED;
	extern const int EMPTY_NESTED_TABLE;
	extern const int NOT_AN_AGGREGATE;
	extern const int UNEXPECTED_EXPRESSION;
	extern const int PARAMETERS_TO_AGGREGATE_FUNCTIONS_MUST_BE_LITERALS;
	extern const int DUPLICATE_COLUMN;
73
	extern const int FUNCTION_CANNOT_HAVE_PARAMETERS;
74
	extern const int ILLEGAL_AGGREGATION;
75 76
}

77

78 79
/** Calls to these functions in the GROUP BY statement would be
  * replaced by their immediate argument.
80
  */
A
Alexey Milovidov 已提交
81 82
const std::unordered_set<String> injective_function_names
{
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
	"negate",
	"bitNot",
	"reverse",
	"reverseUTF8",
	"toString",
	"toFixedString",
	"toStringCutToZero",
	"IPv4NumToString",
	"IPv4StringToNum",
	"hex",
	"unhex",
	"bitmaskToList",
	"bitmaskToArray",
	"tuple",
	"regionToName",
98
	"concatAssumeInjective",
99 100
};

101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
const std::unordered_set<String> possibly_injective_function_names
{
	"dictGetString",
	"dictGetUInt8",
	"dictGetUInt16",
	"dictGetUInt32",
	"dictGetUInt64",
	"dictGetInt8",
	"dictGetInt16",
	"dictGetInt32",
	"dictGetInt64",
	"dictGetFloat32",
	"dictGetFloat64",
	"dictGetDate",
	"dictGetDateTime"
};

A
Merge  
Alexey Arno 已提交
118 119 120 121
namespace
{

bool functionIsInOperator(const String & name)
122 123 124 125
{
	return name == "in" || name == "notIn";
}

A
Merge  
Alexey Arno 已提交
126
bool functionIsInOrGlobalInOperator(const String & name)
127 128 129 130
{
	return name == "in" || name == "notIn" || name == "globalIn" || name == "globalNotIn";
}

A
Merge  
Alexey Arno 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
/// Create a function uniquely identified by the first two parameters. If this
/// function actually is a CASE expression, record this information.
FunctionPtr getFunctionFromFactory(const String & name, const ASTFunction::Genus genus, const Context & context)
{
	FunctionPtr function = FunctionFactory::instance().get(name, context);

	if (genus == ASTFunction::Genus::CASE_WITH_EXPR)
	{
		FunctionTransform * fun_transform = typeid_cast<FunctionTransform *>(&*function);
		if (fun_transform == nullptr)
			throw Exception{"Internal error", ErrorCodes::LOGICAL_ERROR};
		fun_transform->setCaseMode();
	}
	else if (genus == ASTFunction::Genus::CASE_WITHOUT_EXPR)
	{
		FunctionMultiIf * fun_multi_if = typeid_cast<FunctionMultiIf *>(&*function);
		if (fun_multi_if == nullptr)
			throw Exception{"Internal error", ErrorCodes::LOGICAL_ERROR};
		fun_multi_if->setCaseMode();
	}
	else if (genus == ASTFunction::Genus::CASE_ARRAY)
	{
		FunctionArray * fun_array = typeid_cast<FunctionArray *>(&*function);
		if (fun_array == nullptr)
			throw Exception{"Internal error", ErrorCodes::LOGICAL_ERROR};
		fun_array->setCaseMode();
	}

	return function;
}

A
Merge  
Alexey Arno 已提交
162
}
163

164 165
void ExpressionAnalyzer::init()
{
166
	select_query = typeid_cast<ASTSelectQuery *>(ast.get());
167

A
Merge  
Alexey Arno 已提交
168 169 170 171
	/// В зависимости от профиля пользователя проверить наличие прав на выполнение
	/// распределённых подзапросов внутри секций IN или JOIN и обработать эти подзапросы.
	InJoinSubqueriesPreprocessor<>(select_query, context, storage).perform();

172
	/// Оптимизирует логические выражения.
A
Merge  
Alexey Arno 已提交
173
	LogicalExpressionsOptimizer(select_query, settings).perform();
174

175
	/// Создаёт словарь aliases: alias -> ASTPtr
176
	addASTAliases(ast);
177

178
	/// Common subexpression elimination. Rewrite rules.
179
	normalizeTree();
180

181 182 183
	/// ALIAS столбцы не должны подставляться вместо ASTAsterisk, добавим их теперь, после normalizeTree.
	addAliasColumns();

184 185 186
	/// Выполнение скалярных подзапросов - замена их на значения-константы.
	executeScalarSubqueries();

A
Alexey Milovidov 已提交
187
	/// GROUP BY injective function elimination.
188
	optimizeGroupBy();
189

190 191 192
	/// Удалить из ORDER BY повторяющиеся элементы.
	optimizeOrderBy();

193
	/// array_join_alias_to_name, array_join_result_to_source.
194
	getArrayJoinedColumns();
195

196 197 198
	/// Удалить ненужное из списка columns. Создать unknown_required_columns. Сформировать columns_added_by_join.
	collectUsedColumns();

199
	/// external_tables, subqueries_for_sets для глобальных подзапросов.
200 201
	/// Заменяет глобальные подзапросы на сгенерированные имена временных таблиц, которые будут отправлены на удалённые серверы.
	initGlobalSubqueriesAndExternalTables();
202 203 204 205 206 207 208

	/// has_aggregation, aggregation_keys, aggregate_descriptions, aggregated_columns.
	/// Этот анализ надо провести после обработки глобальных подзапросов, потому что в противном случае,
	/// если агрегатная функция содержит глобальный подзапрос, то метод analyzeAggregation сохранит
	/// в aggregate_descriptions информацию о параметрах этой агрегатной функции, среди которых окажется
	/// глобальный подзапрос. Затем при вызове метода initGlobalSubqueriesAndExternalTables, этот
	/// глобальный подзапрос будет заменён на временную таблицу, в результате чего aggregate_descriptions
209
	/// будет содержать устаревшую информацию, что приведёт к ошибке при выполнении запроса.
210
	analyzeAggregation();
211 212 213 214 215 216 217 218 219 220 221
}


void ExpressionAnalyzer::analyzeAggregation()
{
	/** Найдем ключи агрегации (aggregation_keys), информацию об агрегатных функциях (aggregate_descriptions),
	 *  а также набор столбцов, получаемых после агрегации, если она есть,
	 *  или после всех действий, которые обычно выполняются до агрегации (aggregated_columns).
	 *
	 * Всё, что ниже (составление временных ExpressionActions) - только в целях анализа запроса (вывода типов).
	 */
222

223 224
	if (select_query && (select_query->group_expression_list || select_query->having_expression))
		has_aggregation = true;
225

226
	ExpressionActionsPtr temp_actions = std::make_shared<ExpressionActions>(columns, settings);
227 228 229

	if (select_query && select_query->array_join_expression_list)
	{
230
		getRootActions(select_query->array_join_expression_list, true, false, temp_actions);
231
		addMultipleArrayJoinAction(temp_actions);
232
	}
233

234 235
	if (select_query && select_query->join)
	{
236 237 238 239
		auto join = typeid_cast<ASTJoin &>(*select_query->join);
		if (join.using_expr_list)
			getRootActions(join.using_expr_list, true, false, temp_actions);

240
		addJoinAction(temp_actions, true);
241 242
	}

243
	getAggregates(ast, temp_actions);
244

245 246
	if (has_aggregation)
	{
247
		assertSelect();
248

249 250 251
		/// Найдем ключи агрегации.
		if (select_query->group_expression_list)
		{
252
			NameSet unique_keys;
253
			auto & group_asts = select_query->group_expression_list->children;
254 255
			for (size_t i = 0; i < group_asts.size(); ++i)
			{
256
				getRootActions(group_asts[i], true, false, temp_actions);
257

258 259
				const auto & column_name = group_asts[i]->getColumnName();
				const auto & block = temp_actions->getSampleBlock();
260

261 262 263 264 265
				if (!block.has(column_name))
					throw Exception("Unknown identifier (in GROUP BY): " + column_name, ErrorCodes::UNKNOWN_IDENTIFIER);

				const auto & col = block.getByName(column_name);

266 267 268
				/// constant expressions have non-null column pointer at this stage
				if (const auto is_constexpr = col.column)
				{
269 270 271 272 273
					/// but don't remove last key column if no aggregate functions, otherwise aggregation will not work
					if (!aggregate_descriptions.empty() || group_asts.size() > 1)
					{
						if (i < group_asts.size() - 1)
							group_asts[i] = std::move(group_asts.back());
274

275 276
						group_asts.pop_back();
						i -= 1;
277

278 279
						continue;
					}
280 281
				}

282
				NameAndTypePair key{column_name, col.type};
283

284
				/// Ключи агрегации уникализируются.
285
				if (!unique_keys.count(key.name))
286
				{
287
					unique_keys.insert(key.name);
288 289
					aggregation_keys.push_back(key);

290 291
					/// key is no longer needed, therefore we can save a little by moving it
					aggregated_columns.push_back(std::move(key));
292
				}
293
			}
294 295 296 297 298 299

			if (group_asts.empty())
			{
				select_query->group_expression_list = nullptr;
				has_aggregation = select_query->having_expression || aggregate_descriptions.size();
			}
300
		}
301

302 303 304
		for (size_t i = 0; i < aggregate_descriptions.size(); ++i)
		{
			AggregateDescription & desc = aggregate_descriptions[i];
305
			aggregated_columns.emplace_back(desc.column_name, desc.function->getReturnType());
306 307 308 309
		}
	}
	else
	{
310
		aggregated_columns = temp_actions->getSampleBlock().getColumnsList();
311 312 313 314
	}
}


315 316
void ExpressionAnalyzer::initGlobalSubqueriesAndExternalTables()
{
317
	/// Добавляет уже существующие внешние таблицы (не подзапросы) в словарь external_tables.
318
	findExternalTables(ast);
319 320 321

	/// Преобразует GLOBAL-подзапросы во внешние таблицы; кладёт их в словарь external_tables: name -> StoragePtr.
	initGlobalSubqueries(ast);
322 323 324 325 326 327 328 329
}


void ExpressionAnalyzer::initGlobalSubqueries(ASTPtr & ast)
{
	/// Рекурсивные вызовы. Не опускаемся в подзапросы.

	for (auto & child : ast->children)
330
		if (!typeid_cast<ASTSelectQuery *>(child.get()))
331 332 333 334
			initGlobalSubqueries(child);

	/// Действия, выполняемые снизу вверх.

335
	if (ASTFunction * node = typeid_cast<ASTFunction *>(ast.get()))
336 337 338 339 340
	{
		/// Для GLOBAL IN.
		if (do_global && (node->name == "globalIn" || node->name == "globalNotIn"))
			addExternalStorage(node->arguments->children.at(1));
	}
341
	else if (ASTJoin * node = typeid_cast<ASTJoin *>(ast.get()))
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
	{
		/// Для GLOBAL JOIN.
		if (do_global && node->locality == ASTJoin::Global)
			addExternalStorage(node->table);
	}
}


void ExpressionAnalyzer::findExternalTables(ASTPtr & ast)
{
	/// Обход снизу. Намеренно опускаемся в подзапросы.
	for (auto & child : ast->children)
		findExternalTables(child);

	/// Если идентификатор типа таблица
	StoragePtr external_storage;

359
	if (ASTIdentifier * node = typeid_cast<ASTIdentifier *>(ast.get()))
360
		if (node->kind == ASTIdentifier::Table)
361 362 363 364 365
			if ((external_storage = context.tryGetExternalTable(node->name)))
				external_tables[node->name] = external_storage;
}


366
static std::shared_ptr<InterpreterSelectQuery> interpretSubquery(
367 368 369 370 371 372 373 374 375
	ASTPtr & subquery_or_table_name, const Context & context, size_t subquery_depth, const Names & required_columns);


void ExpressionAnalyzer::addExternalStorage(ASTPtr & subquery_or_table_name)
{
	/// При нераспределённых запросах, создание временных таблиц не имеет смысла.
	if (!(storage && storage->isRemote()))
		return;

376
	if (const ASTIdentifier * table = typeid_cast<const ASTIdentifier *>(subquery_or_table_name.get()))
377 378 379 380 381 382 383 384 385 386 387 388 389 390
	{
		/// Если это уже внешняя таблица, ничего заполять не нужно. Просто запоминаем ее наличие.
		if (external_tables.end() != external_tables.find(table->name))
			return;
	}

	/// Сгенерируем имя для внешней таблицы.
	String external_table_name = "_data" + toString(external_table_id);
	while (external_tables.count(external_table_name))
	{
		++external_table_id;
		external_table_name = "_data" + toString(external_table_id);
	}

391
	auto interpreter = interpretSubquery(subquery_or_table_name, context, subquery_depth, {});
392 393

	Block sample = interpreter->getSampleBlock();
394
	NamesAndTypesListPtr columns = std::make_shared<NamesAndTypesList>(sample.getColumnsList());
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420

	StoragePtr external_storage = StorageMemory::create(external_table_name, columns);

	/** Есть два способа выполнения распределённых GLOBAL-подзапросов.
	  *
	  * Способ push:
	  * Данные подзапроса отправляются на все удалённые серверы, где они затем используются.
	  * Для этого способа, данные отправляются в виде "внешних таблиц" и будут доступны на каждом удалённом сервере по имени типа _data1.
	  * Заменяем в запросе подзапрос на это имя.
	  *
	  * Способ pull:
	  * Удалённые серверы скачивают данные подзапроса с сервера-инициатора запроса.
	  * Для этого способа, заменяем подзапрос на другой подзапрос вида (SELECT * FROM remote('host:port', _query_QUERY_ID, _data1))
	  * Этот подзапрос, по факту, говорит - "надо скачать данные оттуда".
	  *
	  * Способ pull имеет преимущество, потому что в нём удалённый сервер может решить, что ему не нужны данные и не скачивать их в таких случаях.
	  */

	if (settings.global_subqueries_method == GlobalSubqueriesMethod::PUSH)
	{
		/** Заменяем подзапрос на имя временной таблицы.
		  * Именно в таком виде, запрос отправится на удалённый сервер.
		  * На удалённый сервер отправится эта временная таблица, и на его стороне,
		  *  вместо выполнения подзапроса, надо будет просто из неё прочитать.
		  */

421
		subquery_or_table_name = std::make_shared<ASTIdentifier>(StringRange(), external_table_name, ASTIdentifier::Table);
422 423 424 425 426 427
	}
	else if (settings.global_subqueries_method == GlobalSubqueriesMethod::PULL)
	{
		String host_port = getFQDNOrHostName() + ":" + toString(context.getTCPPort());
		String database = "_query_" + context.getCurrentQueryId();

428
		auto subquery = std::make_shared<ASTSubquery>();
429 430
		subquery_or_table_name = subquery;

431
		auto select = std::make_shared<ASTSelectQuery>();
432 433
		subquery->children.push_back(select);

434
		auto exp_list = std::make_shared<ASTExpressionList>();
435 436 437 438 439
		select->select_expression_list = exp_list;
		select->children.push_back(select->select_expression_list);

		Names column_names = external_storage->getColumnNamesList();
		for (const auto & name : column_names)
440
			exp_list->children.push_back(std::make_shared<ASTIdentifier>(StringRange(), name));
441

442
		auto table_func = std::make_shared<ASTFunction>();
443 444 445 446
		select->table = table_func;
		select->children.push_back(select->table);

		table_func->name = "remote";
447
		auto args = std::make_shared<ASTExpressionList>();
448 449 450
		table_func->arguments = args;
		table_func->children.push_back(table_func->arguments);

451
		auto address_lit = std::make_shared<ASTLiteral>(StringRange(), host_port);
452 453
		args->children.push_back(address_lit);

454
		auto database_lit = std::make_shared<ASTLiteral>(StringRange(), database);
455 456
		args->children.push_back(database_lit);

457
		auto table_lit = std::make_shared<ASTLiteral>(StringRange(), external_table_name);
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
		args->children.push_back(table_lit);
	}
	else
		throw Exception("Unknown global subqueries execution method", ErrorCodes::UNKNOWN_GLOBAL_SUBQUERIES_METHOD);

	external_tables[external_table_name] = external_storage;
	subqueries_for_sets[external_table_name].source = interpreter->execute().in;
	subqueries_for_sets[external_table_name].source_sample = interpreter->getSampleBlock();
	subqueries_for_sets[external_table_name].table = external_storage;

	/** NOTE Если было написано IN tmp_table - существующая временная (но не внешняя) таблица,
	  *  то здесь будет создана новая временная таблица (например, _data1),
	  *  и данные будут затем в неё скопированы.
	  * Может быть, этого можно избежать.
	  */
}


A
Alexey Milovidov 已提交
476
NamesAndTypesList::iterator ExpressionAnalyzer::findColumn(const String & name, NamesAndTypesList & cols)
477
{
A
Alexey Milovidov 已提交
478
	return std::find_if(cols.begin(), cols.end(),
479
		[&](const NamesAndTypesList::value_type & val) { return val.name == name; });
480 481 482
}


483 484
/// ignore_levels - алиасы в скольки верхних уровнях поддерева нужно игнорировать.
/// Например, при ignore_levels=1 ast не может быть занесен в словарь, но его дети могут.
485
void ExpressionAnalyzer::addASTAliases(ASTPtr & ast, int ignore_levels)
486
{
487
	ASTSelectQuery * select = typeid_cast<ASTSelectQuery *>(ast.get());
488

489
	/// Обход снизу-вверх. Не опускаемся в подзапросы.
490
	for (auto & child : ast->children)
491 492
	{
		int new_ignore_levels = std::max(0, ignore_levels - 1);
A
Alexey Milovidov 已提交
493

494 495
		/// Алиасы верхнего уровня в секции ARRAY JOIN имеют особый смысл, их добавлять не будем
		///  (пропустим сам expression list и его детей).
496
		if (select && child == select->array_join_expression_list)
497
			new_ignore_levels = 2;
A
Alexey Milovidov 已提交
498

499
		if (!typeid_cast<ASTSelectQuery *>(child.get()))
500
			addASTAliases(child, new_ignore_levels);
501 502 503 504 505
	}

	if (ignore_levels > 0)
		return;

A
Alexey Milovidov 已提交
506 507
	String alias = ast->tryGetAlias();
	if (!alias.empty())
508
	{
A
Alexey Milovidov 已提交
509 510
		if (aliases.count(alias) && ast->getTreeID() != aliases[alias]->getTreeID())
			throw Exception("Different expressions with the same alias " + alias, ErrorCodes::MULTIPLE_EXPRESSIONS_FOR_ALIAS);
A
Alexey Milovidov 已提交
511

A
Alexey Milovidov 已提交
512
		aliases[alias] = ast;
513 514 515 516 517 518
	}
}


StoragePtr ExpressionAnalyzer::getTable()
{
519
	if (const ASTSelectQuery * select = typeid_cast<const ASTSelectQuery *>(ast.get()))
520
	{
521
		if (select->table && !typeid_cast<const ASTSelectQuery *>(select->table.get()) && !typeid_cast<const ASTFunction *>(select->table.get()))
522
		{
A
Alexey Milovidov 已提交
523
			String database = select->database
524
				? typeid_cast<const ASTIdentifier &>(*select->database).name
A
Alexey Milovidov 已提交
525
				: "";
526
			const String & table = typeid_cast<const ASTIdentifier &>(*select->table).name;
527 528 529
			return context.tryGetTable(database, table);
		}
	}
A
Alexey Milovidov 已提交
530

531 532 533 534 535 536 537 538
	return StoragePtr();
}


void ExpressionAnalyzer::normalizeTree()
{
	SetOfASTs tmp_set;
	MapOfASTs tmp_map;
539
	normalizeTreeImpl(ast, tmp_map, tmp_set, "");
540 541 542 543 544
}


/// finished_asts - уже обработанные вершины (и на что они заменены)
/// current_asts - вершины в текущем стеке вызовов этого метода
545
/// current_alias - алиас, повешенный на предка ast (самого глубокого из предков с алиасами)
546 547
void ExpressionAnalyzer::normalizeTreeImpl(
	ASTPtr & ast, MapOfASTs & finished_asts, SetOfASTs & current_asts, std::string current_alias)
548 549 550 551 552 553
{
	if (finished_asts.count(ast))
	{
		ast = finished_asts[ast];
		return;
	}
554

555
	ASTPtr initial_ast = ast;
556
	current_asts.insert(initial_ast.get());
557

A
Alexey Milovidov 已提交
558 559 560
	String my_alias = ast->tryGetAlias();
	if (!my_alias.empty())
		current_alias = my_alias;
561

562
	/// rewrite правила, которые действуют при обходе сверху-вниз.
563 564
	bool replaced = false;

565
	ASTFunction * func_node = typeid_cast<ASTFunction *>(ast.get());
566
	if (func_node)
567 568
	{
		/** Нет ли в таблице столбца, название которого полностью совпадает с записью функции?
A
Alexey Milovidov 已提交
569 570
		  * Например, в таблице есть столбец "domain(URL)", и мы запросили domain(URL).
		  */
571
		String function_string = func_node->getColumnName();
572 573 574
		NamesAndTypesList::const_iterator it = findColumn(function_string);
		if (columns.end() != it)
		{
575
			ast = std::make_shared<ASTIdentifier>(func_node->range, function_string);
576
			current_asts.insert(ast.get());
577
			replaced = true;
578
		}
579

580
		/// Может быть указано IN t, где t - таблица, что равносильно IN (SELECT * FROM t).
581
		if (functionIsInOrGlobalInOperator(func_node->name))
582
			if (ASTIdentifier * right = typeid_cast<ASTIdentifier *>(func_node->arguments->children.at(1).get()))
583
				right->kind = ASTIdentifier::Table;
584

585 586 587
		/// Special cases for count function.
		String func_name_lowercase = Poco::toLower(func_node->name);
		if (startsWith(func_name_lowercase, "count"))
588
		{
589 590 591 592 593 594 595 596 597 598 599 600 601
			/// Select implementation of countDistinct based on settings.
			/// Important that it is done as query rewrite. It means rewritten query
			///  will be sent to remote servers during distributed query execution,
			///  and on all remote servers, function implementation will be same.
			if (endsWith(func_node->name, "Distinct") && func_name_lowercase == "countdistinct")
				func_node->name = settings.count_distinct_implementation;

			/// As special case, treat count(*) as count(), not as count(list of all columns).
			if (func_name_lowercase == "count" && func_node->arguments->children.size() == 1
				&& typeid_cast<const ASTAsterisk *>(func_node->arguments->children[0].get()))
			{
				func_node->arguments->children.clear();
			}
602
		}
603
	}
604
	else if (ASTIdentifier * node = typeid_cast<ASTIdentifier *>(ast.get()))
605
	{
606
		if (node->kind == ASTIdentifier::Column)
607
		{
M
Merge  
Michael Kolupaev 已提交
608
			/// Если это алиас, но не родительский алиас (чтобы работали конструкции вроде "SELECT column+1 AS column").
609
			Aliases::const_iterator jt = aliases.find(node->name);
M
Merge  
Michael Kolupaev 已提交
610
			if (jt != aliases.end() && current_alias != node->name)
611
			{
612
				/// Заменим его на соответствующий узел дерева.
613
				if (current_asts.count(jt->second.get()))
614
					throw Exception("Cyclic aliases", ErrorCodes::CYCLIC_ALIASES);
A
Alexey Milovidov 已提交
615
				if (!my_alias.empty() && my_alias != jt->second->getAliasOrColumnName())
616 617 618
				{
					/// В конструкции вроде "a AS b", где a - алиас, нужно перевесить алиас b на результат подстановки алиаса a.
					ast = jt->second->clone();
A
Alexey Milovidov 已提交
619
					ast->setAlias(my_alias);
620 621 622 623 624 625 626
				}
				else
				{
					ast = jt->second;
				}

				replaced = true;
627 628 629
			}
		}
	}
630
	else if (ASTExpressionList * node = typeid_cast<ASTExpressionList *>(ast.get()))
631 632 633 634 635
	{
		/// Заменим * на список столбцов.
		ASTs & asts = node->children;
		for (int i = static_cast<int>(asts.size()) - 1; i >= 0; --i)
		{
636
			if (ASTAsterisk * asterisk = typeid_cast<ASTAsterisk *>(asts[i].get()))
637 638
			{
				ASTs all_columns;
A
Alexey Milovidov 已提交
639
				for (const auto & column_name_type : columns)
640
					all_columns.emplace_back(std::make_shared<ASTIdentifier>(asterisk->range, column_name_type.name));
A
Alexey Milovidov 已提交
641

642 643 644 645 646
				asts.erase(asts.begin() + i);
				asts.insert(asts.begin() + i, all_columns.begin(), all_columns.end());
			}
		}
	}
647
	else if (ASTJoin * node = typeid_cast<ASTJoin *>(ast.get()))
648 649
	{
		/// может быть указано JOIN t, где t - таблица, что равносильно JOIN (SELECT * FROM t).
650
		if (ASTIdentifier * right = typeid_cast<ASTIdentifier *>(node->table.get()))
651 652
			right->kind = ASTIdentifier::Table;
	}
653

654 655 656
	/// Если заменили корень поддерева вызовемся для нового корня снова - на случай, если алиас заменился на алиас.
	if (replaced)
	{
657
		normalizeTreeImpl(ast, finished_asts, current_asts, current_alias);
658 659
		current_asts.erase(initial_ast.get());
		current_asts.erase(ast.get());
660
		finished_asts[initial_ast] = ast;
661 662 663
		return;
	}

664
	/// Рекурсивные вызовы. Не опускаемся в подзапросы.
665 666 667 668 669 670 671 672 673 674
	/// Также не опускаемся в левый аргумент лямбда-выражений, чтобы не заменять формальные параметры
	///  по алиасам в выражениях вида 123 AS x, arrayMap(x -> 1, [2]).

	if (func_node && func_node->name == "lambda")
	{
		/// Пропускаем первый аргумент. Также предполагаем, что у функции lambda не может быть parameters.
		for (size_t i = 1, size = func_node->arguments->children.size(); i < size; ++i)
		{
			auto & child = func_node->arguments->children[i];

675
			if (typeid_cast<const ASTSelectQuery *>(child.get()))
676 677 678 679 680 681 682 683 684
				continue;

			normalizeTreeImpl(child, finished_asts, current_asts, current_alias);
		}
	}
	else
	{
		for (auto & child : ast->children)
		{
685
			if (typeid_cast<const ASTSelectQuery *>(child.get()))
686
				continue;
687

688
			normalizeTreeImpl(child, finished_asts, current_asts, current_alias);
689 690
		}
	}
691

692
	/// Если секция WHERE или HAVING состоит из одного алиаса, ссылку нужно заменить не только в children, но и в where_expression и having_expression.
693
	if (ASTSelectQuery * select = typeid_cast<ASTSelectQuery *>(ast.get()))
694
	{
695
		if (select->prewhere_expression)
696
			normalizeTreeImpl(select->prewhere_expression, finished_asts, current_asts, current_alias);
697
		if (select->where_expression)
698
			normalizeTreeImpl(select->where_expression, finished_asts, current_asts, current_alias);
699
		if (select->having_expression)
700
			normalizeTreeImpl(select->having_expression, finished_asts, current_asts, current_alias);
701
	}
702

M
Merge  
Michael Kolupaev 已提交
703 704
	/// Действия, выполняемые снизу вверх.

705
	if (ASTFunction * node = typeid_cast<ASTFunction *>(ast.get()))
706
	{
707 708 709 710
		if (node->kind == ASTFunction::TABLE_FUNCTION)
		{
		}
		else if (node->name == "lambda")
711
		{
712
			node->kind = ASTFunction::LAMBDA_EXPRESSION;
713 714 715
		}
		else if (context.getAggregateFunctionFactory().isAggregateFunctionName(node->name))
		{
716
			node->kind = ASTFunction::AGGREGATE_FUNCTION;
717
		}
718 719 720 721 722 723 724 725
		else if (node->name == "arrayJoin")
		{
			node->kind = ASTFunction::ARRAY_JOIN;
		}
		else
		{
			node->kind = ASTFunction::FUNCTION;
		}
726 727 728 729

		if (node->parameters && node->kind != ASTFunction::AGGREGATE_FUNCTION)
			throw Exception("The only parametric functions (functions with two separate parenthesis pairs) are aggregate functions"
				", and '" + node->name + "' is not an aggregate function.", ErrorCodes::FUNCTION_CANNOT_HAVE_PARAMETERS);
730
	}
731

732 733
	current_asts.erase(initial_ast.get());
	current_asts.erase(ast.get());
734 735 736
	finished_asts[initial_ast] = ast;
}

737

738 739
void ExpressionAnalyzer::addAliasColumns()
{
740
	if (!select_query)
741 742 743 744 745 746 747 748 749
		return;

	if (!storage)
		return;

	columns.insert(std::end(columns), std::begin(storage->alias_columns), std::end(storage->alias_columns));
}


750 751
void ExpressionAnalyzer::executeScalarSubqueries()
{
752 753 754
	if (!select_query)
		executeScalarSubqueriesImpl(ast);
	else
755
	{
756 757
		for (auto & child : ast->children)
		{
758 759 760 761 762
			/// Не опускаемся в FROM, JOIN, UNION.
			if (child.get() != select_query->table.get()
				&& child.get() != select_query->join.get()
				&& child.get() != select_query->next_union_all.get())
			{
763
				executeScalarSubqueriesImpl(child);
764
			}
765
		}
766
	}
767 768
}

769

770
static ASTPtr addTypeConversion(std::unique_ptr<ASTLiteral> && ast, const String & type_name)
771
{
772
	auto func = std::make_shared<ASTFunction>(ast->range);
773 774 775 776
	ASTPtr res = func;
	func->alias = ast->alias;
	ast->alias.clear();
	func->kind = ASTFunction::FUNCTION;
777
	func->name = "CAST";
778
	auto exp_list = std::make_shared<ASTExpressionList>(ast->range);
779 780
	func->arguments = exp_list;
	func->children.push_back(func->arguments);
781
	exp_list->children.emplace_back(ast.release());
782
	exp_list->children.emplace_back(std::make_shared<ASTLiteral>(StringRange(), type_name));
783 784 785 786
	return res;
}


787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
void ExpressionAnalyzer::executeScalarSubqueriesImpl(ASTPtr & ast)
{
	/** Заменяем подзапросы, возвращающие ровно одну строку
	  * ("скалярные" подзапросы) на соответствующие константы.
	  *
	  * Если подзапрос возвращает более одного столбца, то он заменяется на кортеж констант.
	  *
	  * Особенности:
	  *
	  * Замена происходит во время анализа запроса, а не во время основной стадии выполнения.
	  * Это значит, что не будет работать индикатор прогресса во время выполнения этих запросов,
	  *  а также такие запросы нельзя будет прервать.
	  *
	  * Зато результат запросов может быть использован для индекса в таблице.
	  *
	  * Скалярные подзапросы выполняются на сервере-инициаторе запроса.
	  * На удалённые серверы запрос отправляется с уже подставленными константами.
	  */

	if (ASTSubquery * subquery = typeid_cast<ASTSubquery *>(ast.get()))
	{
		Context subquery_context = context;
		Settings subquery_settings = context.getSettings();
		subquery_settings.limits.max_result_rows = 1;
		subquery_settings.extremes = 0;
		subquery_context.setSettings(subquery_settings);

		ASTPtr query = subquery->children.at(0);
		BlockIO res = InterpreterSelectQuery(query, subquery_context, QueryProcessingStage::Complete, subquery_depth + 1).execute();

		Block block;
		try
		{
			block = res.in->read();

			if (!block)
				throw Exception("Scalar subquery returned empty result", ErrorCodes::INCORRECT_RESULT_OF_SCALAR_SUBQUERY);

			if (block.rows() != 1 || res.in->read())
				throw Exception("Scalar subquery returned more than one row", ErrorCodes::INCORRECT_RESULT_OF_SCALAR_SUBQUERY);
		}
		catch (const Exception & e)
		{
			if (e.code() == ErrorCodes::TOO_MUCH_ROWS)
				throw Exception("Scalar subquery returned more than one row", ErrorCodes::INCORRECT_RESULT_OF_SCALAR_SUBQUERY);
			else
				throw;
		}

		size_t columns = block.columns();
		if (columns == 1)
		{
839
			auto lit = std::make_unique<ASTLiteral>(ast->range, (*block.getByPosition(0).column)[0]);
840
			lit->alias = subquery->alias;
841
			ast = addTypeConversion(std::move(lit), block.getByPosition(0).type->getName());
842 843 844
		}
		else
		{
845
			auto tuple = std::make_shared<ASTFunction>(ast->range);
846
			tuple->alias = subquery->alias;
847 848 849
			ast = tuple;
			tuple->kind = ASTFunction::FUNCTION;
			tuple->name = "tuple";
850
			auto exp_list = std::make_shared<ASTExpressionList>(ast->range);
851
			tuple->arguments = exp_list;
852
			tuple->children.push_back(tuple->arguments);
853 854 855

			exp_list->children.resize(columns);
			for (size_t i = 0; i < columns; ++i)
856 857
			{
				exp_list->children[i] = addTypeConversion(
858
					std::make_unique<ASTLiteral>(ast->range, (*block.getByPosition(i).column)[0]),
859 860
					block.getByPosition(i).type->getName());
			}
861 862 863
		}
	}
	else
864 865 866 867 868
	{
		/** Не опускаемся в подзапросы в аргументах IN.
		  * Но если аргумент - не подзапрос, то глубже внутри него могут быть подзапросы, и в них надо опускаться.
		  */
		ASTFunction * func = typeid_cast<ASTFunction *>(ast.get());
869

870 871 872 873 874
		if (func && func->kind == ASTFunction::FUNCTION
			&& functionIsInOrGlobalInOperator(func->name))
		{
			for (auto & child : ast->children)
			{
875
				if (child != func->arguments)
876 877 878 879 880 881 882 883 884 885 886
					executeScalarSubqueriesImpl(child);
				else
					for (size_t i = 0, size = func->arguments->children.size(); i < size; ++i)
						if (i != 1 || !typeid_cast<ASTSubquery *>(func->arguments->children[i].get()))
							executeScalarSubqueriesImpl(func->arguments->children[i]);
			}
		}
		else
			for (auto & child : ast->children)
				executeScalarSubqueriesImpl(child);
	}
887 888 889
}


890
void ExpressionAnalyzer::optimizeGroupBy()
891 892 893 894
{
	if (!(select_query && select_query->group_expression_list))
		return;

895 896 897
	const auto is_literal = [] (const ASTPtr& ast) {
		return typeid_cast<const ASTLiteral*>(ast.get());
	};
898

899
	auto & group_exprs = select_query->group_expression_list->children;
900

901
	/// removes expression at index idx by making it last one and calling .pop_back()
A
Alexey Milovidov 已提交
902 903
	const auto remove_expr_at_index = [&group_exprs] (const size_t idx)
	{
904
		if (idx < group_exprs.size() - 1)
A
Merge  
Andrey Mironov 已提交
905
			std::swap(group_exprs[idx], group_exprs.back());
906

907 908
		group_exprs.pop_back();
	};
909

A
Andrey Mironov 已提交
910
	/// iterate over each GROUP BY expression, eliminate injective function calls and literals
911
	for (size_t i = 0; i < group_exprs.size();)
912
	{
913
		if (const auto function = typeid_cast<ASTFunction *>(group_exprs[i].get()))
914 915
		{
			/// assert function is injective
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
			if (possibly_injective_function_names.count(function->name))
			{
				/// do not handle semantic errors here
				if (function->arguments->children.size() < 2)
				{
					++i;
					continue;
				}

				const auto & dict_name = typeid_cast<const ASTLiteral &>(*function->arguments->children[0])
					.value.safeGet<String>();

				const auto & dict_ptr = context.getExternalDictionaries().getDictionary(dict_name);

				const auto & attr_name = typeid_cast<const ASTLiteral &>(*function->arguments->children[1])
					.value.safeGet<String>();

				if (!dict_ptr->isInjective(attr_name))
				{
					++i;
					continue;
				}
			}
			else if (!injective_function_names.count(function->name))
940 941
			{
				++i;
942
				continue;
943
			}
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958

			/// copy shared pointer to args in order to ensure lifetime
			auto args_ast = function->arguments;

			/** remove function call and take a step back to ensure
			  * next iteration does not skip not yet processed data
			  */
			remove_expr_at_index(i);

			/// copy non-literal arguments
			std::remove_copy_if(
				std::begin(args_ast->children), std::end(args_ast->children),
				std::back_inserter(group_exprs), is_literal
			);
		}
959 960 961
		else if (is_literal(group_exprs[i]))
		{
			remove_expr_at_index(i);
962 963 964 965 966
		}
		else
		{
			/// if neither a function nor literal - advance to next expression
			++i;
967
		}
968
	}
969 970

	if (group_exprs.empty())
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
	{
		/** Нельзя полностью убирать GROUP BY. Потому что если при этом даже агрегатных функций не было, то получится, что не будет агрегации.
		  * Вместо этого оставим GROUP BY const.
		  * Далее см. удаление констант в методе analyzeAggregation.
		  */

		/// Нужно вставить константу, которая не является именем столбца таблицы. Такой случай редкий, но бывает.
		UInt64 unused_column = 0;
		String unused_column_name = toString(unused_column);

		while (columns.end() != std::find_if(columns.begin(), columns.end(),
			[&unused_column_name](const NameAndTypePair & name_type) { return name_type.name == unused_column_name; }))
		{
			++unused_column;
			unused_column_name = toString(unused_column);
		}

988 989
		select_query->group_expression_list = std::make_shared<ASTExpressionList>();
		select_query->group_expression_list->children.emplace_back(std::make_shared<ASTLiteral>(StringRange(), UInt64(unused_column)));
990
	}
991 992 993
}


994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
void ExpressionAnalyzer::optimizeOrderBy()
{
	if (!(select_query && select_query->order_expression_list))
		return;

	/// Уникализируем условия сортировки.
	using NameAndLocale = std::pair<std::string, std::string>;
	std::set<NameAndLocale> elems_set;

	ASTs & elems = select_query->order_expression_list->children;
	ASTs unique_elems;
	unique_elems.reserve(elems.size());

	for (const auto & elem : elems)
	{
		String name = elem->children.front()->getColumnName();
		const ASTOrderByElement & order_by_elem = typeid_cast<const ASTOrderByElement &>(*elem);

		if (elems_set.emplace(
			std::piecewise_construct,
			std::forward_as_tuple(name),
			std::forward_as_tuple(order_by_elem.collator ? order_by_elem.collator->getLocale() : std::string())).second)
		{
			unique_elems.emplace_back(elem);
		}
	}

	if (unique_elems.size() < elems.size())
		elems = unique_elems;
}


1026
void ExpressionAnalyzer::makeSetsForIndex()
P
Pavel Kartavyy 已提交
1027
{
1028
	if (storage && ast && storage->supportsIndexForIn())
A
Alexey Milovidov 已提交
1029
		makeSetsForIndexImpl(ast, storage->getSampleBlock());
P
Pavel Kartavyy 已提交
1030 1031
}

A
Alexey Milovidov 已提交
1032
void ExpressionAnalyzer::makeSetsForIndexImpl(ASTPtr & node, const Block & sample_block)
P
Pavel Kartavyy 已提交
1033 1034
{
	for (auto & child : node->children)
A
Alexey Milovidov 已提交
1035
		makeSetsForIndexImpl(child, sample_block);
P
Pavel Kartavyy 已提交
1036

1037
	ASTFunction * func = typeid_cast<ASTFunction *>(node.get());
1038
	if (func && func->kind == ASTFunction::FUNCTION && functionIsInOperator(func->name))
P
Pavel Kartavyy 已提交
1039 1040
	{
		IAST & args = *func->arguments;
1041
		ASTPtr & arg = args.children.at(1);
P
Pavel Kartavyy 已提交
1042

1043
		if (!typeid_cast<ASTSet *>(arg.get()) && !typeid_cast<ASTSubquery *>(arg.get()) && !typeid_cast<ASTIdentifier *>(arg.get()))
1044 1045 1046
		{
			try
			{
1047
				makeExplicitSet(func, sample_block, true);
1048 1049 1050 1051 1052 1053 1054 1055
			}
			catch (const DB::Exception & e)
			{
				/// в sample_block нет колонок, которые добаляет getActions
				if (e.code() != ErrorCodes::NOT_FOUND_COLUMN_IN_BLOCK)
					throw;
			}
		}
P
Pavel Kartavyy 已提交
1056 1057
	}
}
1058

1059

1060
static std::shared_ptr<InterpreterSelectQuery> interpretSubquery(
1061
	ASTPtr & subquery_or_table_name, const Context & context, size_t subquery_depth, const Names & required_columns)
1062
{
1063
	/// Подзапрос или имя таблицы. Имя таблицы аналогично подзапросу SELECT * FROM t.
1064 1065
	const ASTSubquery * subquery = typeid_cast<const ASTSubquery *>(subquery_or_table_name.get());
	const ASTIdentifier * table = typeid_cast<const ASTIdentifier *>(subquery_or_table_name.get());
1066

1067 1068
	if (!subquery && !table)
		throw Exception("IN/JOIN supports only SELECT subqueries.", ErrorCodes::BAD_ARGUMENTS);
1069

1070 1071 1072 1073
	/** Для подзапроса в секции IN/JOIN не действуют ограничения на максимальный размер результата.
	  * Так как результат этого поздапроса - ещё не результат всего запроса.
	  * Вместо этого работают ограничения
	  *  max_rows_in_set, max_bytes_in_set, set_overflow_mode,
1074 1075
	  *  max_rows_in_join, max_bytes_in_join, join_overflow_mode,
	  *  которые проверяются отдельно (в объектах Set, Join).
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087
	  */
	Context subquery_context = context;
	Settings subquery_settings = context.getSettings();
	subquery_settings.limits.max_result_rows = 0;
	subquery_settings.limits.max_result_bytes = 0;
	/// Вычисление extremes не имеет смысла и не нужно (если его делать, то в результате всего запроса могут взяться extremes подзапроса).
	subquery_settings.extremes = 0;
	subquery_context.setSettings(subquery_settings);

	ASTPtr query;
	if (table)
	{
1088
		/// create ASTSelectQuery for "SELECT * FROM table" as if written by hand
1089
		const auto select_query = std::make_shared<ASTSelectQuery>();
1090
		query = select_query;
1091

1092
		const auto select_expression_list = std::make_shared<ASTExpressionList>();
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
		select_query->select_expression_list = select_expression_list;
		select_query->children.emplace_back(select_query->select_expression_list);

		/// get columns list for target table
		const auto & storage = context.getTable("", table->name);
		const auto & columns = storage->getColumnsListNonMaterialized();
		select_expression_list->children.reserve(columns.size());

		/// manually substitute column names in place of asterisk
		for (const auto & column : columns)
1103 1104
			select_expression_list->children.emplace_back(std::make_shared<ASTIdentifier>(
				StringRange{}, column.name));
1105 1106 1107

		select_query->table = subquery_or_table_name;
		select_query->children.emplace_back(select_query->table);
1108 1109
	}
	else
1110
	{
1111 1112
		query = subquery->children.at(0);

1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
		/** В подзапросе могут быть указаны столбцы с одинаковыми именами. Например, SELECT x, x FROM t
		  * Это плохо, потому что результат такого запроса нельзя сохранить в таблицу, потому что в таблице не может быть одноимённых столбцов.
		  * Сохранение в таблицу требуется для GLOBAL-подзапросов.
		  *
		  * Чтобы избежать такой ситуации, будем переименовывать одинаковые столбцы.
		  */

		std::set<std::string> all_column_names;
		std::set<std::string> assigned_column_names;

		if (ASTSelectQuery * select = typeid_cast<ASTSelectQuery *>(query.get()))
		{
			for (auto & expr : select->select_expression_list->children)
				all_column_names.insert(expr->getAliasOrColumnName());

			for (auto & expr : select->select_expression_list->children)
			{
				auto name = expr->getAliasOrColumnName();

				if (!assigned_column_names.insert(name).second)
				{
					size_t i = 1;
					while (all_column_names.end() != all_column_names.find(name + "_" + toString(i)))
						++i;

					name = name + "_" + toString(i);
					expr = expr->clone();	/// Отменяет склейку одинаковых выражений в дереве.
					expr->setAlias(name);

					all_column_names.insert(name);
					assigned_column_names.insert(name);
				}
			}
		}
	}

1149
	if (required_columns.empty())
1150 1151
		return std::make_shared<InterpreterSelectQuery>(
			query, subquery_context, QueryProcessingStage::Complete, subquery_depth + 1);
1152
	else
1153 1154
		return std::make_shared<InterpreterSelectQuery>(
			query, subquery_context, required_columns, QueryProcessingStage::Complete, subquery_depth + 1);
1155 1156
}

1157

1158
void ExpressionAnalyzer::makeSet(ASTFunction * node, const Block & sample_block)
1159
{
1160
	/** Нужно преобразовать правый аргумент в множество.
1161
	  * Это может быть имя таблицы, значение, перечисление значений или подзапрос.
1162 1163 1164
	  * Перечисление значений парсится как функция tuple.
	  */
	IAST & args = *node->arguments;
1165
	ASTPtr & arg = args.children.at(1);
1166

1167
	/// Уже преобразовали.
1168
	if (typeid_cast<ASTSet *>(arg.get()))
1169
		return;
1170

1171
	/// Если подзапрос или имя таблицы для SELECT.
1172 1173
	ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(arg.get());
	if (typeid_cast<ASTSubquery *>(arg.get()) || identifier)
1174
	{
1175 1176
		/// Получаем поток блоков для подзапроса. Создаём Set и кладём на место подзапроса.
		String set_id = arg->getColumnName();
1177
		auto ast_set = std::make_shared<ASTSet>(set_id);
1178
		ASTPtr ast_set_ptr = ast_set;
1179

1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
		/// Особый случай - если справа оператора IN указано имя таблицы, при чём, таблица имеет тип Set (заранее подготовленное множество).
		/// TODO В этом синтаксисе не поддерживается указание имени БД.
		if (identifier)
		{
			StoragePtr table = context.tryGetTable("", identifier->name);

			if (table)
			{
				StorageSet * storage_set = typeid_cast<StorageSet *>(table.get());

				if (storage_set)
				{
					SetPtr & set = storage_set->getSet();
					ast_set->set = set;
					arg = ast_set_ptr;
					return;
				}
			}
		}

1200
		SubqueryForSet & subquery_for_set = subqueries_for_sets[set_id];
1201

1202
		/// Если уже создали Set с таким же подзапросом/таблицей.
1203
		if (subquery_for_set.set)
1204
		{
1205 1206 1207
			ast_set->set = subquery_for_set.set;
			arg = ast_set_ptr;
			return;
1208
		}
1209

1210
		ast_set->set = std::make_shared<Set>(settings.limits);
A
Alexey Milovidov 已提交
1211

1212 1213 1214 1215 1216 1217
		/** Для GLOBAL IN-ов происходит следующее:
		  * - в функции addExternalStorage подзапрос IN (SELECT ...) заменяется на IN _data1,
		  *   в объекте subquery_for_set выставляется этот подзапрос в качестве source и временная таблица _data1 в качестве table.
		  * - в этой функции видно выражение IN _data1.
		  */
		if (!subquery_for_set.source)
1218
		{
1219
			auto interpreter = interpretSubquery(arg, context, subquery_depth, {});
1220 1221
			subquery_for_set.source = std::make_shared<LazyBlockInputStream>(
				[interpreter]() mutable { return interpreter->execute().in; });
1222
			subquery_for_set.source_sample = interpreter->getSampleBlock();
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250

			/** Зачем используется LazyBlockInputStream?
			  *
			  * Дело в том, что при обработке запроса вида
			  *  SELECT ... FROM remote_test WHERE column GLOBAL IN (subquery),
			  *  если распределённая таблица remote_test содержит в качестве одного из серверов localhost,
			  *  то запрос будет ещё раз интерпретирован локально (а не отправлен по TCP, как в случае удалённого сервера).
			  *
			  * Конвейер выполнения запроса будет такой:
			  * CreatingSets
			  *  выполнение подзапроса subquery, заполнение временной таблицы _data1 (1)
			  *  CreatingSets
			  *   чтение из таблицы _data1, создание множества (2)
			  *   чтение из таблицы, подчинённой remote_test.
			  *
			  * (Вторая часть конвейера под CreatingSets - это повторная интерпретация запроса внутри StorageDistributed,
			  *  запрос отличается тем, что имя БД и таблицы заменены на подчинённые, а также подзапрос заменён на _data1.)
			  *
			  * Но при создании конвейера, при создании источника (2), будет обнаружено, что таблица _data1 пустая
			  *  (потому что запрос ещё не начал выполняться), и будет возвращён в качестве источника пустой источник.
			  * И затем, при выполнении запроса, на шаге (2), будет создано пустое множество.
			  *
			  * Поэтому, мы делаем инициализацию шага (2) ленивой
			  *  - чтобы она произошла только после выполнения шага (1), на котором нужная таблица будет заполнена.
			  *
			  * Замечание: это решение не очень хорошее, надо подумать лучше.
			  */
		}
1251

1252
		subquery_for_set.set = ast_set->set;
1253
		arg = ast_set_ptr;
1254
	}
1255
	else
1256
	{
A
Alexey Milovidov 已提交
1257
		/// Явное перечисление значений в скобках.
P
Pavel Kartavyy 已提交
1258
		makeExplicitSet(node, sample_block, false);
P
Pavel Kartavyy 已提交
1259 1260 1261 1262
	}
}

/// Случай явного перечисления значений.
P
Pavel Kartavyy 已提交
1263
void ExpressionAnalyzer::makeExplicitSet(ASTFunction * node, const Block & sample_block, bool create_ordered_set)
P
Pavel Kartavyy 已提交
1264
{
1265
	IAST & args = *node->arguments;
1266 1267 1268 1269

	if (args.children.size() != 2)
		throw Exception("Wrong number of arguments passed to function in", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);

1270
	ASTPtr & arg = args.children.at(1);
1271

1272 1273
	DataTypes set_element_types;
	ASTPtr & left_arg = args.children.at(0);
1274

1275
	ASTFunction * left_arg_tuple = typeid_cast<ASTFunction *>(left_arg.get());
1276

A
Alexey Milovidov 已提交
1277 1278 1279 1280 1281
	/** NOTE If tuple in left hand side specified non-explicitly
	  * Example: identity((a, b)) IN ((1, 2), (3, 4))
	  *  instead of        (a, b)) IN ((1, 2), (3, 4))
	  * then set creation of set doesn't work correctly.
	  */
1282 1283 1284
	if (left_arg_tuple && left_arg_tuple->name == "tuple")
	{
		for (const auto & arg : left_arg_tuple->arguments->children)
1285
		{
1286
			const auto & data_type = sample_block.getByName(arg->getColumnName()).type;
1287

1288 1289 1290
			/// @note prevent crash in query: SELECT (1, [1]) in (1, 1)
			if (const auto array = typeid_cast<const DataTypeArray * >(data_type.get()))
				throw Exception("Incorrect element of tuple: " + array->getName(), ErrorCodes::INCORRECT_ELEMENT_OF_SET);
1291

1292
			set_element_types.push_back(data_type);
1293
		}
1294 1295 1296 1297
	}
	else
	{
		DataTypePtr left_type = sample_block.getByName(left_arg->getColumnName()).type;
1298
		if (DataTypeArray * array_type = typeid_cast<DataTypeArray *>(left_type.get()))
1299
			set_element_types.push_back(array_type->getNestedType());
1300
		else
1301 1302
			set_element_types.push_back(left_type);
	}
1303

1304 1305 1306
	/// Отличим случай x in (1, 2) от случая x in 1 (он же x in (1)).
	bool single_value = false;
	ASTPtr elements_ast = arg;
1307

1308
	if (ASTFunction * set_func = typeid_cast<ASTFunction *>(arg.get()))
1309
	{
1310 1311
		if (set_func->name == "tuple")
		{
1312 1313 1314
			if (set_func->arguments->children.empty())
			{
				/// Пустое множество.
1315
				elements_ast = set_func->arguments;
1316 1317 1318
			}
			else
			{
A
Alexey Milovidov 已提交
1319
				/// Отличим случай (x, y) in ((1, 2), (3, 4)) от случая (x, y) in (1, 2).
1320
				ASTFunction * any_element = typeid_cast<ASTFunction *>(set_func->arguments->children.at(0).get());
1321 1322 1323 1324 1325
				if (set_element_types.size() >= 2 && (!any_element || any_element->name != "tuple"))
					single_value = true;
				else
					elements_ast = set_func->arguments;
			}
1326 1327 1328 1329 1330 1331 1332
		}
		else
		{
			if (set_element_types.size() >= 2)
				throw Exception("Incorrect type of 2nd argument for function " + node->name
					+ ". Must be subquery or set of " + toString(set_element_types.size()) + "-element tuples.",
					ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
1333

1334
			single_value = true;
1335
		}
1336
	}
1337
	else if (typeid_cast<ASTLiteral *>(arg.get()))
1338 1339 1340 1341 1342 1343 1344 1345
	{
		single_value = true;
	}
	else
	{
		throw Exception("Incorrect type of 2nd argument for function " + node->name + ". Must be subquery or set of values.",
						ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
	}
1346

1347 1348
	if (single_value)
	{
1349
		ASTPtr exp_list = std::make_shared<ASTExpressionList>();
1350 1351 1352 1353
		exp_list->children.push_back(elements_ast);
		elements_ast = exp_list;
	}

1354
	auto ast_set = std::make_shared<ASTSet>(arg->getColumnName());
1355
	ast_set->set = std::make_shared<Set>(settings.limits);
1356
	ast_set->is_explicit = true;
1357
	ast_set->set->createFromAST(set_element_types, elements_ast, context, create_ordered_set);
1358
	arg = ast_set;
1359 1360 1361
}


1362
static String getUniqueName(const Block & block, const String & prefix)
1363 1364
{
	int i = 1;
1365
	while (block.has(prefix + toString(i)))
1366
		++i;
1367
	return prefix + toString(i);
1368 1369 1370
}


A
Alexey Milovidov 已提交
1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384
/** Для getActionsImpl.
  * Стек из ExpressionActions, соответствующих вложенным лямбда-выражениям.
  * Новое действие нужно добавлять на самый высокий возможный уровень.
  * Например, в выражении "select arrayMap(x -> x + column1 * column2, array1)"
  *  вычисление произведения нужно делать вне лямбда-выражения (оно не зависит от x), а вычисление суммы - внутри (зависит от x).
  */
struct ExpressionAnalyzer::ScopeStack
{
	struct Level
	{
		ExpressionActionsPtr actions;
		NameSet new_columns;
	};

1385
	using Levels = std::vector<Level>;
A
Alexey Milovidov 已提交
1386 1387 1388 1389

	Levels stack;
	Settings settings;

1390
	ScopeStack(const ExpressionActionsPtr & actions, const Settings & settings_)
A
Alexey Milovidov 已提交
1391 1392
		: settings(settings_)
	{
1393
		stack.emplace_back();
1394
		stack.back().actions = actions;
1395 1396 1397 1398

		const Block & sample_block = actions->getSampleBlock();
		for (size_t i = 0, size = sample_block.columns(); i < size; ++i)
			stack.back().new_columns.insert(sample_block.unsafeGetByPosition(i).name);
A
Alexey Milovidov 已提交
1399 1400 1401 1402
	}

	void pushLevel(const NamesAndTypesList & input_columns)
	{
1403
		stack.emplace_back();
A
Alexey Milovidov 已提交
1404 1405
		Level & prev = stack[stack.size() - 2];

1406
		ColumnsWithTypeAndName all_columns;
A
Alexey Milovidov 已提交
1407 1408 1409 1410
		NameSet new_names;

		for (NamesAndTypesList::const_iterator it = input_columns.begin(); it != input_columns.end(); ++it)
		{
1411 1412 1413
			all_columns.emplace_back(nullptr, it->type, it->name);
			new_names.insert(it->name);
			stack.back().new_columns.insert(it->name);
A
Alexey Milovidov 已提交
1414 1415
		}

1416 1417
		const Block & prev_sample_block = prev.actions->getSampleBlock();
		for (size_t i = 0, size = prev_sample_block.columns(); i < size; ++i)
A
Alexey Milovidov 已提交
1418
		{
1419
			const ColumnWithTypeAndName & col = prev_sample_block.unsafeGetByPosition(i);
1420 1421
			if (!new_names.count(col.name))
				all_columns.push_back(col);
A
Alexey Milovidov 已提交
1422 1423
		}

1424
		stack.back().actions = std::make_shared<ExpressionActions>(all_columns, settings);
A
Alexey Milovidov 已提交
1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451
	}

	size_t getColumnLevel(const std::string & name)
	{
		for (int i = static_cast<int>(stack.size()) - 1; i >= 0; --i)
			if (stack[i].new_columns.count(name))
				return i;

		throw Exception("Unknown identifier: " + name, ErrorCodes::UNKNOWN_IDENTIFIER);
	}

	void addAction(const ExpressionAction & action, const Names & additional_required_columns = Names())
	{
		size_t level = 0;
		for (size_t i = 0; i < additional_required_columns.size(); ++i)
			level = std::max(level, getColumnLevel(additional_required_columns[i]));
		Names required = action.getNeededColumns();
		for (size_t i = 0; i < required.size(); ++i)
			level = std::max(level, getColumnLevel(required[i]));

		Names added;
		stack[level].actions->add(action, added);

		stack[level].new_columns.insert(added.begin(), added.end());

		for (size_t i = 0; i < added.size(); ++i)
		{
1452
			const ColumnWithTypeAndName & col = stack[level].actions->getSampleBlock().getByName(added[i]);
A
Alexey Milovidov 已提交
1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464
			for (size_t j = level + 1; j < stack.size(); ++j)
				stack[j].actions->addInput(col);
		}
	}

	ExpressionActionsPtr popLevel()
	{
		ExpressionActionsPtr res = stack.back().actions;
		stack.pop_back();
		return res;
	}

1465
	const Block & getSampleBlock() const
A
Alexey Milovidov 已提交
1466 1467 1468 1469 1470 1471
	{
		return stack.back().actions->getSampleBlock();
	}
};


1472
void ExpressionAnalyzer::getRootActions(ASTPtr ast, bool no_subqueries, bool only_consts, ExpressionActionsPtr & actions)
1473 1474
{
	ScopeStack scopes(actions, settings);
1475
	getActionsImpl(ast, no_subqueries, only_consts, scopes);
1476
	actions = scopes.popLevel();
1477 1478 1479
}


1480 1481
void ExpressionAnalyzer::getArrayJoinedColumns()
{
1482 1483
	if (select_query && select_query->array_join_expression_list)
	{
1484
		ASTs & array_join_asts = select_query->array_join_expression_list->children;
1485
		for (const auto & ast : array_join_asts)
1486
		{
1487 1488
			const String nested_table_name = ast->getColumnName();
			const String nested_table_alias = ast->getAliasOrColumnName();
1489

1490
			if (nested_table_alias == nested_table_name && !typeid_cast<const ASTIdentifier *>(ast.get()))
1491 1492 1493 1494
				throw Exception("No alias for non-trivial value in ARRAY JOIN: " + nested_table_name, ErrorCodes::ALIAS_REQUIRED);

			if (array_join_alias_to_name.count(nested_table_alias) || aliases.count(nested_table_alias))
				throw Exception("Duplicate alias " + nested_table_alias, ErrorCodes::MULTIPLE_EXPRESSIONS_FOR_ALIAS);
1495

1496
			array_join_alias_to_name[nested_table_alias] = nested_table_name;
1497
			array_join_name_to_alias[nested_table_name] = nested_table_alias;
1498 1499 1500
		}

		ASTs & query_asts = select_query->children;
1501
		for (const auto & ast : query_asts)
1502 1503 1504 1505 1506
		{
			/// Не опускаемся в подзапросы и UNION.
			if (typeid_cast<const ASTSelectQuery *>(ast.get()))
				continue;

1507 1508
			if (ast != select_query->array_join_expression_list)
				getArrayJoinedColumnsImpl(ast);
1509
		}
1510 1511 1512

		/// Если результат ARRAY JOIN не используется, придется все равно по-ARRAY-JOIN-ить какой-нибудь столбец,
		/// чтобы получить правильное количество строк.
1513
		if (array_join_result_to_source.empty())
1514
		{
1515
			ASTPtr expr = select_query->array_join_expression_list->children.at(0);
1516
			String source_name = expr->getColumnName();
A
Alexey Milovidov 已提交
1517
			String result_name = expr->getAliasOrColumnName();
A
Alexey Milovidov 已提交
1518

1519
			/// Это массив.
1520
			if (!typeid_cast<ASTIdentifier *>(expr.get()) || findColumn(source_name, columns) != columns.end())
1521
			{
1522
				array_join_result_to_source[result_name] = source_name;
1523 1524 1525 1526
			}
			else /// Это вложенная таблица.
			{
				bool found = false;
A
Alexey Milovidov 已提交
1527
				for (const auto & column_name_type : columns)
1528
				{
1529 1530
					String table_name = DataTypeNested::extractNestedTableName(column_name_type.name);
					String column_name = DataTypeNested::extractNestedColumnName(column_name_type.name);
1531 1532
					if (table_name == source_name)
					{
1533
						array_join_result_to_source[DataTypeNested::concatenateNestedName(result_name, column_name)] = column_name_type.name;
1534 1535 1536 1537
						found = true;
						break;
					}
				}
1538 1539
				if (!found)
					throw Exception("No columns in nested table " + source_name, ErrorCodes::EMPTY_NESTED_TABLE);
1540 1541
			}
		}
1542
	}
1543 1544 1545
}


1546
/// Заполняет array_join_result_to_source: по каким столбцам-массивам размножить, и как их после этого назвать.
1547
void ExpressionAnalyzer::getArrayJoinedColumnsImpl(ASTPtr ast)
1548
{
1549
	if (ASTIdentifier * node = typeid_cast<ASTIdentifier *>(ast.get()))
1550
	{
1551 1552 1553
		if (node->kind == ASTIdentifier::Column)
		{
			String table_name = DataTypeNested::extractNestedTableName(node->name);
1554

1555
			if (array_join_alias_to_name.count(node->name))
1556 1557 1558 1559
			{
				/// Был написан ARRAY JOIN со столбцом-массивом. Пример: SELECT K1 FROM ... ARRAY JOIN ParsedParams.Key1 AS K1
				array_join_result_to_source[node->name] = array_join_alias_to_name[node->name];	/// K1 -> ParsedParams.Key1
			}
1560 1561
			else if (array_join_alias_to_name.count(table_name))
			{
1562 1563 1564
				/// Был написан ARRAY JOIN с вложенной таблицей. Пример: SELECT PP.Key1 FROM ... ARRAY JOIN ParsedParams AS PP
				String nested_column = DataTypeNested::extractNestedColumnName(node->name);	/// Key1
				array_join_result_to_source[node->name]	/// PP.Key1 -> ParsedParams.Key1
1565 1566
					= DataTypeNested::concatenateNestedName(array_join_alias_to_name[table_name], nested_column);
			}
1567 1568 1569 1570 1571 1572 1573 1574 1575 1576
			else if (array_join_name_to_alias.count(table_name))
			{
				/** Пример: SELECT ParsedParams.Key1 FROM ... ARRAY JOIN ParsedParams AS PP.
				  * То есть, в запросе используется исходный массив, размноженный по самому себе.
				  */

				String nested_column = DataTypeNested::extractNestedColumnName(node->name);	/// Key1
				array_join_result_to_source[	/// PP.Key1 -> ParsedParams.Key1
					DataTypeNested::concatenateNestedName(array_join_name_to_alias[table_name], nested_column)] = node->name;
			}
1577
		}
1578 1579 1580
	}
	else
	{
1581
		for (auto & child : ast->children)
1582
			if (!typeid_cast<const ASTSelectQuery *>(child.get()))
1583
				getArrayJoinedColumnsImpl(child);
1584 1585 1586 1587 1588
	}
}


void ExpressionAnalyzer::getActionsImpl(ASTPtr ast, bool no_subqueries, bool only_consts, ScopeStack & actions_stack)
1589 1590
{
	/// Если результат вычисления уже есть в блоке.
1591
	if ((typeid_cast<ASTFunction *>(ast.get()) || typeid_cast<ASTLiteral *>(ast.get()))
1592
		&& actions_stack.getSampleBlock().has(ast->getColumnName()))
1593
		return;
1594

1595
	if (ASTIdentifier * node = typeid_cast<ASTIdentifier *>(ast.get()))
1596 1597 1598 1599 1600
	{
		std::string name = node->getColumnName();
		if (!only_consts && !actions_stack.getSampleBlock().has(name))
		{
			/// Запрошенного столбца нет в блоке.
1601
			/// Если такой столбец есть в таблице, значит пользователь наверно забыл окружить его агрегатной функцией или добавить в GROUP BY.
1602 1603

			bool found = false;
A
Alexey Milovidov 已提交
1604
			for (const auto & column_name_type : columns)
1605
				if (column_name_type.name == name)
1606 1607 1608 1609
					found = true;

			if (found)
				throw Exception("Column " + name + " is not under aggregate function and not in GROUP BY.",
1610
					ErrorCodes::NOT_AN_AGGREGATE);
1611 1612
		}
	}
1613
	else if (ASTFunction * node = typeid_cast<ASTFunction *>(ast.get()))
1614
	{
1615
		if (node->kind == ASTFunction::LAMBDA_EXPRESSION)
1616
			throw Exception("Unexpected lambda expression", ErrorCodes::UNEXPECTED_EXPRESSION);
1617

1618
		/// Функция arrayJoin.
1619 1620 1621 1622
		if (node->kind == ASTFunction::ARRAY_JOIN)
		{
			if (node->arguments->children.size() != 1)
				throw Exception("arrayJoin requires exactly 1 argument", ErrorCodes::TYPE_MISMATCH);
1623

1624
			ASTPtr arg = node->arguments->children.at(0);
1625
			getActionsImpl(arg, no_subqueries, only_consts, actions_stack);
1626
			if (!only_consts)
1627
			{
1628
				String result_name = node->getColumnName();
1629
				actions_stack.addAction(ExpressionAction::copyColumn(arg->getColumnName(), result_name));
1630 1631
				NameSet joined_columns;
				joined_columns.insert(result_name);
1632
				actions_stack.addAction(ExpressionAction::arrayJoin(joined_columns, false));
1633
			}
1634

1635 1636
			return;
		}
1637

1638
		if (node->kind == ASTFunction::FUNCTION)
1639
		{
1640
			if (functionIsInOrGlobalInOperator(node->name))
1641 1642 1643
			{
				if (!no_subqueries)
				{
1644
					/// Найдем тип первого аргумента (потом getActionsImpl вызовется для него снова и ни на что не повлияет).
1645
					getActionsImpl(node->arguments->children.at(0), no_subqueries, only_consts, actions_stack);
1646

1647
					/// Превратим tuple или подзапрос в множество.
1648
					makeSet(node, actions_stack.getSampleBlock());
1649 1650 1651
				}
				else
				{
1652 1653 1654 1655
					if (!only_consts)
					{
						/// Мы в той части дерева, которую не собираемся вычислять. Нужно только определить типы.
						/// Не будем выполнять подзапросы и составлять множества. Вставим произвольный столбец правильного типа.
1656
						ColumnWithTypeAndName fake_column;
1657
						fake_column.name = node->getColumnName();
1658
						fake_column.type = std::make_shared<DataTypeUInt8>();
1659
						actions_stack.addAction(ExpressionAction::addColumn(fake_column));
1660
						getActionsImpl(node->arguments->children.at(0), no_subqueries, only_consts, actions_stack);
1661
					}
1662 1663 1664
					return;
				}
			}
1665

1666 1667 1668 1669 1670
			/// Особая функция indexHint. Всё, что внутри неё не вычисляется
			/// (а используется только для анализа индекса, см. PKCondition).
			if (node->name == "indexHint")
			{
				actions_stack.addAction(ExpressionAction::addColumn(ColumnWithTypeAndName(
1671
					std::make_shared<ColumnConstUInt8>(1, 1), std::make_shared<DataTypeUInt8>(), node->getColumnName())));
1672 1673 1674
				return;
			}

A
Merge  
Alexey Arno 已提交
1675
			const FunctionPtr & function = getFunctionFromFactory(node->name, node->genus, context);
1676

1677 1678
			Names argument_names;
			DataTypes argument_types;
M
Merge  
Michael Kolupaev 已提交
1679
			bool arguments_present = true;
1680

1681 1682
			/// Если у функции есть аргумент-лямбда-выражение, нужно определить его тип до рекурсивного вызова.
			bool has_lambda_arguments = false;
1683

1684
			for (auto & child : node->arguments->children)
1685
			{
1686 1687
				ASTFunction * lambda = typeid_cast<ASTFunction *>(child.get());
				ASTSet * set = typeid_cast<ASTSet *>(child.get());
1688 1689
				if (lambda && lambda->name == "lambda")
				{
M
Merge  
Michael Kolupaev 已提交
1690
					/// Если аргумент - лямбда-выражение, только запомним его примерный тип.
1691 1692
					if (lambda->arguments->children.size() != 2)
						throw Exception("lambda requires two arguments", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
1693

1694
					ASTFunction * lambda_args_tuple = typeid_cast<ASTFunction *>(lambda->arguments->children.at(0).get());
1695

1696 1697
					if (!lambda_args_tuple || lambda_args_tuple->name != "tuple")
						throw Exception("First argument of lambda must be a tuple", ErrorCodes::TYPE_MISMATCH);
1698

1699
					has_lambda_arguments = true;
1700
					argument_types.emplace_back(std::make_shared<DataTypeExpression>(DataTypes(lambda_args_tuple->arguments->children.size())));
1701
					/// Выберем название в следующем цикле.
1702
					argument_names.emplace_back();
1703
				}
1704 1705
				else if (set)
				{
1706
					ColumnWithTypeAndName column;
1707
					column.type = std::make_shared<DataTypeSet>();
1708

1709 1710
					/// Если аргумент - множество, заданное перечислением значений, дадим ему уникальное имя,
					///  чтобы множества с одинаковой записью не склеивались (у них может быть разный тип).
1711
					if (set->is_explicit)
1712 1713 1714 1715 1716 1717
						column.name = getUniqueName(actions_stack.getSampleBlock(), "__set");
					else
						column.name = set->getColumnName();

					if (!actions_stack.getSampleBlock().has(column.name))
					{
1718
						column.column = std::make_shared<ColumnSet>(1, set->set);
1719

1720
						actions_stack.addAction(ExpressionAction::addColumn(column));
1721
					}
1722

1723 1724 1725
					argument_types.push_back(column.type);
					argument_names.push_back(column.name);
				}
1726 1727
				else
				{
M
Merge  
Michael Kolupaev 已提交
1728
					/// Если аргумент не лямбда-выражение, вызовемся рекурсивно и узнаем его тип.
1729
					getActionsImpl(child, no_subqueries, only_consts, actions_stack);
1730
					std::string name = child->getColumnName();
1731
					if (actions_stack.getSampleBlock().has(name))
M
Merge  
Michael Kolupaev 已提交
1732
					{
1733
						argument_types.push_back(actions_stack.getSampleBlock().getByName(name).type);
M
Merge  
Michael Kolupaev 已提交
1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746
						argument_names.push_back(name);
					}
					else
					{
						if (only_consts)
						{
							arguments_present = false;
						}
						else
						{
							throw Exception("Unknown identifier: " + name, ErrorCodes::UNKNOWN_IDENTIFIER);
						}
					}
1747 1748
				}
			}
1749

M
Merge  
Michael Kolupaev 已提交
1750 1751
			if (only_consts && !arguments_present)
				return;
1752

1753
			Names additional_requirements;
1754

1755 1756 1757
			if (has_lambda_arguments && !only_consts)
			{
				function->getLambdaArgumentTypes(argument_types);
1758

1759 1760 1761 1762
				/// Вызовемся рекурсивно для лямбда-выражений.
				for (size_t i = 0; i < node->arguments->children.size(); ++i)
				{
					ASTPtr child = node->arguments->children[i];
1763

1764
					ASTFunction * lambda = typeid_cast<ASTFunction *>(child.get());
1765 1766
					if (lambda && lambda->name == "lambda")
					{
1767 1768
						DataTypeExpression * lambda_type = typeid_cast<DataTypeExpression *>(argument_types[i].get());
						ASTFunction * lambda_args_tuple = typeid_cast<ASTFunction *>(lambda->arguments->children.at(0).get());
1769
						ASTs lambda_arg_asts = lambda_args_tuple->arguments->children;
1770
						NamesAndTypesList lambda_arguments;
1771

1772 1773
						for (size_t j = 0; j < lambda_arg_asts.size(); ++j)
						{
1774
							ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(lambda_arg_asts[j].get());
1775 1776
							if (!identifier)
								throw Exception("lambda argument declarations must be identifiers", ErrorCodes::TYPE_MISMATCH);
1777

1778
							String arg_name = identifier->name;
1779

1780
							lambda_arguments.emplace_back(arg_name, lambda_type->getArgumentTypes()[j]);
1781
						}
1782

1783
						actions_stack.pushLevel(lambda_arguments);
1784
						getActionsImpl(lambda->arguments->children.at(1), no_subqueries, only_consts, actions_stack);
1785
						ExpressionActionsPtr lambda_actions = actions_stack.popLevel();
1786

1787
						String result_name = lambda->arguments->children.at(1)->getColumnName();
1788
						lambda_actions->finalize(Names(1, result_name));
1789
						DataTypePtr result_type = lambda_actions->getSampleBlock().getByName(result_name).type;
1790
						argument_types[i] = std::make_shared<DataTypeExpression>(lambda_type->getArgumentTypes(), result_type);
1791

1792 1793 1794 1795
						Names captured = lambda_actions->getRequiredColumns();
						for (size_t j = 0; j < captured.size(); ++j)
							if (findColumn(captured[j], lambda_arguments) == lambda_arguments.end())
								additional_requirements.push_back(captured[j]);
1796

1797 1798
						/// Не можем дать название getColumnName(),
						///  потому что оно не однозначно определяет выражение (типы аргументов могут быть разными).
1799
						argument_names[i] = getUniqueName(actions_stack.getSampleBlock(), "__lambda");
1800

1801
						ColumnWithTypeAndName lambda_column;
1802
						lambda_column.column = std::make_shared<ColumnExpression>(1, lambda_actions, lambda_arguments, result_type, result_name);
1803 1804
						lambda_column.type = argument_types[i];
						lambda_column.name = argument_names[i];
1805
						actions_stack.addAction(ExpressionAction::addColumn(lambda_column));
1806 1807 1808
					}
				}
			}
1809

1810 1811 1812 1813
			if (only_consts)
			{
				for (size_t i = 0; i < argument_names.size(); ++i)
				{
1814
					if (!actions_stack.getSampleBlock().has(argument_names[i]))
1815
					{
M
Merge  
Michael Kolupaev 已提交
1816
						arguments_present = false;
1817 1818 1819 1820
						break;
					}
				}
			}
1821

M
Merge  
Michael Kolupaev 已提交
1822
			if (arguments_present)
1823
				actions_stack.addAction(ExpressionAction::applyFunction(function, argument_names, node->getColumnName()),
1824
										additional_requirements);
1825 1826
		}
	}
1827
	else if (ASTLiteral * node = typeid_cast<ASTLiteral *>(ast.get()))
1828 1829
	{
		DataTypePtr type = apply_visitor(FieldToDataType(), node->value);
1830

1831
		ColumnWithTypeAndName column;
1832 1833 1834
		column.column = type->createConstColumn(1, node->value);
		column.type = type;
		column.name = node->getColumnName();
1835

1836
		actions_stack.addAction(ExpressionAction::addColumn(column));
1837 1838 1839
	}
	else
	{
1840 1841
		for (auto & child : ast->children)
			getActionsImpl(child, no_subqueries, only_consts, actions_stack);
1842 1843 1844 1845
	}
}


1846
void ExpressionAnalyzer::getAggregates(const ASTPtr & ast, ExpressionActionsPtr & actions)
1847
{
1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862
	/// Внутри WHERE и PREWHERE не может быть агрегатных функций.
	if (select_query && (ast.get() == select_query->where_expression.get() || ast.get() == select_query->prewhere_expression.get()))
	{
		assertNoAggregates(ast, "in WHERE or PREWHERE");
		return;
	}

	/// Если мы анализируем не запрос SELECT, а отдельное выражение, то в нём не может быть агрегатных функций.
	if (!select_query)
	{
		assertNoAggregates(ast, "in wrong place");
		return;
	}

	const ASTFunction * node = typeid_cast<const ASTFunction *>(ast.get());
1863
	if (node && node->kind == ASTFunction::AGGREGATE_FUNCTION)
1864
	{
1865
		has_aggregation = true;
1866 1867
		AggregateDescription aggregate;
		aggregate.column_name = node->getColumnName();
1868

1869
		/// Агрегатные функции уникализируются.
1870 1871 1872
		for (size_t i = 0; i < aggregate_descriptions.size(); ++i)
			if (aggregate_descriptions[i].column_name == aggregate.column_name)
				return;
1873

1874
		const ASTs & arguments = node->arguments->children;
1875 1876
		aggregate.argument_names.resize(arguments.size());
		DataTypes types(arguments.size());
1877

1878 1879
		for (size_t i = 0; i < arguments.size(); ++i)
		{
1880 1881 1882
			/// Внутри агрегатных функций не может быть других агрегатных функций.
			assertNoAggregates(arguments[i], "inside another aggregate function");

1883
			getRootActions(arguments[i], true, false, actions);
1884
			const std::string & name = arguments[i]->getColumnName();
1885
			types[i] = actions->getSampleBlock().getByName(name).type;
1886 1887
			aggregate.argument_names[i] = name;
		}
1888

1889
		aggregate.function = context.getAggregateFunctionFactory().get(node->name, types);
1890

1891 1892
		if (node->parameters)
		{
1893
			const ASTs & parameters = typeid_cast<const ASTExpressionList &>(*node->parameters).children;
1894
			Array params_row(parameters.size());
1895

1896 1897
			for (size_t i = 0; i < parameters.size(); ++i)
			{
1898
				const ASTLiteral * lit = typeid_cast<const ASTLiteral *>(parameters[i].get());
1899
				if (!lit)
1900 1901
					throw Exception("Parameters to aggregate functions must be literals",
						ErrorCodes::PARAMETERS_TO_AGGREGATE_FUNCTIONS_MUST_BE_LITERALS);
1902

1903 1904
				params_row[i] = lit->value;
			}
1905

1906
			aggregate.parameters = params_row;
1907 1908
			aggregate.function->setParameters(params_row);
		}
1909

1910
		aggregate.function->setArguments(types);
1911

1912 1913 1914 1915
		aggregate_descriptions.push_back(aggregate);
	}
	else
	{
1916 1917
		for (const auto & child : ast->children)
			if (!typeid_cast<const ASTSubquery *>(child.get()) && !typeid_cast<const ASTSelectQuery *>(child.get()))
1918
				getAggregates(child, actions);
1919 1920 1921
	}
}

1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936

void ExpressionAnalyzer::assertNoAggregates(const ASTPtr & ast, const char * description)
{
	const ASTFunction * node = typeid_cast<const ASTFunction *>(ast.get());

	if (node && node->kind == ASTFunction::AGGREGATE_FUNCTION)
		throw Exception("Aggregate function " + node->getColumnName()
			+ " is found " + String(description) + " in query", ErrorCodes::ILLEGAL_AGGREGATION);

	for (const auto & child : ast->children)
		if (!typeid_cast<const ASTSubquery *>(child.get()) && !typeid_cast<const ASTSelectQuery *>(child.get()))
			assertNoAggregates(child, description);
}


1937
void ExpressionAnalyzer::assertSelect() const
1938 1939 1940 1941
{
	if (!select_query)
		throw Exception("Not a select query", ErrorCodes::LOGICAL_ERROR);
}
1942

1943
void ExpressionAnalyzer::assertAggregation() const
1944 1945 1946
{
	if (!has_aggregation)
		throw Exception("No aggregation", ErrorCodes::LOGICAL_ERROR);
1947
}
1948

1949
void ExpressionAnalyzer::initChain(ExpressionActionsChain & chain, const NamesAndTypesList & columns) const
1950 1951 1952 1953
{
	if (chain.steps.empty())
	{
		chain.settings = settings;
1954
		chain.steps.emplace_back(std::make_shared<ExpressionActions>(columns, settings));
1955 1956
	}
}
1957

1958
/// "Большой" ARRAY JOIN.
1959
void ExpressionAnalyzer::addMultipleArrayJoinAction(ExpressionActionsPtr & actions) const
1960
{
1961
	NameSet result_columns;
1962
	for (const auto & result_source : array_join_result_to_source)
1963
	{
1964
		/// Дать столбцам новые имена, если надо.
1965 1966
		if (result_source.first != result_source.second)
			actions->add(ExpressionAction::copyColumn(result_source.second, result_source.first));
1967 1968

		/// Сделать ARRAY JOIN (заменить массивы на их внутренности) для столбцов в этими новыми именами.
1969
		result_columns.insert(result_source.first);
1970 1971
	}

1972
	actions->add(ExpressionAction::arrayJoin(result_columns, select_query->array_join_is_left));
1973 1974
}

1975
bool ExpressionAnalyzer::appendArrayJoin(ExpressionActionsChain & chain, bool only_types)
1976 1977
{
	assertSelect();
1978 1979

	if (!select_query->array_join_expression_list)
1980
		return false;
1981

1982 1983
	initChain(chain, columns);
	ExpressionActionsChain::Step & step = chain.steps.back();
1984

1985
	getRootActions(select_query->array_join_expression_list, only_types, false, step.actions);
1986

1987
	addMultipleArrayJoinAction(step.actions);
1988

1989 1990 1991
	return true;
}

1992
void ExpressionAnalyzer::addJoinAction(ExpressionActionsPtr & actions, bool only_types) const
1993
{
1994 1995 1996 1997 1998 1999
	if (only_types)
		actions->add(ExpressionAction::ordinaryJoin(nullptr, columns_added_by_join));
	else
		for (auto & subquery_for_set : subqueries_for_sets)
			if (subquery_for_set.second.join)
				actions->add(ExpressionAction::ordinaryJoin(subquery_for_set.second.join, columns_added_by_join));
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011
}

bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_types)
{
	assertSelect();

	if (!select_query->join)
		return false;

	initChain(chain, columns);
	ExpressionActionsChain::Step & step = chain.steps.back();

2012
	ASTJoin & ast_join = typeid_cast<ASTJoin &>(*select_query->join);
2013 2014
	if (ast_join.using_expr_list)
		getRootActions(ast_join.using_expr_list, only_types, false, step.actions);
2015

2016 2017 2018 2019
	/// Не поддерживается два JOIN-а с одинаковым подзапросом, но разными USING-ами.
	String join_id = ast_join.table->getColumnName();

	SubqueryForSet & subquery_for_set = subqueries_for_sets[join_id];
2020 2021 2022

	/// Особый случай - если справа JOIN указано имя таблицы, при чём, таблица имеет тип Join (заранее подготовленное отображение).
	/// TODO В этом синтаксисе не поддерживается указание имени БД.
2023
	ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(ast_join.table.get());
2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042
	if (identifier)
	{
		StoragePtr table = context.tryGetTable("", identifier->name);

		if (table)
		{
			StorageJoin * storage_join = typeid_cast<StorageJoin *>(table.get());

			if (storage_join)
			{
				storage_join->assertCompatible(ast_join.kind, ast_join.strictness);
				/// TODO Проверять набор ключей.

				JoinPtr & join = storage_join->getJoin();
				subquery_for_set.join = join;
			}
		}
	}

2043
	if (!subquery_for_set.join)
2044
	{
2045
		JoinPtr join = std::make_shared<Join>(join_key_names_left, join_key_names_right, settings.limits, ast_join.kind, ast_join.strictness);
2046

2047
		Names required_joined_columns(join_key_names_right.begin(), join_key_names_right.end());
2048
		for (const auto & name_type : columns_added_by_join)
2049
			required_joined_columns.push_back(name_type.name);
2050

2051
		/** Для GLOBAL JOIN-ов (в случае, например, push-метода выполнения GLOBAL подзапросов) происходит следующее:
2052 2053 2054 2055 2056
		  * - в функции addExternalStorage подзапрос JOIN (SELECT ...) заменяется на JOIN _data1,
		  *   в объекте subquery_for_set выставляется этот подзапрос в качестве source и временная таблица _data1 в качестве table.
		  * - в этой функции видно выражение JOIN _data1.
		  */
		if (!subquery_for_set.source)
2057 2058
		{
			auto interpreter = interpretSubquery(ast_join.table, context, subquery_depth, required_joined_columns);
2059
			subquery_for_set.source = std::make_shared<LazyBlockInputStream>([interpreter]() mutable { return interpreter->execute().in; });
2060
			subquery_for_set.source_sample = interpreter->getSampleBlock();
2061
		}
2062

2063
		/// TODO Это не нужно выставлять, когда JOIN нужен только на удалённых серверах.
2064
		subquery_for_set.join = join;
2065
		subquery_for_set.join->setSampleBlock(subquery_for_set.source_sample);
2066 2067
	}

2068
	addJoinAction(step.actions, false);
2069 2070 2071 2072

	return true;
}

2073
bool ExpressionAnalyzer::appendWhere(ExpressionActionsChain & chain, bool only_types)
2074 2075
{
	assertSelect();
2076

2077 2078
	if (!select_query->where_expression)
		return false;
2079

2080
	initChain(chain, columns);
2081
	ExpressionActionsChain::Step & step = chain.steps.back();
2082

2083
	step.required_output.push_back(select_query->where_expression->getColumnName());
2084
	getRootActions(select_query->where_expression, only_types, false, step.actions);
2085

2086 2087 2088
	return true;
}

2089
bool ExpressionAnalyzer::appendGroupBy(ExpressionActionsChain & chain, bool only_types)
2090 2091
{
	assertAggregation();
2092

2093 2094
	if (!select_query->group_expression_list)
		return false;
2095

2096
	initChain(chain, columns);
2097
	ExpressionActionsChain::Step & step = chain.steps.back();
2098

2099
	ASTs asts = select_query->group_expression_list->children;
2100 2101
	for (size_t i = 0; i < asts.size(); ++i)
	{
2102
		step.required_output.push_back(asts[i]->getColumnName());
2103
		getRootActions(asts[i], only_types, false, step.actions);
2104
	}
2105

2106 2107 2108
	return true;
}

2109
void ExpressionAnalyzer::appendAggregateFunctionsArguments(ExpressionActionsChain & chain, bool only_types)
2110 2111
{
	assertAggregation();
2112

2113
	initChain(chain, columns);
2114
	ExpressionActionsChain::Step & step = chain.steps.back();
2115

2116 2117 2118 2119 2120 2121 2122
	for (size_t i = 0; i < aggregate_descriptions.size(); ++i)
	{
		for (size_t j = 0; j < aggregate_descriptions[i].argument_names.size(); ++j)
		{
			step.required_output.push_back(aggregate_descriptions[i].argument_names[j]);
		}
	}
2123

2124
	getActionsBeforeAggregation(select_query->select_expression_list, step.actions, only_types);
2125

2126
	if (select_query->having_expression)
2127
		getActionsBeforeAggregation(select_query->having_expression, step.actions, only_types);
2128

2129
	if (select_query->order_expression_list)
2130
		getActionsBeforeAggregation(select_query->order_expression_list, step.actions, only_types);
2131 2132
}

2133
bool ExpressionAnalyzer::appendHaving(ExpressionActionsChain & chain, bool only_types)
2134 2135
{
	assertAggregation();
2136

2137 2138
	if (!select_query->having_expression)
		return false;
2139

2140 2141
	initChain(chain, aggregated_columns);
	ExpressionActionsChain::Step & step = chain.steps.back();
2142

2143
	step.required_output.push_back(select_query->having_expression->getColumnName());
2144
	getRootActions(select_query->having_expression, only_types, false, step.actions);
2145

2146
	return true;
2147 2148
}

2149
void ExpressionAnalyzer::appendSelect(ExpressionActionsChain & chain, bool only_types)
2150 2151
{
	assertSelect();
2152

2153 2154
	initChain(chain, aggregated_columns);
	ExpressionActionsChain::Step & step = chain.steps.back();
2155

2156
	getRootActions(select_query->select_expression_list, only_types, false, step.actions);
2157

2158 2159 2160 2161 2162
	ASTs asts = select_query->select_expression_list->children;
	for (size_t i = 0; i < asts.size(); ++i)
	{
		step.required_output.push_back(asts[i]->getColumnName());
	}
2163
}
2164

2165
bool ExpressionAnalyzer::appendOrderBy(ExpressionActionsChain & chain, bool only_types)
2166
{
2167
	assertSelect();
2168

2169 2170
	if (!select_query->order_expression_list)
		return false;
2171

2172 2173
	initChain(chain, aggregated_columns);
	ExpressionActionsChain::Step & step = chain.steps.back();
2174

2175
	getRootActions(select_query->order_expression_list, only_types, false, step.actions);
2176

2177 2178 2179
	ASTs asts = select_query->order_expression_list->children;
	for (size_t i = 0; i < asts.size(); ++i)
	{
2180
		ASTOrderByElement * ast = typeid_cast<ASTOrderByElement *>(asts[i].get());
2181 2182
		if (!ast || ast->children.size() != 1)
			throw Exception("Bad order expression AST", ErrorCodes::UNKNOWN_TYPE_OF_AST_NODE);
2183
		ASTPtr order_expression = ast->children.at(0);
2184 2185
		step.required_output.push_back(order_expression->getColumnName());
	}
2186

2187 2188 2189
	return true;
}

2190
void ExpressionAnalyzer::appendProjectResult(DB::ExpressionActionsChain & chain, bool only_types) const
2191 2192
{
	assertSelect();
2193

2194 2195
	initChain(chain, aggregated_columns);
	ExpressionActionsChain::Step & step = chain.steps.back();
2196

2197
	NamesWithAliases result_columns;
2198

2199
	ASTs asts = select_query->select_expression_list->children;
2200
	for (size_t i = 0; i < asts.size(); ++i)
2201
	{
2202 2203
		result_columns.emplace_back(asts[i]->getColumnName(), asts[i]->getAliasOrColumnName());
		step.required_output.push_back(result_columns.back().second);
2204
	}
2205

2206
	step.actions->add(ExpressionAction::project(result_columns));
2207 2208 2209
}


2210 2211 2212
Block ExpressionAnalyzer::getSelectSampleBlock()
{
	assertSelect();
2213

2214
	ExpressionActionsPtr temp_actions = std::make_shared<ExpressionActions>(aggregated_columns, settings);
2215
	NamesWithAliases result_columns;
2216

2217 2218 2219
	ASTs asts = select_query->select_expression_list->children;
	for (size_t i = 0; i < asts.size(); ++i)
	{
2220
		result_columns.emplace_back(asts[i]->getColumnName(), asts[i]->getAliasOrColumnName());
2221
		getRootActions(asts[i], true, false, temp_actions);
2222
	}
2223

2224
	temp_actions->add(ExpressionAction::project(result_columns));
2225

2226
	return temp_actions->getSampleBlock();
2227 2228
}

2229
void ExpressionAnalyzer::getActionsBeforeAggregation(ASTPtr ast, ExpressionActionsPtr & actions, bool no_subqueries)
2230
{
2231
	ASTFunction * node = typeid_cast<ASTFunction *>(ast.get());
2232

2233 2234 2235
	if (node && node->kind == ASTFunction::AGGREGATE_FUNCTION)
		for (auto & argument : node->arguments->children)
			getRootActions(argument, no_subqueries, false, actions);
2236
	else
2237 2238
		for (auto & child : ast->children)
			getActionsBeforeAggregation(child, actions, no_subqueries);
2239 2240 2241
}


M
Merge  
Michael Kolupaev 已提交
2242
ExpressionActionsPtr ExpressionAnalyzer::getActions(bool project_result)
2243
{
2244
	ExpressionActionsPtr actions = std::make_shared<ExpressionActions>(columns, settings);
2245
	NamesWithAliases result_columns;
2246
	Names result_names;
2247

2248
	ASTs asts;
2249

2250
	if (auto node = typeid_cast<const ASTExpressionList *>(ast.get()))
2251
		asts = node->children;
2252
	else
2253
		asts = ASTs(1, ast);
2254

2255
	for (size_t i = 0; i < asts.size(); ++i)
2256
	{
2257 2258 2259
		std::string name = asts[i]->getColumnName();
		std::string alias;
		if (project_result)
A
Alexey Milovidov 已提交
2260
			alias = asts[i]->getAliasOrColumnName();
2261 2262
		else
			alias = name;
2263
		result_columns.emplace_back(name, alias);
2264
		result_names.push_back(alias);
2265
		getRootActions(asts[i], false, false, actions);
2266
	}
2267

M
Merge  
Michael Kolupaev 已提交
2268 2269
	if (project_result)
	{
2270
		actions->add(ExpressionAction::project(result_columns));
M
Merge  
Michael Kolupaev 已提交
2271
	}
M
Merge  
Michael Kolupaev 已提交
2272 2273 2274
	else
	{
		/// Не будем удалять исходные столбцы.
A
Alexey Milovidov 已提交
2275
		for (const auto & column_name_type : columns)
2276
			result_names.push_back(column_name_type.name);
M
Merge  
Michael Kolupaev 已提交
2277
	}
2278

2279
	actions->finalize(result_names);
2280

2281 2282 2283 2284 2285 2286
	return actions;
}


ExpressionActionsPtr ExpressionAnalyzer::getConstActions()
{
2287
	ExpressionActionsPtr actions = std::make_shared<ExpressionActions>(NamesAndTypesList(), settings);
2288

2289
	getRootActions(ast, true, true, actions);
2290

2291 2292 2293
	return actions;
}

2294
void ExpressionAnalyzer::getAggregateInfo(Names & key_names, AggregateDescriptions & aggregates) const
2295
{
2296 2297
	for (const auto & name_and_type : aggregation_keys)
		key_names.emplace_back(name_and_type.name);
2298

2299 2300 2301
	aggregates = aggregate_descriptions;
}

2302
void ExpressionAnalyzer::collectUsedColumns()
2303
{
A
Alexey Milovidov 已提交
2304 2305 2306 2307 2308 2309 2310
	/** Вычислим, какие столбцы требуются для выполнения выражения.
	  * Затем, удалим все остальные столбцы из списка доступных столбцов.
	  * После выполнения, columns будет содержать только список столбцов, нужных для чтения из таблицы.
	  */

	NameSet required;
	NameSet ignored;
2311

2312 2313 2314 2315 2316 2317
	if (select_query && select_query->array_join_expression_list)
	{
		ASTs & expressions = select_query->array_join_expression_list->children;
		for (size_t i = 0; i < expressions.size(); ++i)
		{
			/// Игнорируем идентификаторы верхнего уровня из секции ARRAY JOIN.
2318
			/// Их потом добавим отдельно.
2319
			if (typeid_cast<ASTIdentifier *>(expressions[i].get()))
2320
			{
2321
				ignored.insert(expressions[i]->getColumnName());
2322 2323 2324 2325
			}
			else
			{
				/// Для выражений в ARRAY JOIN ничего игнорировать не нужно.
A
Alexey Milovidov 已提交
2326
				NameSet empty;
2327
				getRequiredColumnsImpl(expressions[i], required, empty, empty, empty);
2328
			}
2329

A
Alexey Milovidov 已提交
2330
			ignored.insert(expressions[i]->getAliasOrColumnName());
2331 2332
		}
	}
2333

2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344
	/** Также нужно не учитывать идентификаторы столбцов, получающихся путём JOIN-а.
	  * (Не считать, что они требуются для чтения из "левой" таблицы).
	  */
	NameSet available_joined_columns;
	collectJoinedColumns(available_joined_columns, columns_added_by_join);

	NameSet required_joined_columns;
	getRequiredColumnsImpl(ast, required, ignored, available_joined_columns, required_joined_columns);

	for (NamesAndTypesList::iterator it = columns_added_by_join.begin(); it != columns_added_by_join.end();)
	{
2345
		if (required_joined_columns.count(it->name))
2346 2347 2348 2349 2350
			++it;
		else
			columns_added_by_join.erase(it++);
	}

2351
/*	for (const auto & name_type : columns_added_by_join)
2352
		std::cerr << "JOINed column (required, not key): " << name_type.name << std::endl;
2353
	std::cerr << std::endl;*/
2354

A
Alexey Milovidov 已提交
2355
	/// Вставляем в список требуемых столбцов столбцы, нужные для вычисления ARRAY JOIN.
2356
	NameSet array_join_sources;
A
Alexey Milovidov 已提交
2357 2358 2359 2360
	for (const auto & result_source : array_join_result_to_source)
		array_join_sources.insert(result_source.second);

	for (const auto & column_name_type : columns)
2361 2362
		if (array_join_sources.count(column_name_type.name))
			required.insert(column_name_type.name);
2363

2364 2365 2366
	/// Нужно прочитать хоть один столбец, чтобы узнать количество строк.
	if (required.empty())
		required.insert(ExpressionActions::getSmallestColumn(columns));
2367

2368
	unknown_required_columns = required;
2369

2370 2371
	for (NamesAndTypesList::iterator it = columns.begin(); it != columns.end();)
	{
2372
		unknown_required_columns.erase(it->name);
2373

2374
		if (!required.count(it->name))
2375
		{
2376
			required.erase(it->name);
A
Alexey Milovidov 已提交
2377
			columns.erase(it++);
2378
		}
A
Alexey Milovidov 已提交
2379 2380
		else
			++it;
2381
	}
S
Merge  
Sergey Fedorov 已提交
2382

2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397
	/// Возможно, среди неизвестных столбцов есть виртуальные. Удаляем их из списка неизвестных и добавляем
	/// в columns list, чтобы при дальнейшей обработке запроса они воспринимались как настоящие.
	if (storage)
	{
		for (auto it = unknown_required_columns.begin(); it != unknown_required_columns.end();)
		{
			if (storage->hasColumn(*it))
			{
				columns.push_back(storage->getColumn(*it));
				unknown_required_columns.erase(it++);
			}
			else
				++it;
		}
	}
2398 2399
}

2400
void ExpressionAnalyzer::collectJoinedColumns(NameSet & joined_columns, NamesAndTypesList & joined_columns_name_type)
2401 2402 2403 2404
{
	if (!select_query || !select_query->join)
		return;

2405
	auto & node = typeid_cast<ASTJoin &>(*select_query->join);
2406

2407 2408 2409 2410 2411 2412 2413 2414
	Block nested_result_sample;
	if (const auto identifier = typeid_cast<const ASTIdentifier *>(node.table.get()))
	{
		const auto & table = context.getTable("", identifier->name);
		nested_result_sample = table->getSampleBlockNonMaterialized();
	}
	else if (typeid_cast<const ASTSubquery *>(node.table.get()))
	{
2415
		const auto & subquery = node.table->children.at(0);
2416
		nested_result_sample = InterpreterSelectQuery::getSampleBlock(subquery, context);
2417
	}
2418

2419
	if (node.using_expr_list)
2420
	{
2421 2422 2423
		auto & keys = typeid_cast<ASTExpressionList &>(*node.using_expr_list);
		for (const auto & key : keys.children)
		{
2424 2425 2426 2427
			if (join_key_names_left.end() == std::find(join_key_names_left.begin(), join_key_names_left.end(), key->getColumnName()))
				join_key_names_left.push_back(key->getColumnName());
			else
				throw Exception("Duplicate column " + key->getColumnName() + " in USING list", ErrorCodes::DUPLICATE_COLUMN);
2428

2429 2430 2431 2432
			if (join_key_names_right.end() == std::find(join_key_names_right.begin(), join_key_names_right.end(), key->getAliasOrColumnName()))
				join_key_names_right.push_back(key->getAliasOrColumnName());
			else
				throw Exception("Duplicate column " + key->getAliasOrColumnName() + " in USING list", ErrorCodes::DUPLICATE_COLUMN);
2433
		}
2434 2435
	}

2436
	for (const auto i : ext::range(0, nested_result_sample.columns()))
2437
	{
2438
		const auto & col = nested_result_sample.getByPosition(i);
2439 2440
		if (join_key_names_right.end() == std::find(join_key_names_right.begin(), join_key_names_right.end(), col.name)
			&& !joined_columns.count(col.name))	/// Дублирующиеся столбцы в подзапросе для JOIN-а не имеют смысла.
2441
		{
2442 2443
			joined_columns.insert(col.name);
			joined_columns_name_type.emplace_back(col.name, col.type);
2444
		}
2445
	}
2446

2447
/*	for (const auto & name : join_key_names_left)
2448
		std::cerr << "JOIN key (left): " << name << std::endl;
2449
	for (const auto & name : join_key_names_right)
2450
		std::cerr << "JOIN key (right): " << name << std::endl;
2451 2452 2453
	std::cerr << std::endl;
	for (const auto & name : joined_columns)
		std::cerr << "JOINed column: " << name << std::endl;
2454
	std::cerr << std::endl;*/
2455 2456
}

2457 2458
Names ExpressionAnalyzer::getRequiredColumns()
{
M
Merge  
Michael Kolupaev 已提交
2459 2460
	if (!unknown_required_columns.empty())
		throw Exception("Unknown identifier: " + *unknown_required_columns.begin(), ErrorCodes::UNKNOWN_IDENTIFIER);
2461

2462
	Names res;
2463
	for (const auto & column_name_type : columns)
2464
		res.push_back(column_name_type.name);
A
Alexey Milovidov 已提交
2465

2466 2467 2468
	return res;
}

2469 2470 2471
void ExpressionAnalyzer::getRequiredColumnsImpl(ASTPtr ast,
	NameSet & required_columns, NameSet & ignored_names,
	const NameSet & available_joined_columns, NameSet & required_joined_columns)
2472
{
2473 2474 2475 2476 2477
	/** Найдём все идентификаторы в запросе.
	  * Будем искать их рекурсивно, обходя в глубину AST.
	  * При этом:
	  * - для лямбда функций не будем брать формальные параметры;
	  * - не опускаемся в подзапросы (там свои идентификаторы);
2478 2479
	  * - некоторое исключение для секции ARRAY JOIN (в ней идентификаторы немного другие);
	  * - идентификаторы, доступные из JOIN-а, кладём в required_joined_columns.
2480 2481
	  */

2482
	if (ASTIdentifier * node = typeid_cast<ASTIdentifier *>(ast.get()))
2483
	{
2484 2485 2486
		if (node->kind == ASTIdentifier::Column
			&& !ignored_names.count(node->name)
			&& !ignored_names.count(DataTypeNested::extractNestedTableName(node->name)))
2487
		{
2488 2489 2490 2491
			if (!available_joined_columns.count(node->name))
				required_columns.insert(node->name);
			else
				required_joined_columns.insert(node->name);
2492
		}
A
Alexey Milovidov 已提交
2493

2494 2495
		return;
	}
2496

2497
	if (ASTFunction * node = typeid_cast<ASTFunction *>(ast.get()))
2498 2499 2500 2501 2502
	{
		if (node->kind == ASTFunction::LAMBDA_EXPRESSION)
		{
			if (node->arguments->children.size() != 2)
				throw Exception("lambda requires two arguments", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
2503

2504
			ASTFunction * lambda_args_tuple = typeid_cast<ASTFunction *>(node->arguments->children.at(0).get());
2505

2506 2507
			if (!lambda_args_tuple || lambda_args_tuple->name != "tuple")
				throw Exception("First argument of lambda must be a tuple", ErrorCodes::TYPE_MISMATCH);
2508

2509
			/// Не нужно добавлять формальные параметры лямбда-выражения в required_columns.
2510
			Names added_ignored;
2511
			for (auto & child : lambda_args_tuple->arguments->children)
2512
			{
2513
				ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(child.get());
2514 2515
				if (!identifier)
					throw Exception("lambda argument declarations must be identifiers", ErrorCodes::TYPE_MISMATCH);
2516 2517

				String & name = identifier->name;
2518 2519 2520 2521 2522 2523
				if (!ignored_names.count(name))
				{
					ignored_names.insert(name);
					added_ignored.push_back(name);
				}
			}
2524

2525
			getRequiredColumnsImpl(node->arguments->children.at(1),
2526 2527
				required_columns, ignored_names,
				available_joined_columns, required_joined_columns);
2528

2529 2530
			for (size_t i = 0; i < added_ignored.size(); ++i)
				ignored_names.erase(added_ignored[i]);
2531

2532 2533
			return;
		}
2534 2535 2536 2537 2538

		/// Особая функция indexHint. Всё, что внутри неё не вычисляется
		/// (а используется только для анализа индекса, см. PKCondition).
		if (node->name == "indexHint")
			return;
2539
	}
2540

2541
	ASTSelectQuery * select = typeid_cast<ASTSelectQuery *>(ast.get());
2542

2543 2544
	/// Рекурсивный обход выражения.
	for (auto & child : ast->children)
2545
	{
2546
		/** Не пойдем в секцию ARRAY JOIN, потому что там нужно смотреть на имена не-ARRAY-JOIN-енных столбцов.
2547
		  * Туда collectUsedColumns отправит нас отдельно.
2548
		  */
2549
		if (!typeid_cast<ASTSubquery *>(child.get()) && !typeid_cast<ASTSelectQuery *>(child.get()) &&
2550
			!(select && child == select->array_join_expression_list))
2551
			getRequiredColumnsImpl(child, required_columns, ignored_names, available_joined_columns, required_joined_columns);
2552
    }
2553 2554
}

2555
}