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

Function nativeCastWithDecimalScale

src/DataTypes/Native.cpp:220–362  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

218}
219
220llvm::Value * nativeCastWithDecimalScale(
221 llvm::IRBuilderBase & b, const DataTypePtr & from_type, llvm::Value * value, const DataTypePtr & to_type)
222{
223 if (from_type->equals(*to_type))
224 return value;
225
226 if (from_type->isNullable() && to_type->isNullable())
227 {
228 auto * inner_value = b.CreateExtractValue(value, {0});
229 auto * is_null = b.CreateExtractValue(value, {1});
230 auto * inner = nativeCastWithDecimalScale(b, removeNullable(from_type), inner_value, removeNullable(to_type));
231 auto * to_native_type = toNativeType(b, to_type);
232 llvm::Value * result = llvm::Constant::getNullValue(to_native_type);
233 result = b.CreateInsertValue(result, inner, {0});
234 return b.CreateInsertValue(result, is_null, {1});
235 }
236 if (from_type->isNullable())
237 {
238 return nativeCastWithDecimalScale(b, removeNullable(from_type), b.CreateExtractValue(value, {0}), to_type);
239 }
240 if (to_type->isNullable())
241 {
242 auto * to_native_type = toNativeType(b, to_type);
243 auto * inner = nativeCastWithDecimalScale(b, from_type, value, removeNullable(to_type));
244 return b.CreateInsertValue(llvm::Constant::getNullValue(to_native_type), inner, {0});
245 }
246
247 WhichDataType from_w(*from_type);
248 WhichDataType to_w(*to_type);
249
250 /// Only intercept conversions involving `Decimal` here. Everything else
251 /// — including `DateTime` / `DateTime64` / `Time` / `Time64` scale lifts —
252 /// is already handled correctly by `nativeCast`.
253 if (to_w.isDecimal() || from_w.isDecimal())
254 {
255 auto * from_native_type = toNativeType(b, from_type);
256 auto * to_native_type = toNativeType(b, to_type);
257 const UInt32 to_scale = to_w.isDecimal() ? getDecimalScale(*to_type) : 0;
258 const UInt32 from_scale = from_w.isDecimal() ? getDecimalScale(*from_type) : 0;
259
260 /// Build LLVM integer constant for `10^n` of the requested bit width.
261 auto pow10_int_const = [&](unsigned bit_width, UInt32 n) -> llvm::ConstantInt *
262 {
263 llvm::APInt v(bit_width, 1);
264 for (UInt32 i = 0; i < n; ++i)
265 v *= 10;
266 return llvm::cast<llvm::ConstantInt>(llvm::ConstantInt::get(b.getContext(), v));
267 };
268
269 /// Build LLVM floating-point constant for `10^n` from an `APInt` of the requested bit width.
270 /// This goes through `APFloat::convertFromAPInt` rather than `APInt::getZExtValue` so that
271 /// it stays correct when `10^n` does not fit in 64 bits (e.g. `Decimal128` with `scale = 38`,
272 /// or `Decimal256` with even larger scales).
273 auto pow10_fp_const = [&](unsigned bit_width, UInt32 n, llvm::Type * fp_type) -> llvm::Constant *
274 {
275 llvm::APInt v(bit_width, 1);
276 for (UInt32 i = 0; i < n; ++i)
277 v *= 10;

Callers 1

compileImplMethod · 0.85

Calls 15

toNativeTypeFunction · 0.85
getDecimalScaleFunction · 0.85
typeIsSignedFunction · 0.85
isIntMethod · 0.80
isUIntMethod · 0.80
isEnumMethod · 0.80
isDate32Method · 0.80
isFloat32Method · 0.80
isFloat64Method · 0.80
removeNullableFunction · 0.70
nativeCastFunction · 0.70
getFunction · 0.50

Tested by

no test coverage detected