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

Function nativeCast

src/DataTypes/Native.cpp:130–213  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

128}
129
130llvm::Value * nativeCast(llvm::IRBuilderBase & b, const DataTypePtr & from_type, llvm::Value * value, const DataTypePtr & to_type)
131{
132 if (from_type->equals(*to_type))
133 {
134 return value;
135 }
136 if (from_type->isNullable() && to_type->isNullable())
137 {
138 auto * inner = nativeCast(b, removeNullable(from_type), b.CreateExtractValue(value, {0}), to_type);
139 return b.CreateInsertValue(inner, b.CreateExtractValue(value, {1}), {1});
140 }
141 if (from_type->isNullable())
142 {
143 return nativeCast(b, removeNullable(from_type), b.CreateExtractValue(value, {0}), to_type);
144 }
145 if (to_type->isNullable())
146 {
147 auto * to_native_type = toNativeType(b, to_type);
148 auto * inner = nativeCast(b, from_type, value, removeNullable(to_type));
149 return b.CreateInsertValue(llvm::Constant::getNullValue(to_native_type), inner, {0});
150 }
151 auto * from_native_type = toNativeType(b, from_type);
152 auto * to_native_type = toNativeType(b, to_type);
153
154 /// Handle scale conversion for DateTime/DateTime64/Time/Time64 types.
155 /// When converting between types with different scales (e.g., DateTime with implicit
156 /// scale 0 to DateTime64 with scale 3), we need to multiply/divide by the appropriate
157 /// power of 10, not just cast the integer value.
158 /// Note: Decimal types are NOT handled here because JIT-compiled aggregate functions
159 /// (e.g., avg) already manage Decimal scale conversion themselves.
160 {
161 auto get_effective_scale = [](const DataTypePtr & type) -> std::optional<UInt32>
162 {
163 WhichDataType which(type);
164 if (which.isDateTime() || which.isTime())
165 return 0u;
166 if (which.isDateTime64())
167 return typeid_cast<const DataTypeDateTime64 *>(type.get())->getScale();
168 if (which.isTime64())
169 return typeid_cast<const DataTypeTime64 *>(type.get())->getScale();
170 return std::nullopt;
171 };
172
173 auto from_scale = get_effective_scale(from_type);
174 auto to_scale = get_effective_scale(to_type);
175
176 if (from_scale && to_scale && *from_scale != *to_scale)
177 {
178 /// First widen/narrow the integer type if needed.
179 if (from_native_type != to_native_type)
180 value = b.CreateIntCast(value, to_native_type, typeIsSigned(*from_type));
181
182 UInt32 scale_diff = (*to_scale > *from_scale) ? (*to_scale - *from_scale) : (*from_scale - *to_scale);
183 unsigned bit_width = to_native_type->getIntegerBitWidth();
184 llvm::APInt scale_factor(bit_width, 1);
185 for (UInt32 i = 0; i < scale_diff; ++i)
186 scale_factor *= 10;
187 auto * scale_constant = llvm::ConstantInt::get(b.getContext(), scale_factor);

Callers 1

Calls 15

toNativeTypeFunction · 0.85
typeIsSignedFunction · 0.85
isDateTime64Method · 0.80
isTime64Method · 0.80
removeNullableFunction · 0.70
getFunction · 0.50
ExceptionClass · 0.50
equalsMethod · 0.45
isNullableMethod · 0.45
isDateTimeMethod · 0.45
isTimeMethod · 0.45
getScaleMethod · 0.45

Tested by

no test coverage detected