@@ -389,6 +389,12 @@ nlohmann::json ToJson(const Type& type) {
389389 return " uuid" ;
390390 case TypeId::kUnknown :
391391 return " unknown" ;
392+ case TypeId::kVariant :
393+ return " variant" ;
394+ case TypeId::kGeometry :
395+ return type.ToString ();
396+ case TypeId::kGeography :
397+ return type.ToString ();
392398 }
393399 std::unreachable ();
394400}
@@ -486,58 +492,97 @@ Result<std::unique_ptr<Type>> MapTypeFromJson(const nlohmann::json& json) {
486492Result<std::unique_ptr<Type>> TypeFromJson (const nlohmann::json& json) {
487493 if (json.is_string ()) {
488494 std::string type_str = json.get <std::string>();
489- if (type_str == " boolean" ) {
495+ std::string lower_type_str = StringUtils::ToLower (type_str);
496+ if (lower_type_str == " boolean" ) {
490497 return std::make_unique<BooleanType>();
491- } else if (type_str == " int" ) {
498+ } else if (lower_type_str == " int" ) {
492499 return std::make_unique<IntType>();
493- } else if (type_str == " long" ) {
500+ } else if (lower_type_str == " long" ) {
494501 return std::make_unique<LongType>();
495- } else if (type_str == " float" ) {
502+ } else if (lower_type_str == " float" ) {
496503 return std::make_unique<FloatType>();
497- } else if (type_str == " double" ) {
504+ } else if (lower_type_str == " double" ) {
498505 return std::make_unique<DoubleType>();
499- } else if (type_str == " date" ) {
506+ } else if (lower_type_str == " date" ) {
500507 return std::make_unique<DateType>();
501- } else if (type_str == " time" ) {
508+ } else if (lower_type_str == " time" ) {
502509 return std::make_unique<TimeType>();
503- } else if (type_str == " timestamp" ) {
510+ } else if (lower_type_str == " timestamp" ) {
504511 return std::make_unique<TimestampType>();
505- } else if (type_str == " timestamptz" ) {
512+ } else if (lower_type_str == " timestamptz" ) {
506513 return std::make_unique<TimestampTzType>();
507- } else if (type_str == " timestamp_ns" ) {
514+ } else if (lower_type_str == " timestamp_ns" ) {
508515 return std::make_unique<TimestampNsType>();
509- } else if (type_str == " timestamptz_ns" ) {
516+ } else if (lower_type_str == " timestamptz_ns" ) {
510517 return std::make_unique<TimestampTzNsType>();
511- } else if (type_str == " string" ) {
518+ } else if (lower_type_str == " string" ) {
512519 return std::make_unique<StringType>();
513- } else if (type_str == " binary" ) {
520+ } else if (lower_type_str == " binary" ) {
514521 return std::make_unique<BinaryType>();
515- } else if (type_str == " uuid" ) {
522+ } else if (lower_type_str == " uuid" ) {
516523 return std::make_unique<UuidType>();
517- } else if (type_str == " unknown" ) {
524+ } else if (lower_type_str == " unknown" ) {
518525 return std::make_unique<UnknownType>();
519- } else if (type_str.starts_with (" fixed" )) {
520- std::regex fixed_regex (R"( fixed\[\s*(\d+)\s*\])" );
526+ } else if (lower_type_str == " variant" ) {
527+ return std::make_unique<VariantType>();
528+ } else if (lower_type_str.starts_with (" fixed" )) {
529+ static const std::regex fixed_regex (R"( fixed\[\s*(\d+)\s*\])" );
521530 std::smatch match;
522- if (std::regex_match (type_str , match, fixed_regex)) {
531+ if (std::regex_match (lower_type_str , match, fixed_regex)) {
523532 ICEBERG_ASSIGN_OR_RAISE (auto length,
524533 StringUtils::ParseNumber<int32_t >(match[1 ].str ()));
525534 return std::make_unique<FixedType>(length);
526535 }
527536 return JsonParseError (" Invalid fixed type: {}" , type_str);
528- } else if (type_str .starts_with (" decimal" )) {
529- std::regex decimal_regex (R"( decimal\(\s*(\d+)\s*,\s*(\d+)\s*\))" );
537+ } else if (lower_type_str .starts_with (" decimal" )) {
538+ static const std::regex decimal_regex (R"( decimal\(\s*(\d+)\s*,\s*(\d+)\s*\))" );
530539 std::smatch match;
531- if (std::regex_match (type_str , match, decimal_regex)) {
540+ if (std::regex_match (lower_type_str , match, decimal_regex)) {
532541 ICEBERG_ASSIGN_OR_RAISE (auto precision,
533542 StringUtils::ParseNumber<int32_t >(match[1 ].str ()));
534543 ICEBERG_ASSIGN_OR_RAISE (auto scale,
535544 StringUtils::ParseNumber<int32_t >(match[2 ].str ()));
536545 return std::make_unique<DecimalType>(precision, scale);
537546 }
538547 return JsonParseError (" Invalid decimal type: {}" , type_str);
548+ } else if (lower_type_str.starts_with (" geometry" )) {
549+ static const std::regex geometry_regex (R"( \s*(?:\(\s*([^)]*?)\s*\))?)" );
550+ std::smatch match;
551+ const auto type_params = type_str.substr (std::string_view (" geometry" ).size ());
552+ if (std::regex_match (type_params, match, geometry_regex)) {
553+ if (match[1 ].matched ) {
554+ auto crs = match[1 ].str ();
555+ if (crs.empty ()) {
556+ return JsonParseError (" Invalid geometry type: {}" , type_str);
557+ }
558+ return std::make_unique<GeometryType>(std::move (crs));
559+ }
560+ return std::make_unique<GeometryType>();
561+ }
562+ return JsonParseError (" Invalid geometry type: {}" , type_str);
563+ } else if (lower_type_str.starts_with (" geography" )) {
564+ static const std::regex geography_regex (
565+ R"( \s*(?:\(\s*([^,]*?)\s*(?:,\s*(\w*)\s*)?\))?)" );
566+ std::smatch match;
567+ const auto type_params = type_str.substr (std::string_view (" geography" ).size ());
568+ if (std::regex_match (type_params, match, geography_regex)) {
569+ auto crs = match[1 ].str ();
570+ if (match[1 ].matched && crs.empty ()) {
571+ return JsonParseError (" Invalid geography type: {}" , type_str);
572+ }
573+ if (match[2 ].matched ) {
574+ ICEBERG_ASSIGN_OR_RAISE (auto algorithm,
575+ EdgeAlgorithmFromString (match[2 ].str ()));
576+ return std::make_unique<GeographyType>(std::move (crs), algorithm);
577+ }
578+ if (match[1 ].matched ) {
579+ return std::make_unique<GeographyType>(std::move (crs));
580+ }
581+ return std::make_unique<GeographyType>();
582+ }
583+ return JsonParseError (" Invalid geography type: {}" , type_str);
539584 } else {
540- return JsonParseError (" Unknown primitive type: {}" , type_str);
585+ return JsonParseError (" Cannot parse type string : {}" , type_str);
541586 }
542587 }
543588
0 commit comments