@@ -208,7 +208,7 @@ DataTypePtr getLeastSupertype(const DataTypes & types)
208208 }
209209 }
210210
211- // / For Date and DateTime, the common type is DateTime. No other types are compatible.
211+ // / For Date and DateTime/DateTime64 , the common type is DateTime/DateTime64 . No other types are compatible.
212212 {
213213 UInt32 have_date = type_ids.count (TypeIndex::Date);
214214 UInt32 have_datetime = type_ids.count (TypeIndex::DateTime);
@@ -218,40 +218,25 @@ DataTypePtr getLeastSupertype(const DataTypes & types)
218218 {
219219 bool all_date_or_datetime = type_ids.size () == (have_date + have_datetime + have_datetime64);
220220 if (!all_date_or_datetime)
221- throw Exception (getExceptionMessagePrefix (types) + " because some of them are Date/DateTime and some of them are not" , ErrorCodes::NO_COMMON_TYPE);
221+ throw Exception (getExceptionMessagePrefix (types) + " because some of them are Date/DateTime/DateTime64 and some of them are not" ,
222+ ErrorCodes::NO_COMMON_TYPE);
222223
223224 if (have_datetime64 == 0 )
224- {
225225 return std::make_shared<DataTypeDateTime>();
226- }
227226
228- // When DateTime64 involved, make sure that supertype has whole-part precision
229- // big enough to hold max whole-value of any type from `types`.
230- // That would sacrifice scale when comparing DateTime64 of different scales.
227+ UInt8 max_scale = 0 ;
231228
232- UInt32 max_datetime64_whole_precision = 0 ;
233229 for (const auto & t : types)
234230 {
235231 if (const auto * dt64 = typeid_cast<const DataTypeDateTime64 *>(t.get ()))
236232 {
237- const auto whole_precision = dt64->getPrecision () - dt64->getScale ();
238- max_datetime64_whole_precision = std::max (whole_precision, max_datetime64_whole_precision);
233+ const auto scale = dt64->getScale ();
234+ if (scale > max_scale)
235+ max_scale = scale;
239236 }
240237 }
241238
242- UInt32 least_decimal_precision = 0 ;
243- if (have_datetime)
244- {
245- least_decimal_precision = leastDecimalPrecisionFor (TypeIndex::UInt32);
246- }
247- else if (have_date)
248- {
249- least_decimal_precision = leastDecimalPrecisionFor (TypeIndex::UInt16);
250- }
251- max_datetime64_whole_precision = std::max (least_decimal_precision, max_datetime64_whole_precision);
252-
253- const UInt32 scale = DataTypeDateTime64::maxPrecision () - max_datetime64_whole_precision;
254- return std::make_shared<DataTypeDateTime64>(scale);
239+ return std::make_shared<DataTypeDateTime64>(max_scale);
255240 }
256241 }
257242
0 commit comments