From 9af3ff3326c800da5d4daa27bce222b9b6779124 Mon Sep 17 00:00:00 2001 From: glywk Date: Tue, 3 Sep 2024 13:03:08 +0200 Subject: [PATCH] [AVRO-4044][C++] Add time-nanos logical type --- lang/c++/impl/Compiler.cc | 2 ++ lang/c++/impl/LogicalType.cc | 3 +++ lang/c++/impl/Node.cc | 6 ++++++ lang/c++/include/avro/LogicalType.hh | 1 + lang/c++/test/SchemaTests.cc | 14 ++++++++++++++ 5 files changed, 26 insertions(+) diff --git a/lang/c++/impl/Compiler.cc b/lang/c++/impl/Compiler.cc index f3c2397da24..3052c0c3b2e 100644 --- a/lang/c++/impl/Compiler.cc +++ b/lang/c++/impl/Compiler.cc @@ -365,6 +365,8 @@ static LogicalType makeLogicalType(const Entity &e, const Object &m) { t = LogicalType::TIME_MILLIS; else if (typeField == "time-micros") t = LogicalType::TIME_MICROS; + else if (typeField == "time-nanos") + t = LogicalType::TIME_NANOS; else if (typeField == "timestamp-millis") t = LogicalType::TIMESTAMP_MILLIS; else if (typeField == "timestamp-micros") diff --git a/lang/c++/impl/LogicalType.cc b/lang/c++/impl/LogicalType.cc index ed6a12f0892..147674ccaf8 100644 --- a/lang/c++/impl/LogicalType.cc +++ b/lang/c++/impl/LogicalType.cc @@ -65,6 +65,9 @@ void LogicalType::printJson(std::ostream &os) const { case TIME_MICROS: os << R"("logicalType": "time-micros")"; break; + case TIME_NANOS: + os << R"("logicalType": "time-nanos")"; + break; case TIMESTAMP_MILLIS: os << R"("logicalType": "timestamp-millis")"; break; diff --git a/lang/c++/impl/Node.cc b/lang/c++/impl/Node.cc index bde556bf314..1e19ed7e33b 100644 --- a/lang/c++/impl/Node.cc +++ b/lang/c++/impl/Node.cc @@ -177,6 +177,12 @@ void Node::setLogicalType(LogicalType logicalType) { "LONG type"); } break; + case LogicalType::TIME_NANOS: + if (type_ != AVRO_LONG) { + throw Exception("TIME-NANOS logical type can only annotate " + "LONG type"); + } + break; case LogicalType::TIMESTAMP_MILLIS: if (type_ != AVRO_LONG) { throw Exception("TIMESTAMP-MILLIS logical type can only annotate " diff --git a/lang/c++/include/avro/LogicalType.hh b/lang/c++/include/avro/LogicalType.hh index b2a7d0294ff..9da349f55de 100644 --- a/lang/c++/include/avro/LogicalType.hh +++ b/lang/c++/include/avro/LogicalType.hh @@ -33,6 +33,7 @@ public: DATE, TIME_MILLIS, TIME_MICROS, + TIME_NANOS, TIMESTAMP_MILLIS, TIMESTAMP_MICROS, TIMESTAMP_NANOS, diff --git a/lang/c++/test/SchemaTests.cc b/lang/c++/test/SchemaTests.cc index 029be79d57e..225379065ad 100644 --- a/lang/c++/test/SchemaTests.cc +++ b/lang/c++/test/SchemaTests.cc @@ -215,6 +215,7 @@ const char *roundTripSchemas[] = { R"({"type":"int","logicalType":"date"})", R"({"type":"int","logicalType":"time-millis"})", R"({"type":"long","logicalType":"time-micros"})", + R"({"type":"long","logicalType":"time-nanos"})", R"({"type":"long","logicalType":"timestamp-millis"})", R"({"type":"long","logicalType":"timestamp-micros"})", R"({"type":"long","logicalType":"timestamp-nanos"})", @@ -244,6 +245,7 @@ const char *malformedLogicalTypes[] = { R"({"type":"string","logicalType":"date"})", R"({"type":"string","logicalType":"time-millis"})", R"({"type":"string","logicalType":"time-micros"})", + R"({"type":"string","logicalType":"time-nanos"})", R"({"type":"string","logicalType":"timestamp-millis"})", R"({"type":"string","logicalType":"timestamp-micros"})", R"({"type":"string","logicalType":"timestamp-nanos"})", @@ -358,6 +360,9 @@ static void testLogicalTypes() { const char *timeMicrosType = "{\n\ \"type\": \"long\", \"logicalType\": \"time-micros\"\n\ }"; + const char *timeNanosType = "{\n\ + \"type\": \"long\", \"logicalType\": \"time-nanos\"\n\ + }"; const char *timestampMillisType = "{\n\ \"type\": \"long\", \"logicalType\": \"timestamp-millis\"\n\ }"; @@ -438,6 +443,15 @@ static void testLogicalTypes() { GenericDatum datum(schema); BOOST_CHECK(datum.logicalType().type() == LogicalType::TIME_MICROS); } + { + BOOST_TEST_CHECKPOINT(timeNanosType); + ValidSchema schema = compileJsonSchemaFromString(timeNanosType); + BOOST_CHECK(schema.root()->type() == AVRO_LONG); + LogicalType logicalType = schema.root()->logicalType(); + BOOST_CHECK(logicalType.type() == LogicalType::TIME_NANOS); + GenericDatum datum(schema); + BOOST_CHECK(datum.logicalType().type() == LogicalType::TIME_NANOS); + } { BOOST_TEST_CHECKPOINT(timestampMillisType); ValidSchema schema = compileJsonSchemaFromString(timestampMillisType);