diff --git a/src/Analyzer/FunctionNode.cpp b/src/Analyzer/FunctionNode.cpp index 68bdb0f9956..fe170c8482e 100644 --- a/src/Analyzer/FunctionNode.cpp +++ b/src/Analyzer/FunctionNode.cpp @@ -63,7 +63,8 @@ ColumnsWithTypeAndName FunctionNode::getArgumentColumns() const else argument_column.type = argument->getResultType(); - if (auto * constant = argument->as()) + auto * constant = argument->as(); + if (constant && !isNotCreatable(argument_column.type)) argument_column.column = argument_column.type->createColumnConst(1, constant->getValue()); argument_columns.push_back(std::move(argument_column)); diff --git a/src/Analyzer/Passes/LogicalExpressionOptimizer.cpp b/src/Analyzer/Passes/LogicalExpressionOptimizerPass.cpp similarity index 97% rename from src/Analyzer/Passes/LogicalExpressionOptimizer.cpp rename to src/Analyzer/Passes/LogicalExpressionOptimizerPass.cpp index 73585a4cd23..3d65035f9fd 100644 --- a/src/Analyzer/Passes/LogicalExpressionOptimizer.cpp +++ b/src/Analyzer/Passes/LogicalExpressionOptimizerPass.cpp @@ -7,8 +7,6 @@ #include #include -#include - namespace DB { @@ -100,6 +98,9 @@ private: } } + if (and_operands.size() == function_node.getArguments().getNodes().size()) + return; + if (and_operands.size() == 1) { /// AND operator can have UInt8 or bool as its type. @@ -207,6 +208,9 @@ private: or_operands.push_back(std::move(in_function)); } + if (or_operands.size() == function_node.getArguments().getNodes().size()) + return; + if (or_operands.size() == 1) { /// if the result type of operand is the same as the result type of OR diff --git a/src/Analyzer/Passes/QueryAnalysisPass.cpp b/src/Analyzer/Passes/QueryAnalysisPass.cpp index b85999523c3..38575965973 100644 --- a/src/Analyzer/Passes/QueryAnalysisPass.cpp +++ b/src/Analyzer/Passes/QueryAnalysisPass.cpp @@ -6676,6 +6676,17 @@ void QueryAnalyzer::resolveQuery(const QueryTreeNodePtr & query_node, Identifier /// Resolve query node sections. + NamesAndTypes projection_columns; + + if (!scope.group_by_use_nulls) + { + projection_columns = resolveProjectionExpressionNodeList(query_node_typed.getProjectionNode(), scope); + if (query_node_typed.getProjection().getNodes().empty()) + throw Exception(ErrorCodes::EMPTY_LIST_OF_COLUMNS_QUERIED, + "Empty list of columns in projection. In scope {}", + scope.scope_node->formatASTForErrorMessage()); + } + if (query_node_typed.hasWith()) resolveExpressionNodeList(query_node_typed.getWithNode(), scope, true /*allow_lambda_expression*/, false /*allow_table_expression*/); @@ -6770,11 +6781,14 @@ void QueryAnalyzer::resolveQuery(const QueryTreeNodePtr & query_node, Identifier convertLimitOffsetExpression(query_node_typed.getOffset(), "OFFSET", scope); } - auto projection_columns = resolveProjectionExpressionNodeList(query_node_typed.getProjectionNode(), scope); - if (query_node_typed.getProjection().getNodes().empty()) - throw Exception(ErrorCodes::EMPTY_LIST_OF_COLUMNS_QUERIED, - "Empty list of columns in projection. In scope {}", - scope.scope_node->formatASTForErrorMessage()); + if (scope.group_by_use_nulls) + { + projection_columns = resolveProjectionExpressionNodeList(query_node_typed.getProjectionNode(), scope); + if (query_node_typed.getProjection().getNodes().empty()) + throw Exception(ErrorCodes::EMPTY_LIST_OF_COLUMNS_QUERIED, + "Empty list of columns in projection. In scope {}", + scope.scope_node->formatASTForErrorMessage()); + } /** Resolve nodes with duplicate aliases. * Table expressions cannot have duplicate aliases. @@ -6843,7 +6857,7 @@ void QueryAnalyzer::resolveQuery(const QueryTreeNodePtr & query_node, Identifier for (const auto & column : projection_columns) { - if (isNotCreatable(column.type->getTypeId())) + if (isNotCreatable(column.type)) throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Invalid projection column with type {}. In scope {}", column.type->getName(),