| 66 | } |
| 67 | |
| 68 | static DataTypePtr create(const ASTPtr & arguments) |
| 69 | { |
| 70 | if (!arguments || arguments->children.empty()) |
| 71 | return std::make_shared<DataTypeDynamic>(); |
| 72 | |
| 73 | if (arguments->children.size() > 1) |
| 74 | throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, |
| 75 | "Dynamic data type can have only one optional argument - the maximum number of dynamic types in a form 'Dynamic(max_types=N)"); |
| 76 | |
| 77 | |
| 78 | const auto * argument = arguments->children[0]->as<ASTFunction>(); |
| 79 | if (!argument || argument->name != "equals") |
| 80 | throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE, "Dynamic data type argument should be in a form 'max_types=N'"); |
| 81 | |
| 82 | /// The `equals` function expects exactly two children: an identifier and a literal. |
| 83 | /// Validate the argument list shape before indexing. |
| 84 | if (!argument->arguments || argument->arguments->children.size() != 2) |
| 85 | throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE, "Dynamic data type argument should be in a form 'max_types=N'"); |
| 86 | |
| 87 | const auto & identifier_node = argument->arguments->children[0]; |
| 88 | const auto * identifier = identifier_node->as<ASTIdentifier>(); |
| 89 | if (!identifier) |
| 90 | throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE, "Unexpected Dynamic type argument: {}. Expected expression 'max_types=N'", identifier_node->formatForErrorMessage()); |
| 91 | |
| 92 | auto identifier_name = identifier->name(); |
| 93 | if (identifier_name != "max_types") |
| 94 | throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE, "Unexpected identifier: {}. Dynamic data type argument should be in a form 'max_types=N'", identifier_name); |
| 95 | |
| 96 | auto * literal = argument->arguments->children[1]->as<ASTLiteral>(); |
| 97 | |
| 98 | if (!literal || literal->value.getType() != Field::Types::UInt64 || literal->value.safeGet<UInt64>() > ColumnDynamic::MAX_DYNAMIC_TYPES_LIMIT) |
| 99 | throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE, "'max_types' argument for Dynamic type should be a positive integer between 0 and {}", ColumnDynamic::MAX_DYNAMIC_TYPES_LIMIT); |
| 100 | |
| 101 | return std::make_shared<DataTypeDynamic>(literal->value.safeGet<UInt64>()); |
| 102 | } |
| 103 | |
| 104 | void registerDataTypeDynamic(DataTypeFactory & factory) |
| 105 | { |
no test coverage detected