MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / autoAssignNumberForEnum

Function autoAssignNumberForEnum

src/DataTypes/DataTypeEnum.cpp:258–317  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

256}
257
258static std::vector<UInt8> autoAssignNumberForEnum(const ASTPtr & arguments, bool allow_relative)
259{
260 Int64 literal_child_assign_num = 1;
261 ASTs assign_number_child;
262 assign_number_child.reserve(arguments->children.size());
263 /// Each rewritten element keeps a flag that tells `mergeEnumTypes` whether its assigned
264 /// number is a temporary relative placeholder or an explicit final value.
265 std::vector<UInt8> relative_flags;
266 if (allow_relative)
267 relative_flags.reserve(arguments->children.size());
268 bool is_first_child = true;
269 size_t assign_count= 0;
270 bool leading_implicit = true;
271
272 for (const ASTPtr & child : arguments->children)
273 {
274 if (child->as<ASTLiteral>())
275 {
276 assign_count += !is_first_child;
277 /// Keep the addition signed and checked: Int64 + size_t would run unsigned (negative
278 /// base wraps to a huge UInt64), and a plain signed add overflows near Int64 max.
279 Int64 assign_num = 0;
280 if (common::addOverflow(literal_child_assign_num, static_cast<Int64>(assign_count), assign_num))
281 throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND,
282 "Auto-assigned value for Enum element overflows Int64 (base {} + offset {})",
283 literal_child_assign_num, assign_count);
284 ASTPtr func = makeASTOperator("equals", child, make_intrusive<ASTLiteral>(assign_num));
285 assign_number_child.emplace_back(func);
286 if (allow_relative)
287 relative_flags.push_back(leading_implicit);
288 }
289 else if (child->as<ASTFunction>())
290 {
291 if (is_first_child)
292 {
293 const auto literals = getEnumElementLiterals(child);
294 const auto * value_literal = literals.value_literal;
295 literal_child_assign_num = value_literal->value.safeGet<Int64>();
296 }
297 assign_number_child.emplace_back(child);
298 if (allow_relative)
299 relative_flags.push_back(0);
300 leading_implicit = false;
301 }
302 else
303 throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE,
304 "Elements of Enum data type must be of form: "
305 "'name' = number or 'name', where name is string literal and number is an integer");
306
307 is_first_child = false;
308 }
309
310 if (assign_count != 0 && assign_count != arguments->children.size() - 1)
311 throw Exception(ErrorCodes::UNEXPECTED_AST_STRUCTURE,
312 "All elements of Enum data type must be of form: "
313 "'name' = number or 'name', where name is string literal and number is an integer");
314
315 arguments->children = assign_number_child;

Callers 2

createExactFunction · 0.85
createFunction · 0.85

Calls 8

addOverflowFunction · 0.85
makeASTOperatorFunction · 0.85
getEnumElementLiteralsFunction · 0.85
ExceptionClass · 0.50
reserveMethod · 0.45
sizeMethod · 0.45
emplace_backMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected