ExpressionAnalyzer.cpp 93.2 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 588 589 590

		/// А ещё, в качестве исключения, будем понимать count(*) как count(), а не count(список всех столбцов).
		if (func_node->name == "count" && func_node->arguments->children.size() == 1
			&& typeid_cast<const ASTAsterisk *>(func_node->arguments->children[0].get()))
		{
			func_node->arguments->children.clear();
		}
591
	}
592
	else if (ASTIdentifier * node = typeid_cast<ASTIdentifier *>(ast.get()))
593
	{
594
		if (node->kind == ASTIdentifier::Column)
595
		{
M
Merge  
Michael Kolupaev 已提交
596
			/// Если это алиас, но не родительский алиас (чтобы работали конструкции вроде "SELECT column+1 AS column").
597
			Aliases::const_iterator jt = aliases.find(node->name);
M
Merge  
Michael Kolupaev 已提交
598
			if (jt != aliases.end() && current_alias != node->name)
599
			{
600
				/// Заменим его на соответствующий узел дерева.
601
				if (current_asts.count(jt->second.get()))
602
					throw Exception("Cyclic aliases", ErrorCodes::CYCLIC_ALIASES);
A
Alexey Milovidov 已提交
603
				if (!my_alias.empty() && my_alias != jt->second->getAliasOrColumnName())
604 605 606
				{
					/// В конструкции вроде "a AS b", где a - алиас, нужно перевесить алиас b на результат подстановки алиаса a.
					ast = jt->second->clone();
A
Alexey Milovidov 已提交
607
					ast->setAlias(my_alias);
608 609 610 611 612 613 614
				}
				else
				{
					ast = jt->second;
				}

				replaced = true;
615 616 617
			}
		}
	}
618
	else if (ASTExpressionList * node = typeid_cast<ASTExpressionList *>(ast.get()))
619 620 621 622 623
	{
		/// Заменим * на список столбцов.
		ASTs & asts = node->children;
		for (int i = static_cast<int>(asts.size()) - 1; i >= 0; --i)
		{
624
			if (ASTAsterisk * asterisk = typeid_cast<ASTAsterisk *>(asts[i].get()))
625 626
			{
				ASTs all_columns;
A
Alexey Milovidov 已提交
627
				for (const auto & column_name_type : columns)
628
					all_columns.emplace_back(std::make_shared<ASTIdentifier>(asterisk->range, column_name_type.name));
A
Alexey Milovidov 已提交
629

630 631 632 633 634
				asts.erase(asts.begin() + i);
				asts.insert(asts.begin() + i, all_columns.begin(), all_columns.end());
			}
		}
	}
635
	else if (ASTJoin * node = typeid_cast<ASTJoin *>(ast.get()))
636 637
	{
		/// может быть указано JOIN t, где t - таблица, что равносильно JOIN (SELECT * FROM t).
638
		if (ASTIdentifier * right = typeid_cast<ASTIdentifier *>(node->table.get()))
639 640
			right->kind = ASTIdentifier::Table;
	}
641

642 643 644
	/// Если заменили корень поддерева вызовемся для нового корня снова - на случай, если алиас заменился на алиас.
	if (replaced)
	{
645
		normalizeTreeImpl(ast, finished_asts, current_asts, current_alias);
646 647
		current_asts.erase(initial_ast.get());
		current_asts.erase(ast.get());
648
		finished_asts[initial_ast] = ast;
649 650 651
		return;
	}

652
	/// Рекурсивные вызовы. Не опускаемся в подзапросы.
653 654 655 656 657 658 659 660 661 662
	/// Также не опускаемся в левый аргумент лямбда-выражений, чтобы не заменять формальные параметры
	///  по алиасам в выражениях вида 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];

663
			if (typeid_cast<const ASTSelectQuery *>(child.get()))
664 665 666 667 668 669 670 671 672
				continue;

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

676
			normalizeTreeImpl(child, finished_asts, current_asts, current_alias);
677 678
		}
	}
679

680
	/// Если секция WHERE или HAVING состоит из одного алиаса, ссылку нужно заменить не только в children, но и в where_expression и having_expression.
681
	if (ASTSelectQuery * select = typeid_cast<ASTSelectQuery *>(ast.get()))
682
	{
683
		if (select->prewhere_expression)
684
			normalizeTreeImpl(select->prewhere_expression, finished_asts, current_asts, current_alias);
685
		if (select->where_expression)
686
			normalizeTreeImpl(select->where_expression, finished_asts, current_asts, current_alias);
687
		if (select->having_expression)
688
			normalizeTreeImpl(select->having_expression, finished_asts, current_asts, current_alias);
689
	}
690

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

693
	if (ASTFunction * node = typeid_cast<ASTFunction *>(ast.get()))
694
	{
695 696 697 698
		if (node->kind == ASTFunction::TABLE_FUNCTION)
		{
		}
		else if (node->name == "lambda")
699
		{
700
			node->kind = ASTFunction::LAMBDA_EXPRESSION;
701 702 703
		}
		else if (context.getAggregateFunctionFactory().isAggregateFunctionName(node->name))
		{
704
			node->kind = ASTFunction::AGGREGATE_FUNCTION;
705
		}
706 707 708 709 710 711 712 713
		else if (node->name == "arrayJoin")
		{
			node->kind = ASTFunction::ARRAY_JOIN;
		}
		else
		{
			node->kind = ASTFunction::FUNCTION;
		}
714 715 716 717

		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);
718
	}
719

720 721
	current_asts.erase(initial_ast.get());
	current_asts.erase(ast.get());
722 723 724
	finished_asts[initial_ast] = ast;
}

725

726 727
void ExpressionAnalyzer::addAliasColumns()
{
728
	if (!select_query)
729 730 731 732 733 734 735 736 737
		return;

	if (!storage)
		return;

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


738 739
void ExpressionAnalyzer::executeScalarSubqueries()
{
740 741 742
	if (!select_query)
		executeScalarSubqueriesImpl(ast);
	else
743
	{
744 745
		for (auto & child : ast->children)
		{
746 747 748 749 750
			/// Не опускаемся в FROM, JOIN, UNION.
			if (child.get() != select_query->table.get()
				&& child.get() != select_query->join.get()
				&& child.get() != select_query->next_union_all.get())
			{
751
				executeScalarSubqueriesImpl(child);
752
			}
753
		}
754
	}
755 756
}

757

758
static ASTPtr addTypeConversion(std::unique_ptr<ASTLiteral> && ast, const String & type_name)
759
{
760
	auto func = std::make_shared<ASTFunction>(ast->range);
761 762 763 764
	ASTPtr res = func;
	func->alias = ast->alias;
	ast->alias.clear();
	func->kind = ASTFunction::FUNCTION;
765
	func->name = "CAST";
766
	auto exp_list = std::make_shared<ASTExpressionList>(ast->range);
767 768
	func->arguments = exp_list;
	func->children.push_back(func->arguments);
769
	exp_list->children.emplace_back(ast.release());
770
	exp_list->children.emplace_back(std::make_shared<ASTLiteral>(StringRange(), type_name));
771 772 773 774
	return res;
}


775 776 777 778 779 780 781 782 783 784 785 786 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
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)
		{
827
			auto lit = std::make_unique<ASTLiteral>(ast->range, (*block.getByPosition(0).column)[0]);
828
			lit->alias = subquery->alias;
829
			ast = addTypeConversion(std::move(lit), block.getByPosition(0).type->getName());
830 831 832
		}
		else
		{
833
			auto tuple = std::make_shared<ASTFunction>(ast->range);
834
			tuple->alias = subquery->alias;
835 836 837
			ast = tuple;
			tuple->kind = ASTFunction::FUNCTION;
			tuple->name = "tuple";
838
			auto exp_list = std::make_shared<ASTExpressionList>(ast->range);
839
			tuple->arguments = exp_list;
840
			tuple->children.push_back(tuple->arguments);
841 842 843

			exp_list->children.resize(columns);
			for (size_t i = 0; i < columns; ++i)
844 845
			{
				exp_list->children[i] = addTypeConversion(
846
					std::make_unique<ASTLiteral>(ast->range, (*block.getByPosition(i).column)[0]),
847 848
					block.getByPosition(i).type->getName());
			}
849 850 851
		}
	}
	else
852 853 854 855 856
	{
		/** Не опускаемся в подзапросы в аргументах IN.
		  * Но если аргумент - не подзапрос, то глубже внутри него могут быть подзапросы, и в них надо опускаться.
		  */
		ASTFunction * func = typeid_cast<ASTFunction *>(ast.get());
857

858 859 860 861 862
		if (func && func->kind == ASTFunction::FUNCTION
			&& functionIsInOrGlobalInOperator(func->name))
		{
			for (auto & child : ast->children)
			{
863
				if (child != func->arguments)
864 865 866 867 868 869 870 871 872 873 874
					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);
	}
875 876 877
}


878
void ExpressionAnalyzer::optimizeGroupBy()
879 880 881 882
{
	if (!(select_query && select_query->group_expression_list))
		return;

883 884 885
	const auto is_literal = [] (const ASTPtr& ast) {
		return typeid_cast<const ASTLiteral*>(ast.get());
	};
886

887
	auto & group_exprs = select_query->group_expression_list->children;
888

889
	/// removes expression at index idx by making it last one and calling .pop_back()
A
Alexey Milovidov 已提交
890 891
	const auto remove_expr_at_index = [&group_exprs] (const size_t idx)
	{
892
		if (idx < group_exprs.size() - 1)
A
Merge  
Andrey Mironov 已提交
893
			std::swap(group_exprs[idx], group_exprs.back());
894

895 896
		group_exprs.pop_back();
	};
897

A
Andrey Mironov 已提交
898
	/// iterate over each GROUP BY expression, eliminate injective function calls and literals
899
	for (size_t i = 0; i < group_exprs.size();)
900
	{
901
		if (const auto function = typeid_cast<ASTFunction *>(group_exprs[i].get()))
902 903
		{
			/// assert function is injective
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927
			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))
928 929
			{
				++i;
930
				continue;
931
			}
932 933 934 935 936 937 938 939 940 941 942 943 944 945 946

			/// 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
			);
		}
947 948 949
		else if (is_literal(group_exprs[i]))
		{
			remove_expr_at_index(i);
950 951 952 953 954
		}
		else
		{
			/// if neither a function nor literal - advance to next expression
			++i;
955
		}
956
	}
957 958

	if (group_exprs.empty())
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975
	{
		/** Нельзя полностью убирать 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);
		}

976 977
		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)));
978
	}
979 980 981
}


982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
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;
}


1014
void ExpressionAnalyzer::makeSetsForIndex()
P
Pavel Kartavyy 已提交
1015
{
1016
	if (storage && ast && storage->supportsIndexForIn())
A
Alexey Milovidov 已提交
1017
		makeSetsForIndexImpl(ast, storage->getSampleBlock());
P
Pavel Kartavyy 已提交
1018 1019
}

A
Alexey Milovidov 已提交
1020
void ExpressionAnalyzer::makeSetsForIndexImpl(ASTPtr & node, const Block & sample_block)
P
Pavel Kartavyy 已提交
1021 1022
{
	for (auto & child : node->children)
A
Alexey Milovidov 已提交
1023
		makeSetsForIndexImpl(child, sample_block);
P
Pavel Kartavyy 已提交
1024

1025
	ASTFunction * func = typeid_cast<ASTFunction *>(node.get());
1026
	if (func && func->kind == ASTFunction::FUNCTION && functionIsInOperator(func->name))
P
Pavel Kartavyy 已提交
1027 1028
	{
		IAST & args = *func->arguments;
1029
		ASTPtr & arg = args.children.at(1);
P
Pavel Kartavyy 已提交
1030

1031
		if (!typeid_cast<ASTSet *>(arg.get()) && !typeid_cast<ASTSubquery *>(arg.get()) && !typeid_cast<ASTIdentifier *>(arg.get()))
1032 1033 1034
		{
			try
			{
1035
				makeExplicitSet(func, sample_block, true);
1036 1037 1038 1039 1040 1041 1042 1043
			}
			catch (const DB::Exception & e)
			{
				/// в sample_block нет колонок, которые добаляет getActions
				if (e.code() != ErrorCodes::NOT_FOUND_COLUMN_IN_BLOCK)
					throw;
			}
		}
P
Pavel Kartavyy 已提交
1044 1045
	}
}
1046

1047

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

1055 1056
	if (!subquery && !table)
		throw Exception("IN/JOIN supports only SELECT subqueries.", ErrorCodes::BAD_ARGUMENTS);
1057

1058 1059 1060 1061
	/** Для подзапроса в секции IN/JOIN не действуют ограничения на максимальный размер результата.
	  * Так как результат этого поздапроса - ещё не результат всего запроса.
	  * Вместо этого работают ограничения
	  *  max_rows_in_set, max_bytes_in_set, set_overflow_mode,
1062 1063
	  *  max_rows_in_join, max_bytes_in_join, join_overflow_mode,
	  *  которые проверяются отдельно (в объектах Set, Join).
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
	  */
	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)
	{
1076
		/// create ASTSelectQuery for "SELECT * FROM table" as if written by hand
1077
		const auto select_query = std::make_shared<ASTSelectQuery>();
1078
		query = select_query;
1079

1080
		const auto select_expression_list = std::make_shared<ASTExpressionList>();
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
		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)
1091 1092
			select_expression_list->children.emplace_back(std::make_shared<ASTIdentifier>(
				StringRange{}, column.name));
1093 1094 1095

		select_query->table = subquery_or_table_name;
		select_query->children.emplace_back(select_query->table);
1096 1097
	}
	else
1098
	{
1099 1100
		query = subquery->children.at(0);

1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
		/** В подзапросе могут быть указаны столбцы с одинаковыми именами. Например, 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);
				}
			}
		}
	}

1137
	if (required_columns.empty())
1138 1139
		return std::make_shared<InterpreterSelectQuery>(
			query, subquery_context, QueryProcessingStage::Complete, subquery_depth + 1);
1140
	else
1141 1142
		return std::make_shared<InterpreterSelectQuery>(
			query, subquery_context, required_columns, QueryProcessingStage::Complete, subquery_depth + 1);
1143 1144
}

1145

1146
void ExpressionAnalyzer::makeSet(ASTFunction * node, const Block & sample_block)
1147
{
1148
	/** Нужно преобразовать правый аргумент в множество.
1149
	  * Это может быть имя таблицы, значение, перечисление значений или подзапрос.
1150 1151 1152
	  * Перечисление значений парсится как функция tuple.
	  */
	IAST & args = *node->arguments;
1153
	ASTPtr & arg = args.children.at(1);
1154

1155
	/// Уже преобразовали.
1156
	if (typeid_cast<ASTSet *>(arg.get()))
1157
		return;
1158

1159
	/// Если подзапрос или имя таблицы для SELECT.
1160 1161
	ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(arg.get());
	if (typeid_cast<ASTSubquery *>(arg.get()) || identifier)
1162
	{
1163 1164
		/// Получаем поток блоков для подзапроса. Создаём Set и кладём на место подзапроса.
		String set_id = arg->getColumnName();
1165
		auto ast_set = std::make_shared<ASTSet>(set_id);
1166
		ASTPtr ast_set_ptr = ast_set;
1167

1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187
		/// Особый случай - если справа оператора 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;
				}
			}
		}

1188
		SubqueryForSet & subquery_for_set = subqueries_for_sets[set_id];
1189

1190
		/// Если уже создали Set с таким же подзапросом/таблицей.
1191
		if (subquery_for_set.set)
1192
		{
1193 1194 1195
			ast_set->set = subquery_for_set.set;
			arg = ast_set_ptr;
			return;
1196
		}
1197

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

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

			/** Зачем используется 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), на котором нужная таблица будет заполнена.
			  *
			  * Замечание: это решение не очень хорошее, надо подумать лучше.
			  */
		}
1239

1240
		subquery_for_set.set = ast_set->set;
1241
		arg = ast_set_ptr;
1242
	}
1243
	else
1244
	{
A
Alexey Milovidov 已提交
1245
		/// Явное перечисление значений в скобках.
P
Pavel Kartavyy 已提交
1246
		makeExplicitSet(node, sample_block, false);
P
Pavel Kartavyy 已提交
1247 1248 1249 1250
	}
}

/// Случай явного перечисления значений.
P
Pavel Kartavyy 已提交
1251
void ExpressionAnalyzer::makeExplicitSet(ASTFunction * node, const Block & sample_block, bool create_ordered_set)
P
Pavel Kartavyy 已提交
1252
{
1253
	IAST & args = *node->arguments;
1254 1255 1256 1257

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

1258
	ASTPtr & arg = args.children.at(1);
1259

1260 1261
	DataTypes set_element_types;
	ASTPtr & left_arg = args.children.at(0);
1262

1263
	ASTFunction * left_arg_tuple = typeid_cast<ASTFunction *>(left_arg.get());
1264

1265 1266 1267
	if (left_arg_tuple && left_arg_tuple->name == "tuple")
	{
		for (const auto & arg : left_arg_tuple->arguments->children)
1268
		{
1269
			const auto & data_type = sample_block.getByName(arg->getColumnName()).type;
1270

1271 1272 1273
			/// @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);
1274

1275
			set_element_types.push_back(data_type);
1276
		}
1277 1278 1279 1280
	}
	else
	{
		DataTypePtr left_type = sample_block.getByName(left_arg->getColumnName()).type;
1281
		if (DataTypeArray * array_type = typeid_cast<DataTypeArray *>(left_type.get()))
1282
			set_element_types.push_back(array_type->getNestedType());
1283
		else
1284 1285
			set_element_types.push_back(left_type);
	}
1286

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

1291
	if (ASTFunction * set_func = typeid_cast<ASTFunction *>(arg.get()))
1292
	{
1293 1294
		if (set_func->name == "tuple")
		{
1295 1296 1297
			if (set_func->arguments->children.empty())
			{
				/// Пустое множество.
1298
				elements_ast = set_func->arguments;
1299 1300 1301
			}
			else
			{
A
Alexey Milovidov 已提交
1302
				/// Отличим случай (x, y) in ((1, 2), (3, 4)) от случая (x, y) in (1, 2).
1303
				ASTFunction * any_element = typeid_cast<ASTFunction *>(set_func->arguments->children.at(0).get());
1304 1305 1306 1307 1308
				if (set_element_types.size() >= 2 && (!any_element || any_element->name != "tuple"))
					single_value = true;
				else
					elements_ast = set_func->arguments;
			}
1309 1310 1311 1312 1313 1314 1315
		}
		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);
1316

1317
			single_value = true;
1318
		}
1319
	}
1320
	else if (typeid_cast<ASTLiteral *>(arg.get()))
1321 1322 1323 1324 1325 1326 1327 1328
	{
		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);
	}
1329

1330 1331
	if (single_value)
	{
1332
		ASTPtr exp_list = std::make_shared<ASTExpressionList>();
1333 1334 1335 1336
		exp_list->children.push_back(elements_ast);
		elements_ast = exp_list;
	}

1337
	auto ast_set = std::make_shared<ASTSet>(arg->getColumnName());
1338
	ast_set->set = std::make_shared<Set>(settings.limits);
1339
	ast_set->is_explicit = true;
1340
	ast_set->set->createFromAST(set_element_types, elements_ast, context, create_ordered_set);
1341
	arg = ast_set;
1342 1343 1344
}


1345
static String getUniqueName(const Block & block, const String & prefix)
1346 1347
{
	int i = 1;
1348
	while (block.has(prefix + toString(i)))
1349
		++i;
1350
	return prefix + toString(i);
1351 1352 1353
}


A
Alexey Milovidov 已提交
1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367
/** Для getActionsImpl.
  * Стек из ExpressionActions, соответствующих вложенным лямбда-выражениям.
  * Новое действие нужно добавлять на самый высокий возможный уровень.
  * Например, в выражении "select arrayMap(x -> x + column1 * column2, array1)"
  *  вычисление произведения нужно делать вне лямбда-выражения (оно не зависит от x), а вычисление суммы - внутри (зависит от x).
  */
struct ExpressionAnalyzer::ScopeStack
{
	struct Level
	{
		ExpressionActionsPtr actions;
		NameSet new_columns;
	};

1368
	using Levels = std::vector<Level>;
A
Alexey Milovidov 已提交
1369 1370 1371 1372

	Levels stack;
	Settings settings;

1373
	ScopeStack(const ExpressionActionsPtr & actions, const Settings & settings_)
A
Alexey Milovidov 已提交
1374 1375
		: settings(settings_)
	{
1376
		stack.emplace_back();
1377
		stack.back().actions = actions;
1378 1379 1380 1381

		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 已提交
1382 1383 1384 1385
	}

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

1389
		ColumnsWithTypeAndName all_columns;
A
Alexey Milovidov 已提交
1390 1391 1392 1393
		NameSet new_names;

		for (NamesAndTypesList::const_iterator it = input_columns.begin(); it != input_columns.end(); ++it)
		{
1394 1395 1396
			all_columns.emplace_back(nullptr, it->type, it->name);
			new_names.insert(it->name);
			stack.back().new_columns.insert(it->name);
A
Alexey Milovidov 已提交
1397 1398
		}

1399 1400
		const Block & prev_sample_block = prev.actions->getSampleBlock();
		for (size_t i = 0, size = prev_sample_block.columns(); i < size; ++i)
A
Alexey Milovidov 已提交
1401
		{
1402
			const ColumnWithTypeAndName & col = prev_sample_block.unsafeGetByPosition(i);
1403 1404
			if (!new_names.count(col.name))
				all_columns.push_back(col);
A
Alexey Milovidov 已提交
1405 1406
		}

1407
		stack.back().actions = std::make_shared<ExpressionActions>(all_columns, settings);
A
Alexey Milovidov 已提交
1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434
	}

	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)
		{
1435
			const ColumnWithTypeAndName & col = stack[level].actions->getSampleBlock().getByName(added[i]);
A
Alexey Milovidov 已提交
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447
			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;
	}

1448
	const Block & getSampleBlock() const
A
Alexey Milovidov 已提交
1449 1450 1451 1452 1453 1454
	{
		return stack.back().actions->getSampleBlock();
	}
};


1455
void ExpressionAnalyzer::getRootActions(ASTPtr ast, bool no_subqueries, bool only_consts, ExpressionActionsPtr & actions)
1456 1457
{
	ScopeStack scopes(actions, settings);
1458
	getActionsImpl(ast, no_subqueries, only_consts, scopes);
1459
	actions = scopes.popLevel();
1460 1461 1462
}


1463 1464
void ExpressionAnalyzer::getArrayJoinedColumns()
{
1465 1466
	if (select_query && select_query->array_join_expression_list)
	{
1467
		ASTs & array_join_asts = select_query->array_join_expression_list->children;
1468
		for (const auto & ast : array_join_asts)
1469
		{
1470 1471
			const String nested_table_name = ast->getColumnName();
			const String nested_table_alias = ast->getAliasOrColumnName();
1472

1473
			if (nested_table_alias == nested_table_name && !typeid_cast<const ASTIdentifier *>(ast.get()))
1474 1475 1476 1477
				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);
1478

1479
			array_join_alias_to_name[nested_table_alias] = nested_table_name;
1480
			array_join_name_to_alias[nested_table_name] = nested_table_alias;
1481 1482 1483
		}

		ASTs & query_asts = select_query->children;
1484
		for (const auto & ast : query_asts)
1485 1486 1487 1488 1489
		{
			/// Не опускаемся в подзапросы и UNION.
			if (typeid_cast<const ASTSelectQuery *>(ast.get()))
				continue;

1490 1491
			if (ast != select_query->array_join_expression_list)
				getArrayJoinedColumnsImpl(ast);
1492
		}
1493 1494 1495

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

1502
			/// Это массив.
1503
			if (!typeid_cast<ASTIdentifier *>(expr.get()) || findColumn(source_name, columns) != columns.end())
1504
			{
1505
				array_join_result_to_source[result_name] = source_name;
1506 1507 1508 1509
			}
			else /// Это вложенная таблица.
			{
				bool found = false;
A
Alexey Milovidov 已提交
1510
				for (const auto & column_name_type : columns)
1511
				{
1512 1513
					String table_name = DataTypeNested::extractNestedTableName(column_name_type.name);
					String column_name = DataTypeNested::extractNestedColumnName(column_name_type.name);
1514 1515
					if (table_name == source_name)
					{
1516
						array_join_result_to_source[DataTypeNested::concatenateNestedName(result_name, column_name)] = column_name_type.name;
1517 1518 1519 1520
						found = true;
						break;
					}
				}
1521 1522
				if (!found)
					throw Exception("No columns in nested table " + source_name, ErrorCodes::EMPTY_NESTED_TABLE);
1523 1524
			}
		}
1525
	}
1526 1527 1528
}


1529
/// Заполняет array_join_result_to_source: по каким столбцам-массивам размножить, и как их после этого назвать.
1530
void ExpressionAnalyzer::getArrayJoinedColumnsImpl(ASTPtr ast)
1531
{
1532
	if (ASTIdentifier * node = typeid_cast<ASTIdentifier *>(ast.get()))
1533
	{
1534 1535 1536
		if (node->kind == ASTIdentifier::Column)
		{
			String table_name = DataTypeNested::extractNestedTableName(node->name);
1537

1538
			if (array_join_alias_to_name.count(node->name))
1539 1540 1541 1542
			{
				/// Был написан 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
			}
1543 1544
			else if (array_join_alias_to_name.count(table_name))
			{
1545 1546 1547
				/// Был написан 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
1548 1549
					= DataTypeNested::concatenateNestedName(array_join_alias_to_name[table_name], nested_column);
			}
1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
			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;
			}
1560
		}
1561 1562 1563
	}
	else
	{
1564
		for (auto & child : ast->children)
1565
			if (!typeid_cast<const ASTSelectQuery *>(child.get()))
1566
				getArrayJoinedColumnsImpl(child);
1567 1568 1569 1570 1571
	}
}


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

1578
	if (ASTIdentifier * node = typeid_cast<ASTIdentifier *>(ast.get()))
1579 1580 1581 1582 1583
	{
		std::string name = node->getColumnName();
		if (!only_consts && !actions_stack.getSampleBlock().has(name))
		{
			/// Запрошенного столбца нет в блоке.
1584
			/// Если такой столбец есть в таблице, значит пользователь наверно забыл окружить его агрегатной функцией или добавить в GROUP BY.
1585 1586

			bool found = false;
A
Alexey Milovidov 已提交
1587
			for (const auto & column_name_type : columns)
1588
				if (column_name_type.name == name)
1589 1590 1591 1592
					found = true;

			if (found)
				throw Exception("Column " + name + " is not under aggregate function and not in GROUP BY.",
1593
					ErrorCodes::NOT_AN_AGGREGATE);
1594 1595
		}
	}
1596
	else if (ASTFunction * node = typeid_cast<ASTFunction *>(ast.get()))
1597
	{
1598
		if (node->kind == ASTFunction::LAMBDA_EXPRESSION)
1599
			throw Exception("Unexpected lambda expression", ErrorCodes::UNEXPECTED_EXPRESSION);
1600

1601
		/// Функция arrayJoin.
1602 1603 1604 1605
		if (node->kind == ASTFunction::ARRAY_JOIN)
		{
			if (node->arguments->children.size() != 1)
				throw Exception("arrayJoin requires exactly 1 argument", ErrorCodes::TYPE_MISMATCH);
1606

1607
			ASTPtr arg = node->arguments->children.at(0);
1608
			getActionsImpl(arg, no_subqueries, only_consts, actions_stack);
1609
			if (!only_consts)
1610
			{
1611
				String result_name = node->getColumnName();
1612
				actions_stack.addAction(ExpressionAction::copyColumn(arg->getColumnName(), result_name));
1613 1614
				NameSet joined_columns;
				joined_columns.insert(result_name);
1615
				actions_stack.addAction(ExpressionAction::arrayJoin(joined_columns, false));
1616
			}
1617

1618 1619
			return;
		}
1620

1621
		if (node->kind == ASTFunction::FUNCTION)
1622
		{
1623
			if (functionIsInOrGlobalInOperator(node->name))
1624 1625 1626
			{
				if (!no_subqueries)
				{
1627
					/// Найдем тип первого аргумента (потом getActionsImpl вызовется для него снова и ни на что не повлияет).
1628
					getActionsImpl(node->arguments->children.at(0), no_subqueries, only_consts, actions_stack);
1629

1630
					/// Превратим tuple или подзапрос в множество.
1631
					makeSet(node, actions_stack.getSampleBlock());
1632 1633 1634
				}
				else
				{
1635 1636 1637 1638
					if (!only_consts)
					{
						/// Мы в той части дерева, которую не собираемся вычислять. Нужно только определить типы.
						/// Не будем выполнять подзапросы и составлять множества. Вставим произвольный столбец правильного типа.
1639
						ColumnWithTypeAndName fake_column;
1640
						fake_column.name = node->getColumnName();
1641
						fake_column.type = std::make_shared<DataTypeUInt8>();
1642
						actions_stack.addAction(ExpressionAction::addColumn(fake_column));
1643
						getActionsImpl(node->arguments->children.at(0), no_subqueries, only_consts, actions_stack);
1644
					}
1645 1646 1647
					return;
				}
			}
1648

1649 1650 1651 1652 1653
			/// Особая функция indexHint. Всё, что внутри неё не вычисляется
			/// (а используется только для анализа индекса, см. PKCondition).
			if (node->name == "indexHint")
			{
				actions_stack.addAction(ExpressionAction::addColumn(ColumnWithTypeAndName(
1654
					std::make_shared<ColumnConstUInt8>(1, 1), std::make_shared<DataTypeUInt8>(), node->getColumnName())));
1655 1656 1657
				return;
			}

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

1660 1661
			Names argument_names;
			DataTypes argument_types;
M
Merge  
Michael Kolupaev 已提交
1662
			bool arguments_present = true;
1663

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

1667
			for (auto & child : node->arguments->children)
1668
			{
1669 1670
				ASTFunction * lambda = typeid_cast<ASTFunction *>(child.get());
				ASTSet * set = typeid_cast<ASTSet *>(child.get());
1671 1672
				if (lambda && lambda->name == "lambda")
				{
M
Merge  
Michael Kolupaev 已提交
1673
					/// Если аргумент - лямбда-выражение, только запомним его примерный тип.
1674 1675
					if (lambda->arguments->children.size() != 2)
						throw Exception("lambda requires two arguments", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
1676

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

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

1682
					has_lambda_arguments = true;
1683
					argument_types.emplace_back(std::make_shared<DataTypeExpression>(DataTypes(lambda_args_tuple->arguments->children.size())));
1684
					/// Выберем название в следующем цикле.
1685
					argument_names.emplace_back();
1686
				}
1687 1688
				else if (set)
				{
1689
					ColumnWithTypeAndName column;
1690
					column.type = std::make_shared<DataTypeSet>();
1691

1692 1693
					/// Если аргумент - множество, заданное перечислением значений, дадим ему уникальное имя,
					///  чтобы множества с одинаковой записью не склеивались (у них может быть разный тип).
1694
					if (set->is_explicit)
1695 1696 1697 1698 1699 1700
						column.name = getUniqueName(actions_stack.getSampleBlock(), "__set");
					else
						column.name = set->getColumnName();

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

1703
						actions_stack.addAction(ExpressionAction::addColumn(column));
1704
					}
1705

1706 1707 1708
					argument_types.push_back(column.type);
					argument_names.push_back(column.name);
				}
1709 1710
				else
				{
M
Merge  
Michael Kolupaev 已提交
1711
					/// Если аргумент не лямбда-выражение, вызовемся рекурсивно и узнаем его тип.
1712
					getActionsImpl(child, no_subqueries, only_consts, actions_stack);
1713
					std::string name = child->getColumnName();
1714
					if (actions_stack.getSampleBlock().has(name))
M
Merge  
Michael Kolupaev 已提交
1715
					{
1716
						argument_types.push_back(actions_stack.getSampleBlock().getByName(name).type);
M
Merge  
Michael Kolupaev 已提交
1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729
						argument_names.push_back(name);
					}
					else
					{
						if (only_consts)
						{
							arguments_present = false;
						}
						else
						{
							throw Exception("Unknown identifier: " + name, ErrorCodes::UNKNOWN_IDENTIFIER);
						}
					}
1730 1731
				}
			}
1732

M
Merge  
Michael Kolupaev 已提交
1733 1734
			if (only_consts && !arguments_present)
				return;
1735

1736
			Names additional_requirements;
1737

1738 1739 1740
			if (has_lambda_arguments && !only_consts)
			{
				function->getLambdaArgumentTypes(argument_types);
1741

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

1747
					ASTFunction * lambda = typeid_cast<ASTFunction *>(child.get());
1748 1749
					if (lambda && lambda->name == "lambda")
					{
1750 1751
						DataTypeExpression * lambda_type = typeid_cast<DataTypeExpression *>(argument_types[i].get());
						ASTFunction * lambda_args_tuple = typeid_cast<ASTFunction *>(lambda->arguments->children.at(0).get());
1752
						ASTs lambda_arg_asts = lambda_args_tuple->arguments->children;
1753
						NamesAndTypesList lambda_arguments;
1754

1755 1756
						for (size_t j = 0; j < lambda_arg_asts.size(); ++j)
						{
1757
							ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(lambda_arg_asts[j].get());
1758 1759
							if (!identifier)
								throw Exception("lambda argument declarations must be identifiers", ErrorCodes::TYPE_MISMATCH);
1760

1761
							String arg_name = identifier->name;
1762

1763
							lambda_arguments.emplace_back(arg_name, lambda_type->getArgumentTypes()[j]);
1764
						}
1765

1766
						actions_stack.pushLevel(lambda_arguments);
1767
						getActionsImpl(lambda->arguments->children.at(1), no_subqueries, only_consts, actions_stack);
1768
						ExpressionActionsPtr lambda_actions = actions_stack.popLevel();
1769

1770
						String result_name = lambda->arguments->children.at(1)->getColumnName();
1771
						lambda_actions->finalize(Names(1, result_name));
1772
						DataTypePtr result_type = lambda_actions->getSampleBlock().getByName(result_name).type;
1773
						argument_types[i] = std::make_shared<DataTypeExpression>(lambda_type->getArgumentTypes(), result_type);
1774

1775 1776 1777 1778
						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]);
1779

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

1784
						ColumnWithTypeAndName lambda_column;
1785
						lambda_column.column = std::make_shared<ColumnExpression>(1, lambda_actions, lambda_arguments, result_type, result_name);
1786 1787
						lambda_column.type = argument_types[i];
						lambda_column.name = argument_names[i];
1788
						actions_stack.addAction(ExpressionAction::addColumn(lambda_column));
1789 1790 1791
					}
				}
			}
1792

1793 1794 1795 1796
			if (only_consts)
			{
				for (size_t i = 0; i < argument_names.size(); ++i)
				{
1797
					if (!actions_stack.getSampleBlock().has(argument_names[i]))
1798
					{
M
Merge  
Michael Kolupaev 已提交
1799
						arguments_present = false;
1800 1801 1802 1803
						break;
					}
				}
			}
1804

M
Merge  
Michael Kolupaev 已提交
1805
			if (arguments_present)
1806
				actions_stack.addAction(ExpressionAction::applyFunction(function, argument_names, node->getColumnName()),
1807
										additional_requirements);
1808 1809
		}
	}
1810
	else if (ASTLiteral * node = typeid_cast<ASTLiteral *>(ast.get()))
1811 1812
	{
		DataTypePtr type = apply_visitor(FieldToDataType(), node->value);
1813

1814
		ColumnWithTypeAndName column;
1815 1816 1817
		column.column = type->createConstColumn(1, node->value);
		column.type = type;
		column.name = node->getColumnName();
1818

1819
		actions_stack.addAction(ExpressionAction::addColumn(column));
1820 1821 1822
	}
	else
	{
1823 1824
		for (auto & child : ast->children)
			getActionsImpl(child, no_subqueries, only_consts, actions_stack);
1825 1826 1827 1828
	}
}


1829
void ExpressionAnalyzer::getAggregates(const ASTPtr & ast, ExpressionActionsPtr & actions)
1830
{
1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845
	/// Внутри 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());
1846
	if (node && node->kind == ASTFunction::AGGREGATE_FUNCTION)
1847
	{
1848
		has_aggregation = true;
1849 1850
		AggregateDescription aggregate;
		aggregate.column_name = node->getColumnName();
1851

1852
		/// Агрегатные функции уникализируются.
1853 1854 1855
		for (size_t i = 0; i < aggregate_descriptions.size(); ++i)
			if (aggregate_descriptions[i].column_name == aggregate.column_name)
				return;
1856

1857
		const ASTs & arguments = node->arguments->children;
1858 1859
		aggregate.argument_names.resize(arguments.size());
		DataTypes types(arguments.size());
1860

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

1866
			getRootActions(arguments[i], true, false, actions);
1867
			const std::string & name = arguments[i]->getColumnName();
1868
			types[i] = actions->getSampleBlock().getByName(name).type;
1869 1870
			aggregate.argument_names[i] = name;
		}
1871

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

1874 1875
		if (node->parameters)
		{
1876
			const ASTs & parameters = typeid_cast<const ASTExpressionList &>(*node->parameters).children;
1877
			Array params_row(parameters.size());
1878

1879 1880
			for (size_t i = 0; i < parameters.size(); ++i)
			{
1881
				const ASTLiteral * lit = typeid_cast<const ASTLiteral *>(parameters[i].get());
1882
				if (!lit)
1883 1884
					throw Exception("Parameters to aggregate functions must be literals",
						ErrorCodes::PARAMETERS_TO_AGGREGATE_FUNCTIONS_MUST_BE_LITERALS);
1885

1886 1887
				params_row[i] = lit->value;
			}
1888

1889
			aggregate.parameters = params_row;
1890 1891
			aggregate.function->setParameters(params_row);
		}
1892

1893
		aggregate.function->setArguments(types);
1894

1895 1896 1897 1898
		aggregate_descriptions.push_back(aggregate);
	}
	else
	{
1899 1900
		for (const auto & child : ast->children)
			if (!typeid_cast<const ASTSubquery *>(child.get()) && !typeid_cast<const ASTSelectQuery *>(child.get()))
1901
				getAggregates(child, actions);
1902 1903 1904
	}
}

1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919

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);
}


1920
void ExpressionAnalyzer::assertSelect() const
1921 1922 1923 1924
{
	if (!select_query)
		throw Exception("Not a select query", ErrorCodes::LOGICAL_ERROR);
}
1925

1926
void ExpressionAnalyzer::assertAggregation() const
1927 1928 1929
{
	if (!has_aggregation)
		throw Exception("No aggregation", ErrorCodes::LOGICAL_ERROR);
1930
}
1931

1932
void ExpressionAnalyzer::initChain(ExpressionActionsChain & chain, const NamesAndTypesList & columns) const
1933 1934 1935 1936
{
	if (chain.steps.empty())
	{
		chain.settings = settings;
1937
		chain.steps.emplace_back(std::make_shared<ExpressionActions>(columns, settings));
1938 1939
	}
}
1940

1941
/// "Большой" ARRAY JOIN.
1942
void ExpressionAnalyzer::addMultipleArrayJoinAction(ExpressionActionsPtr & actions) const
1943
{
1944
	NameSet result_columns;
1945
	for (const auto & result_source : array_join_result_to_source)
1946
	{
1947
		/// Дать столбцам новые имена, если надо.
1948 1949
		if (result_source.first != result_source.second)
			actions->add(ExpressionAction::copyColumn(result_source.second, result_source.first));
1950 1951

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

1955
	actions->add(ExpressionAction::arrayJoin(result_columns, select_query->array_join_is_left));
1956 1957
}

1958
bool ExpressionAnalyzer::appendArrayJoin(ExpressionActionsChain & chain, bool only_types)
1959 1960
{
	assertSelect();
1961 1962

	if (!select_query->array_join_expression_list)
1963
		return false;
1964

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

1968
	getRootActions(select_query->array_join_expression_list, only_types, false, step.actions);
1969

1970
	addMultipleArrayJoinAction(step.actions);
1971

1972 1973 1974
	return true;
}

1975
void ExpressionAnalyzer::addJoinAction(ExpressionActionsPtr & actions, bool only_types) const
1976
{
1977 1978 1979 1980 1981 1982
	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));
1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994
}

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

	if (!select_query->join)
		return false;

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

1995
	ASTJoin & ast_join = typeid_cast<ASTJoin &>(*select_query->join);
1996 1997
	if (ast_join.using_expr_list)
		getRootActions(ast_join.using_expr_list, only_types, false, step.actions);
1998

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

	SubqueryForSet & subquery_for_set = subqueries_for_sets[join_id];
2003 2004 2005

	/// Особый случай - если справа JOIN указано имя таблицы, при чём, таблица имеет тип Join (заранее подготовленное отображение).
	/// TODO В этом синтаксисе не поддерживается указание имени БД.
2006
	ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(ast_join.table.get());
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025
	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;
			}
		}
	}

2026
	if (!subquery_for_set.join)
2027
	{
2028
		JoinPtr join = std::make_shared<Join>(join_key_names_left, join_key_names_right, settings.limits, ast_join.kind, ast_join.strictness);
2029

2030
		Names required_joined_columns(join_key_names_right.begin(), join_key_names_right.end());
2031
		for (const auto & name_type : columns_added_by_join)
2032
			required_joined_columns.push_back(name_type.name);
2033

2034
		/** Для GLOBAL JOIN-ов (в случае, например, push-метода выполнения GLOBAL подзапросов) происходит следующее:
2035 2036 2037 2038 2039
		  * - в функции addExternalStorage подзапрос JOIN (SELECT ...) заменяется на JOIN _data1,
		  *   в объекте subquery_for_set выставляется этот подзапрос в качестве source и временная таблица _data1 в качестве table.
		  * - в этой функции видно выражение JOIN _data1.
		  */
		if (!subquery_for_set.source)
2040 2041
		{
			auto interpreter = interpretSubquery(ast_join.table, context, subquery_depth, required_joined_columns);
2042
			subquery_for_set.source = std::make_shared<LazyBlockInputStream>([interpreter]() mutable { return interpreter->execute().in; });
2043
			subquery_for_set.source_sample = interpreter->getSampleBlock();
2044
		}
2045

2046
		/// TODO Это не нужно выставлять, когда JOIN нужен только на удалённых серверах.
2047
		subquery_for_set.join = join;
2048
		subquery_for_set.join->setSampleBlock(subquery_for_set.source_sample);
2049 2050
	}

2051
	addJoinAction(step.actions, false);
2052 2053 2054 2055

	return true;
}

2056
bool ExpressionAnalyzer::appendWhere(ExpressionActionsChain & chain, bool only_types)
2057 2058
{
	assertSelect();
2059

2060 2061
	if (!select_query->where_expression)
		return false;
2062

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

2066
	step.required_output.push_back(select_query->where_expression->getColumnName());
2067
	getRootActions(select_query->where_expression, only_types, false, step.actions);
2068

2069 2070 2071
	return true;
}

2072
bool ExpressionAnalyzer::appendGroupBy(ExpressionActionsChain & chain, bool only_types)
2073 2074
{
	assertAggregation();
2075

2076 2077
	if (!select_query->group_expression_list)
		return false;
2078

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

2082
	ASTs asts = select_query->group_expression_list->children;
2083 2084
	for (size_t i = 0; i < asts.size(); ++i)
	{
2085
		step.required_output.push_back(asts[i]->getColumnName());
2086
		getRootActions(asts[i], only_types, false, step.actions);
2087
	}
2088

2089 2090 2091
	return true;
}

2092
void ExpressionAnalyzer::appendAggregateFunctionsArguments(ExpressionActionsChain & chain, bool only_types)
2093 2094
{
	assertAggregation();
2095

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

2099 2100 2101 2102 2103 2104 2105
	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]);
		}
	}
2106

2107
	getActionsBeforeAggregation(select_query->select_expression_list, step.actions, only_types);
2108

2109
	if (select_query->having_expression)
2110
		getActionsBeforeAggregation(select_query->having_expression, step.actions, only_types);
2111

2112
	if (select_query->order_expression_list)
2113
		getActionsBeforeAggregation(select_query->order_expression_list, step.actions, only_types);
2114 2115
}

2116
bool ExpressionAnalyzer::appendHaving(ExpressionActionsChain & chain, bool only_types)
2117 2118
{
	assertAggregation();
2119

2120 2121
	if (!select_query->having_expression)
		return false;
2122

2123 2124
	initChain(chain, aggregated_columns);
	ExpressionActionsChain::Step & step = chain.steps.back();
2125

2126
	step.required_output.push_back(select_query->having_expression->getColumnName());
2127
	getRootActions(select_query->having_expression, only_types, false, step.actions);
2128

2129
	return true;
2130 2131
}

2132
void ExpressionAnalyzer::appendSelect(ExpressionActionsChain & chain, bool only_types)
2133 2134
{
	assertSelect();
2135

2136 2137
	initChain(chain, aggregated_columns);
	ExpressionActionsChain::Step & step = chain.steps.back();
2138

2139
	getRootActions(select_query->select_expression_list, only_types, false, step.actions);
2140

2141 2142 2143 2144 2145
	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());
	}
2146
}
2147

2148
bool ExpressionAnalyzer::appendOrderBy(ExpressionActionsChain & chain, bool only_types)
2149
{
2150
	assertSelect();
2151

2152 2153
	if (!select_query->order_expression_list)
		return false;
2154

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

2158
	getRootActions(select_query->order_expression_list, only_types, false, step.actions);
2159

2160 2161 2162
	ASTs asts = select_query->order_expression_list->children;
	for (size_t i = 0; i < asts.size(); ++i)
	{
2163
		ASTOrderByElement * ast = typeid_cast<ASTOrderByElement *>(asts[i].get());
2164 2165
		if (!ast || ast->children.size() != 1)
			throw Exception("Bad order expression AST", ErrorCodes::UNKNOWN_TYPE_OF_AST_NODE);
2166
		ASTPtr order_expression = ast->children.at(0);
2167 2168
		step.required_output.push_back(order_expression->getColumnName());
	}
2169

2170 2171 2172
	return true;
}

2173
void ExpressionAnalyzer::appendProjectResult(DB::ExpressionActionsChain & chain, bool only_types) const
2174 2175
{
	assertSelect();
2176

2177 2178
	initChain(chain, aggregated_columns);
	ExpressionActionsChain::Step & step = chain.steps.back();
2179

2180
	NamesWithAliases result_columns;
2181

2182
	ASTs asts = select_query->select_expression_list->children;
2183
	for (size_t i = 0; i < asts.size(); ++i)
2184
	{
2185 2186
		result_columns.emplace_back(asts[i]->getColumnName(), asts[i]->getAliasOrColumnName());
		step.required_output.push_back(result_columns.back().second);
2187
	}
2188

2189
	step.actions->add(ExpressionAction::project(result_columns));
2190 2191 2192
}


2193 2194 2195
Block ExpressionAnalyzer::getSelectSampleBlock()
{
	assertSelect();
2196

2197
	ExpressionActionsPtr temp_actions = std::make_shared<ExpressionActions>(aggregated_columns, settings);
2198
	NamesWithAliases result_columns;
2199

2200 2201 2202
	ASTs asts = select_query->select_expression_list->children;
	for (size_t i = 0; i < asts.size(); ++i)
	{
2203
		result_columns.emplace_back(asts[i]->getColumnName(), asts[i]->getAliasOrColumnName());
2204
		getRootActions(asts[i], true, false, temp_actions);
2205
	}
2206

2207
	temp_actions->add(ExpressionAction::project(result_columns));
2208

2209
	return temp_actions->getSampleBlock();
2210 2211
}

2212
void ExpressionAnalyzer::getActionsBeforeAggregation(ASTPtr ast, ExpressionActionsPtr & actions, bool no_subqueries)
2213
{
2214
	ASTFunction * node = typeid_cast<ASTFunction *>(ast.get());
2215

2216 2217 2218
	if (node && node->kind == ASTFunction::AGGREGATE_FUNCTION)
		for (auto & argument : node->arguments->children)
			getRootActions(argument, no_subqueries, false, actions);
2219
	else
2220 2221
		for (auto & child : ast->children)
			getActionsBeforeAggregation(child, actions, no_subqueries);
2222 2223 2224
}


M
Merge  
Michael Kolupaev 已提交
2225
ExpressionActionsPtr ExpressionAnalyzer::getActions(bool project_result)
2226
{
2227
	ExpressionActionsPtr actions = std::make_shared<ExpressionActions>(columns, settings);
2228
	NamesWithAliases result_columns;
2229
	Names result_names;
2230

2231
	ASTs asts;
2232

2233
	if (auto node = typeid_cast<const ASTExpressionList *>(ast.get()))
2234
		asts = node->children;
2235
	else
2236
		asts = ASTs(1, ast);
2237

2238
	for (size_t i = 0; i < asts.size(); ++i)
2239
	{
2240 2241 2242
		std::string name = asts[i]->getColumnName();
		std::string alias;
		if (project_result)
A
Alexey Milovidov 已提交
2243
			alias = asts[i]->getAliasOrColumnName();
2244 2245
		else
			alias = name;
2246
		result_columns.emplace_back(name, alias);
2247
		result_names.push_back(alias);
2248
		getRootActions(asts[i], false, false, actions);
2249
	}
2250

M
Merge  
Michael Kolupaev 已提交
2251 2252
	if (project_result)
	{
2253
		actions->add(ExpressionAction::project(result_columns));
M
Merge  
Michael Kolupaev 已提交
2254
	}
M
Merge  
Michael Kolupaev 已提交
2255 2256 2257
	else
	{
		/// Не будем удалять исходные столбцы.
A
Alexey Milovidov 已提交
2258
		for (const auto & column_name_type : columns)
2259
			result_names.push_back(column_name_type.name);
M
Merge  
Michael Kolupaev 已提交
2260
	}
2261

2262
	actions->finalize(result_names);
2263

2264 2265 2266 2267 2268 2269
	return actions;
}


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

2272
	getRootActions(ast, true, true, actions);
2273

2274 2275 2276
	return actions;
}

2277
void ExpressionAnalyzer::getAggregateInfo(Names & key_names, AggregateDescriptions & aggregates) const
2278
{
2279 2280
	for (const auto & name_and_type : aggregation_keys)
		key_names.emplace_back(name_and_type.name);
2281

2282 2283 2284
	aggregates = aggregate_descriptions;
}

2285
void ExpressionAnalyzer::collectUsedColumns()
2286
{
A
Alexey Milovidov 已提交
2287 2288 2289 2290 2291 2292 2293
	/** Вычислим, какие столбцы требуются для выполнения выражения.
	  * Затем, удалим все остальные столбцы из списка доступных столбцов.
	  * После выполнения, columns будет содержать только список столбцов, нужных для чтения из таблицы.
	  */

	NameSet required;
	NameSet ignored;
2294

2295 2296 2297 2298 2299 2300
	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.
2301
			/// Их потом добавим отдельно.
2302
			if (typeid_cast<ASTIdentifier *>(expressions[i].get()))
2303
			{
2304
				ignored.insert(expressions[i]->getColumnName());
2305 2306 2307 2308
			}
			else
			{
				/// Для выражений в ARRAY JOIN ничего игнорировать не нужно.
A
Alexey Milovidov 已提交
2309
				NameSet empty;
2310
				getRequiredColumnsImpl(expressions[i], required, empty, empty, empty);
2311
			}
2312

A
Alexey Milovidov 已提交
2313
			ignored.insert(expressions[i]->getAliasOrColumnName());
2314 2315
		}
	}
2316

2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327
	/** Также нужно не учитывать идентификаторы столбцов, получающихся путём 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();)
	{
2328
		if (required_joined_columns.count(it->name))
2329 2330 2331 2332 2333
			++it;
		else
			columns_added_by_join.erase(it++);
	}

2334
/*	for (const auto & name_type : columns_added_by_join)
2335
		std::cerr << "JOINed column (required, not key): " << name_type.name << std::endl;
2336
	std::cerr << std::endl;*/
2337

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

	for (const auto & column_name_type : columns)
2344 2345
		if (array_join_sources.count(column_name_type.name))
			required.insert(column_name_type.name);
2346

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

2351
	unknown_required_columns = required;
2352

2353 2354
	for (NamesAndTypesList::iterator it = columns.begin(); it != columns.end();)
	{
2355
		unknown_required_columns.erase(it->name);
2356

2357
		if (!required.count(it->name))
2358
		{
2359
			required.erase(it->name);
A
Alexey Milovidov 已提交
2360
			columns.erase(it++);
2361
		}
A
Alexey Milovidov 已提交
2362 2363
		else
			++it;
2364
	}
S
Merge  
Sergey Fedorov 已提交
2365

2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380
	/// Возможно, среди неизвестных столбцов есть виртуальные. Удаляем их из списка неизвестных и добавляем
	/// в 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;
		}
	}
2381 2382
}

2383
void ExpressionAnalyzer::collectJoinedColumns(NameSet & joined_columns, NamesAndTypesList & joined_columns_name_type)
2384 2385 2386 2387
{
	if (!select_query || !select_query->join)
		return;

2388
	auto & node = typeid_cast<ASTJoin &>(*select_query->join);
2389

2390 2391 2392 2393 2394 2395 2396 2397
	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()))
	{
2398
		const auto & subquery = node.table->children.at(0);
2399
		nested_result_sample = InterpreterSelectQuery::getSampleBlock(subquery, context);
2400
	}
2401

2402
	if (node.using_expr_list)
2403
	{
2404 2405 2406
		auto & keys = typeid_cast<ASTExpressionList &>(*node.using_expr_list);
		for (const auto & key : keys.children)
		{
2407 2408 2409 2410
			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);
2411

2412 2413 2414 2415
			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);
2416
		}
2417 2418
	}

2419
	for (const auto i : ext::range(0, nested_result_sample.columns()))
2420
	{
2421
		const auto & col = nested_result_sample.getByPosition(i);
2422 2423
		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-а не имеют смысла.
2424
		{
2425 2426
			joined_columns.insert(col.name);
			joined_columns_name_type.emplace_back(col.name, col.type);
2427
		}
2428
	}
2429

2430
/*	for (const auto & name : join_key_names_left)
2431
		std::cerr << "JOIN key (left): " << name << std::endl;
2432
	for (const auto & name : join_key_names_right)
2433
		std::cerr << "JOIN key (right): " << name << std::endl;
2434 2435 2436
	std::cerr << std::endl;
	for (const auto & name : joined_columns)
		std::cerr << "JOINed column: " << name << std::endl;
2437
	std::cerr << std::endl;*/
2438 2439
}

2440 2441
Names ExpressionAnalyzer::getRequiredColumns()
{
M
Merge  
Michael Kolupaev 已提交
2442 2443
	if (!unknown_required_columns.empty())
		throw Exception("Unknown identifier: " + *unknown_required_columns.begin(), ErrorCodes::UNKNOWN_IDENTIFIER);
2444

2445
	Names res;
2446
	for (const auto & column_name_type : columns)
2447
		res.push_back(column_name_type.name);
A
Alexey Milovidov 已提交
2448

2449 2450 2451
	return res;
}

2452 2453 2454
void ExpressionAnalyzer::getRequiredColumnsImpl(ASTPtr ast,
	NameSet & required_columns, NameSet & ignored_names,
	const NameSet & available_joined_columns, NameSet & required_joined_columns)
2455
{
2456 2457 2458 2459 2460
	/** Найдём все идентификаторы в запросе.
	  * Будем искать их рекурсивно, обходя в глубину AST.
	  * При этом:
	  * - для лямбда функций не будем брать формальные параметры;
	  * - не опускаемся в подзапросы (там свои идентификаторы);
2461 2462
	  * - некоторое исключение для секции ARRAY JOIN (в ней идентификаторы немного другие);
	  * - идентификаторы, доступные из JOIN-а, кладём в required_joined_columns.
2463 2464
	  */

2465
	if (ASTIdentifier * node = typeid_cast<ASTIdentifier *>(ast.get()))
2466
	{
2467 2468 2469
		if (node->kind == ASTIdentifier::Column
			&& !ignored_names.count(node->name)
			&& !ignored_names.count(DataTypeNested::extractNestedTableName(node->name)))
2470
		{
2471 2472 2473 2474
			if (!available_joined_columns.count(node->name))
				required_columns.insert(node->name);
			else
				required_joined_columns.insert(node->name);
2475
		}
A
Alexey Milovidov 已提交
2476

2477 2478
		return;
	}
2479

2480
	if (ASTFunction * node = typeid_cast<ASTFunction *>(ast.get()))
2481 2482 2483 2484 2485
	{
		if (node->kind == ASTFunction::LAMBDA_EXPRESSION)
		{
			if (node->arguments->children.size() != 2)
				throw Exception("lambda requires two arguments", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
2486

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

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

2492
			/// Не нужно добавлять формальные параметры лямбда-выражения в required_columns.
2493
			Names added_ignored;
2494
			for (auto & child : lambda_args_tuple->arguments->children)
2495
			{
2496
				ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(child.get());
2497 2498
				if (!identifier)
					throw Exception("lambda argument declarations must be identifiers", ErrorCodes::TYPE_MISMATCH);
2499 2500

				String & name = identifier->name;
2501 2502 2503 2504 2505 2506
				if (!ignored_names.count(name))
				{
					ignored_names.insert(name);
					added_ignored.push_back(name);
				}
			}
2507

2508
			getRequiredColumnsImpl(node->arguments->children.at(1),
2509 2510
				required_columns, ignored_names,
				available_joined_columns, required_joined_columns);
2511

2512 2513
			for (size_t i = 0; i < added_ignored.size(); ++i)
				ignored_names.erase(added_ignored[i]);
2514

2515 2516
			return;
		}
2517 2518 2519 2520 2521

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

2524
	ASTSelectQuery * select = typeid_cast<ASTSelectQuery *>(ast.get());
2525

2526 2527
	/// Рекурсивный обход выражения.
	for (auto & child : ast->children)
2528
	{
2529
		/** Не пойдем в секцию ARRAY JOIN, потому что там нужно смотреть на имена не-ARRAY-JOIN-енных столбцов.
2530
		  * Туда collectUsedColumns отправит нас отдельно.
2531
		  */
2532
		if (!typeid_cast<ASTSubquery *>(child.get()) && !typeid_cast<ASTSelectQuery *>(child.get()) &&
2533
			!(select && child == select->array_join_expression_list))
2534
			getRequiredColumnsImpl(child, required_columns, ignored_names, available_joined_columns, required_joined_columns);
2535
    }
2536 2537
}

2538
}