@@ -593,23 +593,31 @@ static std::shared_ptr<clickhouse::Column> makeArrColumn(ColumnType type)
593593 return column;
594594}
595595
596- static std::shared_ptr<clickhouse::Column> makeNonArrColumn (ColumnType type)
596+ static std::shared_ptr<clickhouse::Column> makeNonArrColumn (ColumnType type, bool nullable )
597597{
598598 std::shared_ptr<clickhouse::Column> column;
599- visit (type, [&](auto traits) {
600- using ColType = clickhouse::ColumnNullableT<typename decltype (traits)::ColumnType>;
601- column = std::make_shared<ColType>();
602- });
599+
600+ if (nullable) {
601+ visit (type, [&](auto traits) {
602+ using ColType = clickhouse::ColumnNullableT<typename decltype (traits)::ColumnType>;
603+ column = std::make_shared<ColType>();
604+ });
605+ } else {
606+ visit (type, [&](auto traits) {
607+ using ColType = typename decltype (traits)::ColumnType;
608+ column = std::make_shared<ColType>();
609+ });
610+ }
603611
604612 return column;
605613}
606614
607- std::shared_ptr<clickhouse::Column> makeColumn (ColumnType type)
615+ std::shared_ptr<clickhouse::Column> makeColumn (ColumnType type, bool nullable )
608616{
609617 if (isArr (type)) {
610618 return makeArrColumn (type);
611619 }
612- return makeNonArrColumn (type);
620+ return makeNonArrColumn (type, nullable );
613621}
614622
615623GetterFn makeGetter (ColumnType type)
@@ -644,40 +652,68 @@ static ColumnWriterFn makeArrColumnwriter(ColumnType type)
644652 return columnwriter;
645653}
646654
647- static ColumnWriterFn makeNonArrColumnwriter (ColumnType type)
655+ static ColumnWriterFn makeNonArrColumnwriter (ColumnType type, bool nullable )
648656{
649657 ColumnWriterFn columnwriter;
650658
651- visitNonArr (type, [&](auto traits) {
652- columnwriter = [](ValueVariant* value, clickhouse::Column& column) {
653- using ColumnType = clickhouse::ColumnNullableT<typename decltype (traits)::ColumnType>;
654- using ValueType = std::invoke_result_t <
655- decltype (decltype (traits)::GETTER),
656- Nemea::UnirecRecordView&,
657- ur_field_type_t >;
658- auto * col = dynamic_cast <ColumnType*>(&column);
659- if (!value) {
660- col->Append (std::nullopt );
661- } else {
662- col->Append (std::get<ValueType>(*value));
663- }
664- };
665- });
659+ if (nullable) {
660+ visitNonArr (type, [&](auto traits) {
661+ columnwriter = [](ValueVariant* value, clickhouse::Column& column) {
662+ using ColumnType = clickhouse::ColumnNullableT<typename decltype (traits)::ColumnType>;
663+ using ValueType = std::invoke_result_t <
664+ decltype (decltype (traits)::GETTER),
665+ Nemea::UnirecRecordView&,
666+ ur_field_type_t >;
667+ auto * col = dynamic_cast <ColumnType*>(&column);
668+ if (!value) {
669+ col->Append (std::nullopt );
670+ } else {
671+ col->Append (std::get<ValueType>(*value));
672+ }
673+ };
674+ });
675+ } else {
676+ visitNonArr (type, [&](auto traits) {
677+ columnwriter = [](ValueVariant* value, clickhouse::Column& column) {
678+ using ColumnType = typename decltype (traits)::ColumnType;
679+ using ValueType = std::invoke_result_t <
680+ decltype (decltype (traits)::GETTER),
681+ Nemea::UnirecRecordView&,
682+ ur_field_type_t >;
683+ auto * col = dynamic_cast <ColumnType*>(&column);
684+ if (!value) {
685+ throw std::runtime_error (" NULL value for non-nullable column" );
686+ }
687+ // Cast to avoid sign conversion warnings for DateTime64
688+ if constexpr (std::is_same_v<ValueType, uint64_t > && std::is_same_v<ColumnType, ColumnDateTime64<g_TIME_PRECISION>>) {
689+ col->Append (static_cast <int64_t >(std::get<ValueType>(*value)));
690+ } else {
691+ col->Append (std::get<ValueType>(*value));
692+ }
693+ };
694+ });
695+ }
666696
667697 return columnwriter;
668698}
669699
670- ColumnWriterFn makeColumnwriter (ColumnType type)
700+ ColumnWriterFn makeColumnwriter (ColumnType type, bool nullable )
671701{
672702 if (isArr (type)) {
673703 return makeArrColumnwriter (type);
674704 }
675- return makeNonArrColumnwriter (type);
705+ return makeNonArrColumnwriter (type, nullable );
676706}
677707
678- std::string typeToClickhouse (ColumnType type)
708+ std::string typeToClickhouse (ColumnType type, bool nullable )
679709{
680710 std::string result;
681711 visit (type, [&](auto traits) { result = traits.CLICKHOUSE_TYPE_NAME ; });
712+
713+ // Don't wrap arrays in Nullable
714+ if (nullable && !isArr (type)) {
715+ result = " Nullable(" + result + " )" ;
716+ }
717+
682718 return result;
683719}
0 commit comments