This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/main by this push:
     new 4d88c035 feat(c/driver/postgresql): Duration support (#907)
4d88c035 is described below

commit 4d88c03545c16da3a2ae2ed93997d3c540471c56
Author: William Ayd <[email protected]>
AuthorDate: Thu Sep 7 11:41:55 2023 -0400

    feat(c/driver/postgresql): Duration support (#907)
---
 c/driver/postgresql/postgresql_test.cc       | 88 ++++++++++++++++++++++------
 c/driver/postgresql/statement.cc             | 17 +++++-
 c/driver/snowflake/snowflake_test.cc         | 44 ++++++++------
 c/driver/sqlite/sqlite_test.cc               | 61 +++++++++++--------
 c/driver_manager/adbc_driver_manager_test.cc |  4 +-
 c/validation/adbc_validation.cc              | 73 ++++++++++++++++-------
 c/validation/adbc_validation.h               | 12 ++--
 7 files changed, 212 insertions(+), 87 deletions(-)

diff --git a/c/driver/postgresql/postgresql_test.cc 
b/c/driver/postgresql/postgresql_test.cc
index e49e8e20..e7cd4b1f 100644
--- a/c/driver/postgresql/postgresql_test.cc
+++ b/c/driver/postgresql/postgresql_test.cc
@@ -92,6 +92,8 @@ class PostgresQuirks : public adbc_validation::DriverQuirks {
     switch (ingest_type) {
       case NANOARROW_TYPE_INT8:
         return NANOARROW_TYPE_INT16;
+      case NANOARROW_TYPE_DURATION:
+        return NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO;
       default:
         return ingest_type;
     }
@@ -796,26 +798,78 @@ class PostgresStatementTest : public ::testing::Test,
   }
 
  protected:
-  void ValidateIngestedTimestampData(struct ArrowArrayView* values,
-                                     enum ArrowTimeUnit unit,
-                                     const char* timezone) override {
-    std::vector<std::optional<int64_t>> expected;
-    switch (unit) {
-      case (NANOARROW_TIME_UNIT_SECOND):
-        expected.insert(expected.end(), {std::nullopt, -42000000, 0, 
42000000});
-        break;
-      case (NANOARROW_TIME_UNIT_MILLI):
-        expected.insert(expected.end(), {std::nullopt, -42000, 0, 42000});
-        break;
-      case (NANOARROW_TIME_UNIT_MICRO):
-        expected.insert(expected.end(), {std::nullopt, -42, 0, 42});
+  void ValidateIngestedTemporalData(struct ArrowArrayView* values, ArrowType 
type,
+                                    enum ArrowTimeUnit unit,
+                                    const char* timezone) override {
+    switch (type) {
+      case NANOARROW_TYPE_TIMESTAMP: {
+        std::vector<std::optional<int64_t>> expected;
+        switch (unit) {
+          case (NANOARROW_TIME_UNIT_SECOND):
+            expected.insert(expected.end(), {std::nullopt, -42000000, 0, 
42000000});
+            break;
+          case (NANOARROW_TIME_UNIT_MILLI):
+            expected.insert(expected.end(), {std::nullopt, -42000, 0, 42000});
+            break;
+          case (NANOARROW_TIME_UNIT_MICRO):
+            expected.insert(expected.end(), {std::nullopt, -42, 0, 42});
+            break;
+          case (NANOARROW_TIME_UNIT_NANO):
+            expected.insert(expected.end(), {std::nullopt, 0, 0, 0});
+            break;
+        }
+        ASSERT_NO_FATAL_FAILURE(
+            adbc_validation::CompareArray<std::int64_t>(values, expected));
         break;
-      case (NANOARROW_TIME_UNIT_NANO):
-        expected.insert(expected.end(), {std::nullopt, 0, 0, 0});
+      }
+      case NANOARROW_TYPE_DURATION: {
+        struct ArrowInterval neg_interval;
+        struct ArrowInterval zero_interval;
+        struct ArrowInterval pos_interval;
+
+        ArrowIntervalInit(&neg_interval, type);
+        ArrowIntervalInit(&zero_interval, type);
+        ArrowIntervalInit(&pos_interval, type);
+
+        neg_interval.months = 0;
+        neg_interval.days = 0;
+        zero_interval.months = 0;
+        zero_interval.days = 0;
+        pos_interval.months = 0;
+        pos_interval.days = 0;
+
+        switch (unit) {
+          case (NANOARROW_TIME_UNIT_SECOND):
+            neg_interval.ns = -42000000000;
+            zero_interval.ns = 0;
+            pos_interval.ns = 42000000000;
+            break;
+          case (NANOARROW_TIME_UNIT_MILLI):
+            neg_interval.ns = -42000000;
+            zero_interval.ns = 0;
+            pos_interval.ns = 42000000;
+            break;
+          case (NANOARROW_TIME_UNIT_MICRO):
+            neg_interval.ns = -42000;
+            zero_interval.ns = 0;
+            pos_interval.ns = 42000;
+            break;
+          case (NANOARROW_TIME_UNIT_NANO):
+            // lower than us precision is lost
+            neg_interval.ns = 0;
+            zero_interval.ns = 0;
+            pos_interval.ns = 0;
+            break;
+        }
+        const std::vector<std::optional<ArrowInterval*>> expected = {
+            std::nullopt, &neg_interval, &zero_interval, &pos_interval};
+        ASSERT_NO_FATAL_FAILURE(
+            adbc_validation::CompareArray<ArrowInterval*>(values, expected));
         break;
+      }
+      default:
+        FAIL() << "ValidateIngestedTemporalData not implemented for type " << 
type;
     }
-    ASSERT_NO_FATAL_FAILURE(
-        adbc_validation::CompareArray<std::int64_t>(values, expected));
   }
 
   PostgresQuirks quirks_;
diff --git a/c/driver/postgresql/statement.cc b/c/driver/postgresql/statement.cc
index c1aaa1f6..b933a643 100644
--- a/c/driver/postgresql/statement.cc
+++ b/c/driver/postgresql/statement.cc
@@ -230,6 +230,7 @@ struct BindStream {
           type_id = PostgresTypeId::kTimestamp;
           param_lengths[i] = 8;
           break;
+        case ArrowType::NANOARROW_TYPE_DURATION:
         case ArrowType::NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO:
           type_id = PostgresTypeId::kInterval;
           param_lengths[i] = 16;
@@ -417,6 +418,7 @@ struct BindStream {
               std::memcpy(param_values[col], &value, sizeof(int32_t));
               break;
             }
+            case ArrowType::NANOARROW_TYPE_DURATION:
             case ArrowType::NANOARROW_TYPE_TIMESTAMP: {
               int64_t val = 
array_view->children[col]->buffer_views[1].data.as_int64[row];
 
@@ -448,8 +450,18 @@ struct BindStream {
                 return ADBC_STATUS_INVALID_ARGUMENT;
               }
 
-              const uint64_t value = ToNetworkInt64(val - 
kPostgresTimestampEpoch);
-              std::memcpy(param_values[col], &value, sizeof(int64_t));
+              if (bind_schema_fields[col].type == 
ArrowType::NANOARROW_TYPE_TIMESTAMP) {
+                const uint64_t value = ToNetworkInt64(val - 
kPostgresTimestampEpoch);
+                std::memcpy(param_values[col], &value, sizeof(int64_t));
+              } else if (bind_schema_fields[col].type ==
+                         ArrowType::NANOARROW_TYPE_DURATION) {
+                // postgres stores an interval as a 64 bit offset in 
microsecond
+                // resolution alongside a 32 bit day and 32 bit month
+                // for now we just send 0 for the day / month values
+                const uint64_t value = ToNetworkInt64(val);
+                std::memcpy(param_values[col], &value, sizeof(int64_t));
+                std::memset(param_values[col] + sizeof(int64_t), 0, 
sizeof(int64_t));
+              }
               break;
             }
             case ArrowType::NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO: {
@@ -878,6 +890,7 @@ AdbcStatusCode PostgresStatement::CreateBulkTable(
           create += " TIMESTAMP";
         }
         break;
+      case ArrowType::NANOARROW_TYPE_DURATION:
       case ArrowType::NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO:
         create += " INTERVAL";
         break;
diff --git a/c/driver/snowflake/snowflake_test.cc 
b/c/driver/snowflake/snowflake_test.cc
index 8c3cd72c..7b5861cb 100644
--- a/c/driver/snowflake/snowflake_test.cc
+++ b/c/driver/snowflake/snowflake_test.cc
@@ -184,28 +184,36 @@ class SnowflakeStatementTest : public ::testing::Test,
   }
 
   void TestSqlIngestInterval() { GTEST_SKIP(); }
+  void TestSqlIngestDuration() { GTEST_SKIP(); }
 
  protected:
-  void ValidateIngestedTimestampData(struct ArrowArrayView* values,
-                                     enum ArrowTimeUnit unit,
-                                     const char* timezone) override {
-    std::vector<std::optional<int64_t>> expected;
-    switch (unit) {
-      case NANOARROW_TIME_UNIT_SECOND:
-        expected = {std::nullopt, -42, 0, 42};
-        break;
-      case NANOARROW_TIME_UNIT_MILLI:
-        expected = {std::nullopt, -42000, 0, 42000};
-        break;
-      case NANOARROW_TIME_UNIT_MICRO:
-        expected = {std::nullopt, -42, 0, 42};
-        break;
-      case NANOARROW_TIME_UNIT_NANO:
-        expected = {std::nullopt, -42, 0, 42};
+  void ValidateIngestedTemporalData(struct ArrowArrayView* values, ArrowType 
type,
+                                    enum ArrowTimeUnit unit,
+                                    const char* timezone) override {
+    switch (type) {
+      case NANOARROW_TYPE_TIMESTAMP: {
+        std::vector<std::optional<int64_t>> expected;
+        switch (unit) {
+          case NANOARROW_TIME_UNIT_SECOND:
+            expected = {std::nullopt, -42, 0, 42};
+            break;
+          case NANOARROW_TIME_UNIT_MILLI:
+            expected = {std::nullopt, -42000, 0, 42000};
+            break;
+          case NANOARROW_TIME_UNIT_MICRO:
+            expected = {std::nullopt, -42, 0, 42};
+            break;
+          case NANOARROW_TIME_UNIT_NANO:
+            expected = {std::nullopt, -42, 0, 42};
+            break;
+        }
+        ASSERT_NO_FATAL_FAILURE(
+            adbc_validation::CompareArray<std::int64_t>(values, expected));
         break;
+      }
+      default:
+        FAIL() << "ValidateIngestedTemporalData not implemented for type " << 
type;
     }
-    ASSERT_NO_FATAL_FAILURE(
-        adbc_validation::CompareArray<std::int64_t>(values, expected));
   }
 
   SnowflakeQuirks quirks_;
diff --git a/c/driver/sqlite/sqlite_test.cc b/c/driver/sqlite/sqlite_test.cc
index e5234b9a..2d68cc34 100644
--- a/c/driver/sqlite/sqlite_test.cc
+++ b/c/driver/sqlite/sqlite_test.cc
@@ -216,37 +216,50 @@ class SqliteStatementTest : public ::testing::Test,
   }
 
   void TestSqlIngestBinary() { GTEST_SKIP() << "Cannot ingest BINARY (not 
implemented)"; }
+  void TestSqlIngestDuration() {
+    GTEST_SKIP() << "Cannot ingest DURATION (not implemented)";
+  }
   void TestSqlIngestInterval() {
     GTEST_SKIP() << "Cannot ingest Interval (not implemented)";
   }
 
  protected:
-  void ValidateIngestedTimestampData(struct ArrowArrayView* values,
-                                     enum ArrowTimeUnit unit,
-                                     const char* timezone) override {
-    std::vector<std::optional<std::string>> expected;
-    switch (unit) {
-      case (NANOARROW_TIME_UNIT_SECOND):
-        expected.insert(expected.end(), {std::nullopt, "1969-12-31T23:59:18",
-                                         "1970-01-01T00:00:00", 
"1970-01-01T00:00:42"});
-        break;
-      case (NANOARROW_TIME_UNIT_MILLI):
-        expected.insert(expected.end(),
-                        {std::nullopt, "1969-12-31T23:59:59.958",
-                         "1970-01-01T00:00:00.000", 
"1970-01-01T00:00:00.042"});
-        break;
-      case (NANOARROW_TIME_UNIT_MICRO):
-        expected.insert(expected.end(),
-                        {std::nullopt, "1969-12-31T23:59:59.999958",
-                         "1970-01-01T00:00:00.000000", 
"1970-01-01T00:00:00.000042"});
-        break;
-      case (NANOARROW_TIME_UNIT_NANO):
-        expected.insert(expected.end(), {std::nullopt, 
"1969-12-31T23:59:59.999999958",
-                                         "1970-01-01T00:00:00.000000000",
-                                         "1970-01-01T00:00:00.000000042"});
+  void ValidateIngestedTemporalData(struct ArrowArrayView* values, ArrowType 
type,
+                                    enum ArrowTimeUnit unit,
+                                    const char* timezone) override {
+    switch (type) {
+      case NANOARROW_TYPE_TIMESTAMP: {
+        std::vector<std::optional<std::string>> expected;
+        switch (unit) {
+          case (NANOARROW_TIME_UNIT_SECOND):
+            expected.insert(expected.end(),
+                            {std::nullopt, "1969-12-31T23:59:18", 
"1970-01-01T00:00:00",
+                             "1970-01-01T00:00:42"});
+            break;
+          case (NANOARROW_TIME_UNIT_MILLI):
+            expected.insert(expected.end(),
+                            {std::nullopt, "1969-12-31T23:59:59.958",
+                             "1970-01-01T00:00:00.000", 
"1970-01-01T00:00:00.042"});
+            break;
+          case (NANOARROW_TIME_UNIT_MICRO):
+            expected.insert(expected.end(),
+                            {std::nullopt, "1969-12-31T23:59:59.999958",
+                             "1970-01-01T00:00:00.000000", 
"1970-01-01T00:00:00.000042"});
+            break;
+          case (NANOARROW_TIME_UNIT_NANO):
+            expected.insert(
+                expected.end(),
+                {std::nullopt, "1969-12-31T23:59:59.999999958",
+                 "1970-01-01T00:00:00.000000000", 
"1970-01-01T00:00:00.000000042"});
+            break;
+        }
+        ASSERT_NO_FATAL_FAILURE(
+            adbc_validation::CompareArray<std::string>(values, expected));
         break;
+      }
+      default:
+        FAIL() << "ValidateIngestedTemporalData not implemented for type " << 
type;
     }
-    ASSERT_NO_FATAL_FAILURE(adbc_validation::CompareArray<std::string>(values, 
expected));
   }
 
   SqliteQuirks quirks_;
diff --git a/c/driver_manager/adbc_driver_manager_test.cc 
b/c/driver_manager/adbc_driver_manager_test.cc
index 58d056c4..262171f1 100644
--- a/c/driver_manager/adbc_driver_manager_test.cc
+++ b/c/driver_manager/adbc_driver_manager_test.cc
@@ -270,6 +270,9 @@ class SqliteStatementTest : public ::testing::Test,
   void TestSqlIngestTimestampTz() {
     GTEST_SKIP() << "Cannot ingest TIMESTAMP WITH TIMEZONE (not implemented)";
   }
+  void TestSqlIngestDuration() {
+    GTEST_SKIP() << "Cannot ingest DURATION (not implemented)";
+  }
   void TestSqlIngestInterval() {
     GTEST_SKIP() << "Cannot ingest Interval (not implemented)";
   }
@@ -315,5 +318,4 @@ TEST(AdbcDriverManagerInternal, 
AdbcDriverManagerDefaultEntrypoint) {
     EXPECT_EQ("AdbcProprietaryEngineInit", 
::AdbcDriverManagerDefaultEntrypoint(driver));
   }
 }
-
 }  // namespace adbc
diff --git a/c/validation/adbc_validation.cc b/c/validation/adbc_validation.cc
index c0dde715..0833aa2d 100644
--- a/c/validation/adbc_validation.cc
+++ b/c/validation/adbc_validation.cc
@@ -1261,8 +1261,8 @@ void StatementTest::TestSqlIngestDate32() {
   
ASSERT_NO_FATAL_FAILURE(TestSqlIngestNumericType<int32_t>(NANOARROW_TYPE_DATE32));
 }
 
-template <enum ArrowTimeUnit TU>
-void StatementTest::TestSqlIngestTimestampType(const char* timezone) {
+template <ArrowType type, enum ArrowTimeUnit TU>
+void StatementTest::TestSqlIngestTemporalType(const char* timezone) {
   if (!quirks()->supports_bulk_ingest(ADBC_INGEST_OPTION_MODE_CREATE)) {
     GTEST_SKIP();
   }
@@ -1274,7 +1274,6 @@ void StatementTest::TestSqlIngestTimestampType(const 
char* timezone) {
   Handle<struct ArrowArray> array;
   struct ArrowError na_error;
   const std::vector<std::optional<int64_t>> values = {std::nullopt, -42, 0, 
42};
-  const ArrowType type = NANOARROW_TYPE_TIMESTAMP;
 
   // much of this code is shared with TestSqlIngestType with minor
   // changes to allow for various time units to be tested
@@ -1321,7 +1320,7 @@ void StatementTest::TestSqlIngestTimestampType(const 
char* timezone) {
     ASSERT_EQ(values.size(), reader.array->length);
     ASSERT_EQ(1, reader.array->n_children);
 
-    ValidateIngestedTimestampData(reader.array_view->children[0], TU, 
timezone);
+    ValidateIngestedTemporalData(reader.array_view->children[0], type, TU, 
timezone);
 
     ASSERT_NO_FATAL_FAILURE(reader.Next());
     ASSERT_EQ(nullptr, reader.array->release);
@@ -1330,34 +1329,68 @@ void StatementTest::TestSqlIngestTimestampType(const 
char* timezone) {
   ASSERT_THAT(AdbcStatementRelease(&statement, &error), IsOkStatus(&error));
 }
 
-void StatementTest::ValidateIngestedTimestampData(struct ArrowArrayView* 
values,
-                                                  enum ArrowTimeUnit unit,
-                                                  const char* timezone) {
-  FAIL() << "ValidateIngestedTimestampData is not implemented in the base 
class";
+void StatementTest::ValidateIngestedTemporalData(struct ArrowArrayView* values,
+                                                 ArrowType type, enum 
ArrowTimeUnit unit,
+                                                 const char* timezone) {
+  FAIL() << "ValidateIngestedTemporalData is not implemented in the base 
class";
+}
+
+void StatementTest::TestSqlIngestDuration() {
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_DURATION, 
NANOARROW_TIME_UNIT_SECOND>(
+          nullptr)));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_DURATION, 
NANOARROW_TIME_UNIT_MILLI>(
+          nullptr)));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_DURATION, 
NANOARROW_TIME_UNIT_MICRO>(
+          nullptr)));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_DURATION, 
NANOARROW_TIME_UNIT_NANO>(
+          nullptr)));
 }
 
 void StatementTest::TestSqlIngestTimestamp() {
   ASSERT_NO_FATAL_FAILURE(
-      TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_SECOND>(nullptr));
-  
ASSERT_NO_FATAL_FAILURE(TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_MILLI>(nullptr));
-  
ASSERT_NO_FATAL_FAILURE(TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_MICRO>(nullptr));
-  
ASSERT_NO_FATAL_FAILURE(TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_NANO>(nullptr));
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_SECOND>(
+          nullptr)));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_MILLI>(
+          nullptr)));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_MICRO>(
+          nullptr)));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_NANO>(
+          nullptr)));
 }
 
 void StatementTest::TestSqlIngestTimestampTz() {
-  
ASSERT_NO_FATAL_FAILURE(TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_SECOND>("UTC"));
-  
ASSERT_NO_FATAL_FAILURE(TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_MILLI>("UTC"));
-  
ASSERT_NO_FATAL_FAILURE(TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_MICRO>("UTC"));
-  
ASSERT_NO_FATAL_FAILURE(TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_NANO>("UTC"));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_SECOND>(
+          "UTC")));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_MILLI>(
+          "UTC")));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_MICRO>(
+          "UTC")));
+  ASSERT_NO_FATAL_FAILURE(
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_NANO>(
+          "UTC")));
 
   ASSERT_NO_FATAL_FAILURE(
-      
TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_SECOND>("America/Los_Angeles"));
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_SECOND>(
+          "America/Los_Angeles")));
   ASSERT_NO_FATAL_FAILURE(
-      
TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_MILLI>("America/Los_Angeles"));
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_MILLI>(
+          "America/Los_Angeles")));
   ASSERT_NO_FATAL_FAILURE(
-      
TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_MICRO>("America/Los_Angeles"));
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_MICRO>(
+          "America/Los_Angeles")));
   ASSERT_NO_FATAL_FAILURE(
-      
TestSqlIngestTimestampType<NANOARROW_TIME_UNIT_NANO>("America/Los_Angeles"));
+      (TestSqlIngestTemporalType<NANOARROW_TYPE_TIMESTAMP, 
NANOARROW_TIME_UNIT_NANO>(
+          "America/Los_Angeles")));
 }
 
 void StatementTest::TestSqlIngestInterval() {
diff --git a/c/validation/adbc_validation.h b/c/validation/adbc_validation.h
index 74fba89e..dda52eb2 100644
--- a/c/validation/adbc_validation.h
+++ b/c/validation/adbc_validation.h
@@ -274,6 +274,7 @@ class StatementTest {
   void TestSqlIngestBinary();
 
   // Temporal
+  void TestSqlIngestDuration();
   void TestSqlIngestDate32();
   void TestSqlIngestTimestamp();
   void TestSqlIngestTimestampTz();
@@ -331,12 +332,12 @@ class StatementTest {
   template <typename CType>
   void TestSqlIngestNumericType(ArrowType type);
 
-  template <enum ArrowTimeUnit TU>
-  void TestSqlIngestTimestampType(const char* timezone);
+  template <ArrowType type, enum ArrowTimeUnit TU>
+  void TestSqlIngestTemporalType(const char* timezone);
 
-  virtual void ValidateIngestedTimestampData(struct ArrowArrayView* values,
-                                             enum ArrowTimeUnit unit,
-                                             const char* timezone);
+  virtual void ValidateIngestedTemporalData(struct ArrowArrayView* values, 
ArrowType type,
+                                            enum ArrowTimeUnit unit,
+                                            const char* timezone);
 };
 
 #define ADBCV_TEST_STATEMENT(FIXTURE)                                          
         \
@@ -356,6 +357,7 @@ class StatementTest {
   TEST_F(FIXTURE, SqlIngestFloat64) { TestSqlIngestFloat64(); }                
         \
   TEST_F(FIXTURE, SqlIngestString) { TestSqlIngestString(); }                  
         \
   TEST_F(FIXTURE, SqlIngestBinary) { TestSqlIngestBinary(); }                  
         \
+  TEST_F(FIXTURE, SqlIngestDuration) { TestSqlIngestDuration(); }              
         \
   TEST_F(FIXTURE, SqlIngestDate32) { TestSqlIngestDate32(); }                  
         \
   TEST_F(FIXTURE, SqlIngestTimestamp) { TestSqlIngestTimestamp(); }            
         \
   TEST_F(FIXTURE, SqlIngestTimestampTz) { TestSqlIngestTimestampTz(); }        
         \

Reply via email to