Skip to content

Commit

Permalink
AVRO-4038: [C++] Add local-timestamp-nanos and timestamp-nanos
Browse files Browse the repository at this point in the history
  • Loading branch information
glywk committed Aug 19, 2024
1 parent 2205c20 commit f229a5c
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lang/c++/impl/Compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -369,10 +369,14 @@ static LogicalType makeLogicalType(const Entity &e, const Object &m) {
t = LogicalType::TIMESTAMP_MILLIS;
else if (typeField == "timestamp-micros")
t = LogicalType::TIMESTAMP_MICROS;
else if (typeField == "timestamp-nanos")
t = LogicalType::TIMESTAMP_NANOS;
else if (typeField == "local-timestamp-millis")
t = LogicalType::LOCAL_TIMESTAMP_MILLIS;
else if (typeField == "local-timestamp-micros")
t = LogicalType::LOCAL_TIMESTAMP_MICROS;
else if (typeField == "local-timestamp-nanos")
t = LogicalType::LOCAL_TIMESTAMP_NANOS;
else if (typeField == "duration")
t = LogicalType::DURATION;
else if (typeField == "uuid")
Expand Down
6 changes: 6 additions & 0 deletions lang/c++/impl/LogicalType.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,18 @@ void LogicalType::printJson(std::ostream &os) const {
case TIMESTAMP_MICROS:
os << R"("logicalType": "timestamp-micros")";
break;
case TIMESTAMP_NANOS:
os << R"("logicalType": "timestamp-nanos")";
break;
case LOCAL_TIMESTAMP_MILLIS:
os << R"("logicalType": "local-timestamp-millis")";
break;
case LOCAL_TIMESTAMP_MICROS:
os << R"("logicalType": "local-timestamp-micros")";
break;
case LOCAL_TIMESTAMP_NANOS:
os << R"("logicalType": "local-timestamp-nanos")";
break;
case DURATION:
os << R"("logicalType": "duration")";
break;
Expand Down
12 changes: 12 additions & 0 deletions lang/c++/impl/Node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ void Node::setLogicalType(LogicalType logicalType) {
"LONG type");
}
break;
case LogicalType::TIMESTAMP_NANOS:
if (type_ != AVRO_LONG) {
throw Exception("TIMESTAMP-NANOS logical type can only annotate "
"LONG type");
}
break;
case LogicalType::LOCAL_TIMESTAMP_MILLIS:
if (type_ != AVRO_LONG) {
throw Exception("LOCAL-TIMESTAMP-MILLIS logical type can only annotate "
Expand All @@ -201,6 +207,12 @@ void Node::setLogicalType(LogicalType logicalType) {
"LONG type");
}
break;
case LogicalType::LOCAL_TIMESTAMP_NANOS:
if (type_ != AVRO_LONG) {
throw Exception("LOCAL-TIMESTAMP-NANOS logical type can only annotate "
"LONG type");
}
break;
case LogicalType::DURATION:
if (type_ != AVRO_FIXED || fixedSize() != 12) {
throw Exception("DURATION logical type can only annotate "
Expand Down
2 changes: 2 additions & 0 deletions lang/c++/include/avro/LogicalType.hh
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ public:
TIME_MICROS,
TIMESTAMP_MILLIS,
TIMESTAMP_MICROS,
TIMESTAMP_NANOS,
LOCAL_TIMESTAMP_MILLIS,
LOCAL_TIMESTAMP_MICROS,
LOCAL_TIMESTAMP_NANOS,
DURATION,
UUID
};
Expand Down
28 changes: 28 additions & 0 deletions lang/c++/test/SchemaTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,10 @@ const char *roundTripSchemas[] = {
R"({"type":"long","logicalType":"time-micros"})",
R"({"type":"long","logicalType":"timestamp-millis"})",
R"({"type":"long","logicalType":"timestamp-micros"})",
R"({"type":"long","logicalType":"timestamp-nanos"})",
R"({"type":"long","logicalType":"local-timestamp-millis"})",
R"({"type":"long","logicalType":"local-timestamp-micros"})",
R"({"type":"long","logicalType":"local-timestamp-nanos"})",
R"({"type":"fixed","name":"test","size":12,"logicalType":"duration"})",
R"({"type":"string","logicalType":"uuid"})",

Expand All @@ -244,8 +246,10 @@ const char *malformedLogicalTypes[] = {
R"({"type":"string","logicalType":"time-micros"})",
R"({"type":"string","logicalType":"timestamp-millis"})",
R"({"type":"string","logicalType":"timestamp-micros"})",
R"({"type":"string","logicalType":"timestamp-nanos"})",
R"({"type":"string","logicalType":"local-timestamp-millis"})",
R"({"type":"string","logicalType":"local-timestamp-micros"})",
R"({"type":"string","logicalType":"local-timestamp-nanos"})",
R"({"type":"string","logicalType":"duration"})",
R"({"type":"long","logicalType":"uuid"})",
// Missing the required field 'precision'.
Expand Down Expand Up @@ -360,12 +364,18 @@ static void testLogicalTypes() {
const char *timestampMicrosType = "{\n\
\"type\": \"long\", \"logicalType\": \"timestamp-micros\"\n\
}";
const char *timestampNanosType = "{\n\
\"type\": \"long\", \"logicalType\": \"timestamp-nanos\"\n\
}";
const char *localTimestampMillisType = "{\n\
\"type\": \"long\", \"logicalType\": \"local-timestamp-millis\"\n\
}";
const char *localTimestampMicrosType = "{\n\
\"type\": \"long\", \"logicalType\": \"local-timestamp-micros\"\n\
}";
const char *localTimestampNanosType = "{\n\
\"type\": \"long\", \"logicalType\": \"local-timestamp-nanos\"\n\
}";
const char *durationType = "{\n\
\"type\": \"fixed\",\n\
\"size\": 12,\n\
Expand Down Expand Up @@ -446,6 +456,15 @@ static void testLogicalTypes() {
GenericDatum datum(schema);
BOOST_CHECK(datum.logicalType().type() == LogicalType::TIMESTAMP_MICROS);
}
{
BOOST_TEST_CHECKPOINT(timestampNanosType);
ValidSchema schema = compileJsonSchemaFromString(timestampNanosType);
BOOST_CHECK(schema.root()->type() == AVRO_LONG);
LogicalType logicalType = schema.root()->logicalType();
BOOST_CHECK(logicalType.type() == LogicalType::TIMESTAMP_NANOS);
GenericDatum datum(schema);
BOOST_CHECK(datum.logicalType().type() == LogicalType::TIMESTAMP_NANOS);
}
{
BOOST_TEST_CHECKPOINT(localTimestampMillisType);
ValidSchema schema = compileJsonSchemaFromString(localTimestampMillisType);
Expand All @@ -464,6 +483,15 @@ static void testLogicalTypes() {
GenericDatum datum(schema);
BOOST_CHECK(datum.logicalType().type() == LogicalType::LOCAL_TIMESTAMP_MICROS);
}
{
BOOST_TEST_CHECKPOINT(localTimestampNanosType);
ValidSchema schema = compileJsonSchemaFromString(localTimestampNanosType);
BOOST_CHECK(schema.root()->type() == AVRO_LONG);
LogicalType logicalType = schema.root()->logicalType();
BOOST_CHECK(logicalType.type() == LogicalType::LOCAL_TIMESTAMP_NANOS);
GenericDatum datum(schema);
BOOST_CHECK(datum.logicalType().type() == LogicalType::LOCAL_TIMESTAMP_NANOS);
}
{
BOOST_TEST_CHECKPOINT(durationType);
ValidSchema schema = compileJsonSchemaFromString(durationType);
Expand Down

0 comments on commit f229a5c

Please sign in to comment.