|
31 | 31 | #include "udf/udf.h" |
32 | 32 | #include "util/binary_cast.hpp" |
33 | 33 | #include "vec/columns/column_decimal.h" |
| 34 | +#include "vec/columns/column.h" |
34 | 35 | #include "vec/columns/column_nullable.h" |
35 | 36 | #include "vec/columns/column_string.h" |
36 | 37 | #include "vec/columns/column_vector.h" |
|
43 | 44 | #include "vec/data_types/data_type_decimal.h" |
44 | 45 | #include "vec/data_types/data_type_string.h" |
45 | 46 | #include "vec/functions/date_format_type.h" |
| 47 | +#include "vec/runtime/time_value.h" |
46 | 48 | #include "vec/runtime/vdatetime_value.h" |
47 | 49 | #include "vec/utils/util.hpp" |
48 | 50 |
|
@@ -431,139 +433,6 @@ struct FromUnixTimeDecimalImpl { |
431 | 433 | } |
432 | 434 | }; |
433 | 435 |
|
434 | | -// Base template for optimized time field(HOUR, MINUTE, SECOND, MS) extraction from Unix timestamp |
435 | | -// Uses lookup_offset to avoid expensive civil_second construction |
436 | | -template <typename Impl> |
437 | | -class FunctionTimeFieldFromUnixtime : public IFunction { |
438 | | -public: |
439 | | - static constexpr auto name = Impl::name; |
440 | | - static FunctionPtr create() { return std::make_shared<FunctionTimeFieldFromUnixtime<Impl>>(); } |
441 | | - |
442 | | - String get_name() const override { return name; } |
443 | | - |
444 | | - size_t get_number_of_arguments() const override { return 1; } |
445 | | - |
446 | | - DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { |
447 | | - // microsecond_from_unixtime returns Int32, others (hour/minute/second) return Int8 |
448 | | - if constexpr (Impl::ArgType == PrimitiveType::TYPE_DECIMAL64) { |
449 | | - return make_nullable(std::make_shared<DataTypeInt32>()); |
450 | | - } else { |
451 | | - return make_nullable(std::make_shared<DataTypeInt8>()); |
452 | | - } |
453 | | - } |
454 | | - |
455 | | - // (UTC 9999-12-31 23:59:59) - 24 * 3600 |
456 | | - static const int64_t TIMESTAMP_VALID_MAX = 253402243199L; |
457 | | - |
458 | | - Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
459 | | - uint32_t result, size_t input_rows_count) const override { |
460 | | - using ArgColType = PrimitiveTypeTraits<Impl::ArgType>::ColumnType; |
461 | | - using ResColType = std::conditional_t<Impl::ArgType == PrimitiveType::TYPE_DECIMAL64, |
462 | | - ColumnInt32, ColumnInt8>; |
463 | | - using ResItemType = typename ResColType::value_type; |
464 | | - auto res = ResColType::create(); |
465 | | - |
466 | | - const auto* ts_col = |
467 | | - assert_cast<const ArgColType*>(block.get_by_position(arguments[0]).column.get()); |
468 | | - if constexpr (Impl::ArgType == PrimitiveType::TYPE_DECIMAL64) { |
469 | | - // microsecond_from_unixtime only |
470 | | - const auto scale = static_cast<int32_t>(ts_col->get_scale()); |
471 | | - |
472 | | - for (int i = 0; i < input_rows_count; ++i) { |
473 | | - const auto seconds = ts_col->get_intergral_part(i); |
474 | | - const auto fraction = ts_col->get_fractional_part(i); |
475 | | - |
476 | | - if (seconds < 0 || seconds > TIMESTAMP_VALID_MAX) { |
477 | | - return Status::InvalidArgument( |
478 | | - "The input value of TimeFiled(from_unixtime()) must between 0 and " |
479 | | - "253402243199L"); |
480 | | - } |
481 | | - |
482 | | - ResItemType value = Impl::extract_field(fraction, scale); |
483 | | - res->insert_value(value); |
484 | | - } |
485 | | - } else { |
486 | | - auto ctz = context->state()->timezone_obj(); |
487 | | - for (int i = 0; i < input_rows_count; ++i) { |
488 | | - auto date = ts_col->get_element(i); |
489 | | - |
490 | | - if (date < 0 || date > TIMESTAMP_VALID_MAX) { |
491 | | - return Status::InvalidArgument( |
492 | | - "The input value of TimeFiled(from_unixtime()) must between 0 and " |
493 | | - "253402243199L"); |
494 | | - } |
495 | | - |
496 | | - ResItemType value = Impl::extract_field(date, ctz); |
497 | | - res->insert_value(value); |
498 | | - } |
499 | | - } |
500 | | - block.replace_by_position(result, std::move(res)); |
501 | | - return Status::OK(); |
502 | | - } |
503 | | -}; |
504 | | - |
505 | | -struct HourFromUnixtimeImpl { |
506 | | - static constexpr PrimitiveType ArgType = PrimitiveType::TYPE_BIGINT; |
507 | | - static constexpr auto name = "hour_from_unixtime"; |
508 | | - |
509 | | - static int8_t extract_field(int64_t local_time, const cctz::time_zone& ctz) { |
510 | | - static const auto epoch = std::chrono::time_point_cast<cctz::sys_seconds>( |
511 | | - std::chrono::system_clock::from_time_t(0)); |
512 | | - cctz::time_point<cctz::sys_seconds> t = epoch + cctz::seconds(local_time); |
513 | | - int offset = ctz.lookup_offset(t).offset; |
514 | | - local_time += offset; |
515 | | - |
516 | | - static const libdivide::divider<int64_t> fast_div_3600(3600); |
517 | | - static const libdivide::divider<int64_t> fast_div_86400(86400); |
518 | | - |
519 | | - int64_t remainder; |
520 | | - if (LIKELY(local_time >= 0)) { |
521 | | - remainder = local_time - local_time / fast_div_86400 * 86400; |
522 | | - } else { |
523 | | - remainder = local_time % 86400; |
524 | | - if (remainder < 0) { |
525 | | - remainder += 86400; |
526 | | - } |
527 | | - } |
528 | | - return static_cast<int8_t>(remainder / fast_div_3600); |
529 | | - } |
530 | | -}; |
531 | | - |
532 | | -struct MinuteFromUnixtimeImpl { |
533 | | - static constexpr PrimitiveType ArgType = PrimitiveType::TYPE_BIGINT; |
534 | | - static constexpr auto name = "minute_from_unixtime"; |
535 | | - |
536 | | - static int8_t extract_field(int64_t local_time, const cctz::time_zone& /*ctz*/) { |
537 | | - static const libdivide::divider<int64_t> fast_div_60(60); |
538 | | - static const libdivide::divider<int64_t> fast_div_3600(3600); |
539 | | - |
540 | | - local_time = local_time - local_time / fast_div_3600 * 3600; |
541 | | - |
542 | | - return static_cast<int8_t>(local_time / fast_div_60); |
543 | | - } |
544 | | -}; |
545 | | - |
546 | | -struct SecondFromUnixtimeImpl { |
547 | | - static constexpr PrimitiveType ArgType = PrimitiveType::TYPE_BIGINT; |
548 | | - static constexpr auto name = "second_from_unixtime"; |
549 | | - |
550 | | - static int8_t extract_field(int64_t local_time, const cctz::time_zone& /*ctz*/) { |
551 | | - return static_cast<int8_t>(local_time % 60); |
552 | | - } |
553 | | -}; |
554 | | - |
555 | | -struct MicrosecondFromUnixtimeImpl { |
556 | | - static constexpr PrimitiveType ArgType = PrimitiveType::TYPE_DECIMAL64; |
557 | | - static constexpr auto name = "microsecond_from_unixtime"; |
558 | | - |
559 | | - static int32_t extract_field(int64_t fraction, int scale) { |
560 | | - if (scale < 6) { |
561 | | - fraction *= common::exp10_i64(6 - scale); |
562 | | - } |
563 | | - return static_cast<int32_t>(fraction); |
564 | | - } |
565 | | -}; |
566 | | - |
567 | 436 | #include "common/compile_check_end.h" |
568 | 437 | } // namespace doris::vectorized |
569 | 438 |
|
|
0 commit comments