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 257420a69 feat(c/driver/postgresql): add money type and test intervals 
(#1741)
257420a69 is described below

commit 257420a69f9215de12c8fcb8d90c95a10e510380
Author: David Li <[email protected]>
AuthorDate: Mon Apr 22 14:04:39 2024 +0900

    feat(c/driver/postgresql): add money type and test intervals (#1741)
    
    Doesn't add anything meaningfully new, just adds tests for types.
    
    Fixes #933.
---
 c/driver/postgresql/copy/reader.h      |   1 +
 c/driver/postgresql/postgres_type.h    |   4 +
 c/driver/postgresql/postgresql_test.cc | 192 ++++++++++++++++++++++++++++++---
 3 files changed, 181 insertions(+), 16 deletions(-)

diff --git a/c/driver/postgresql/copy/reader.h 
b/c/driver/postgresql/copy/reader.h
index c3c9acb32..9486df93c 100644
--- a/c/driver/postgresql/copy/reader.h
+++ b/c/driver/postgresql/copy/reader.h
@@ -741,6 +741,7 @@ static inline ArrowErrorCode MakeCopyFieldReader(
     case NANOARROW_TYPE_INT64:
       switch (pg_type.type_id()) {
         case PostgresTypeId::kInt8:
+        case PostgresTypeId::kCash:
           *out = 
std::make_unique<PostgresCopyNetworkEndianFieldReader<int64_t>>();
           return NANOARROW_OK;
         default:
diff --git a/c/driver/postgresql/postgres_type.h 
b/c/driver/postgresql/postgres_type.h
index dc5d38784..c7cc55745 100644
--- a/c/driver/postgresql/postgres_type.h
+++ b/c/driver/postgresql/postgres_type.h
@@ -214,6 +214,10 @@ class PostgresType {
       case PostgresTypeId::kFloat8:
         NANOARROW_RETURN_NOT_OK(ArrowSchemaSetType(schema, 
NANOARROW_TYPE_DOUBLE));
         break;
+      case PostgresTypeId::kCash:
+        // PostgreSQL appears to send an int64, without decimal point 
information
+        NANOARROW_RETURN_NOT_OK(ArrowSchemaSetType(schema, 
NANOARROW_TYPE_INT64));
+        break;
 
       // ---- Numeric/Decimal-------------------
       case PostgresTypeId::kNumeric:
diff --git a/c/driver/postgresql/postgresql_test.cc 
b/c/driver/postgresql/postgresql_test.cc
index d8c6ee148..3c924d391 100644
--- a/c/driver/postgresql/postgresql_test.cc
+++ b/c/driver/postgresql/postgresql_test.cc
@@ -38,6 +38,7 @@
 using adbc_validation::Handle;
 using adbc_validation::IsOkStatus;
 using adbc_validation::IsStatus;
+using std::string_literals::operator""s;
 
 class PostgresQuirks : public adbc_validation::DriverQuirks {
  public:
@@ -1344,13 +1345,17 @@ struct TypeTestCase {
   std::string sql_type;
   std::string sql_literal;
   ArrowType arrow_type;
-  std::variant<bool, int64_t, double, std::string> scalar;
+  std::variant<bool, int64_t, double, std::string, ArrowInterval> scalar;
 
   static std::string FormatName(const ::testing::TestParamInfo<TypeTestCase>& 
info) {
     return info.param.name;
   }
 };
 
+ArrowInterval MonthDayNano(int32_t months, int32_t days, int64_t nanos) {
+  return {NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO, months, days, 0, nanos};
+}
+
 void PrintTo(const TypeTestCase& value, std::ostream* os) { (*os) << 
value.name; }
 
 class PostgresTypeTest : public ::testing::TestWithParam<TypeTestCase> {
@@ -1460,8 +1465,18 @@ TEST_P(PostgresTypeTest, SelectValue) {
         } else if constexpr (std::is_same_v<T, std::string>) {
           ArrowStringView view =
               ArrowArrayViewGetStringUnsafe(reader.array_view->children[0], 0);
-          ASSERT_EQ(arg.size(), view.size_bytes);
-          ASSERT_EQ(0, std::strncmp(arg.c_str(), view.data, arg.size()));
+          std::string_view v(view.data, static_cast<size_t>(view.size_bytes));
+          ASSERT_EQ(arg, v);
+        } else if constexpr (std::is_same_v<T, ArrowInterval>) {
+          ArrowInterval interval;
+          std::memset(&interval, 0, sizeof(interval));
+          ArrowArrayViewGetIntervalUnsafe(reader.array_view->children[0], 0, 
&interval);
+          // The getter doesn't set this.
+          // EXPECT_EQ(arg.type, interval.type);
+          EXPECT_EQ(arg.months, interval.months);
+          EXPECT_EQ(arg.days, interval.days);
+          EXPECT_EQ(arg.ms, interval.ms);
+          EXPECT_EQ(arg.ns, interval.ns);
         } else {
           FAIL() << "Unimplemented case";
         }
@@ -1477,12 +1492,12 @@ static std::initializer_list<TypeTestCase> 
kBoolTypeCases = {
     {"BOOL_FALSE", "BOOLEAN", "FALSE", NANOARROW_TYPE_BOOL, false},
 };
 static std::initializer_list<TypeTestCase> kBinaryTypeCases = {
-    {"BYTEA", "BYTEA", R"('\000\001\002\003\004\005\006\007'::bytea)",
+    {"BYTEA", "BYTEA", R"('\000\001\002\003\004\005\006\007'::bytea)"s,
      NANOARROW_TYPE_BINARY, std::string("\x00\x01\x02\x03\x04\x05\x06\x07", 
8)},
-    {"TEXT", "TEXT", "'foobar'", NANOARROW_TYPE_STRING, "foobar"},
-    {"CHAR6_1", "CHAR(6)", "'foo'", NANOARROW_TYPE_STRING, "foo   "},
-    {"CHAR6_2", "CHAR(6)", "'foobar'", NANOARROW_TYPE_STRING, "foobar"},
-    {"VARCHAR", "VARCHAR", "'foobar'", NANOARROW_TYPE_STRING, "foobar"},
+    {"TEXT", "TEXT", "'foobar'", NANOARROW_TYPE_STRING, "foobar"s},
+    {"CHAR6_1", "CHAR(6)", "'foo'", NANOARROW_TYPE_STRING, "foo   "s},
+    {"CHAR6_2", "CHAR(6)", "'foobar'", NANOARROW_TYPE_STRING, "foobar"s},
+    {"VARCHAR", "VARCHAR", "'foobar'", NANOARROW_TYPE_STRING, "foobar"s},
 };
 static std::initializer_list<TypeTestCase> kFloatTypeCases = {
     {"REAL", "REAL", "-1E0", NANOARROW_TYPE_FLOAT, -1.0},
@@ -1501,20 +1516,163 @@ static std::initializer_list<TypeTestCase> 
kIntTypeCases = {
      NANOARROW_TYPE_INT64, std::numeric_limits<int64_t>::max()},
 };
 static std::initializer_list<TypeTestCase> kNumericTypeCases = {
-    {"NUMERIC_TRAILING0", "NUMERIC", "1000000", NANOARROW_TYPE_STRING, 
"1000000"},
-    {"NUMERIC_LEADING0", "NUMERIC", "0.00001234", NANOARROW_TYPE_STRING, 
"0.00001234"},
-    {"NUMERIC_TRAILING02", "NUMERIC", "'1.0000'", NANOARROW_TYPE_STRING, 
"1.0000"},
-    {"NUMERIC_NEGATIVE", "NUMERIC", "-123.456", NANOARROW_TYPE_STRING, 
"-123.456"},
-    {"NUMERIC_POSITIVE", "NUMERIC", "123.456", NANOARROW_TYPE_STRING, 
"123.456"},
-    {"NUMERIC_NAN", "NUMERIC", "'nan'", NANOARROW_TYPE_STRING, "nan"},
-    {"NUMERIC_NINF", "NUMERIC", "'-inf'", NANOARROW_TYPE_STRING, "-inf"},
-    {"NUMERIC_PINF", "NUMERIC", "'inf'", NANOARROW_TYPE_STRING, "inf"},
+    {"NUMERIC_TRAILING0", "NUMERIC", "1000000", NANOARROW_TYPE_STRING, 
"1000000"s},
+    {"NUMERIC_LEADING0", "NUMERIC", "0.00001234", NANOARROW_TYPE_STRING, 
"0.00001234"s},
+    {"NUMERIC_TRAILING02", "NUMERIC", "'1.0000'", NANOARROW_TYPE_STRING, 
"1.0000"s},
+    {"NUMERIC_NEGATIVE", "NUMERIC", "-123.456", NANOARROW_TYPE_STRING, 
"-123.456"s},
+    {"NUMERIC_POSITIVE", "NUMERIC", "123.456", NANOARROW_TYPE_STRING, 
"123.456"s},
+    {"NUMERIC_NAN", "NUMERIC", "'nan'", NANOARROW_TYPE_STRING, "nan"s},
+    {"NUMERIC_NINF", "NUMERIC", "'-inf'", NANOARROW_TYPE_STRING, "-inf"s},
+    {"NUMERIC_PINF", "NUMERIC", "'inf'", NANOARROW_TYPE_STRING, "inf"s},
+    {"MONEY", "MONEY", "12.34", NANOARROW_TYPE_INT64, int64_t(1234)},
 };
 static std::initializer_list<TypeTestCase> kDateTypeCases = {
     {"DATE0", "DATE", "'1970-01-01'", NANOARROW_TYPE_DATE32, int64_t(0)},
     {"DATE1", "DATE", "'2000-01-01'", NANOARROW_TYPE_DATE32, int64_t(10957)},
     {"DATE2", "DATE", "'1950-01-01'", NANOARROW_TYPE_DATE32, int64_t(-7305)},
 };
+static std::initializer_list<TypeTestCase> kIntervalTypeCases = {
+    {
+        "INTERVAL",
+        "INTERVAL",
+        "'P-1Y2M42DT1H1M1S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(-10, 42, (1L * 60 * 60 + 60L + 1L) * 1'000'000'000),
+    },
+    {
+        "INTERVAL2",
+        "INTERVAL",
+        "'P0Y0M0DT0H0M0.1S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, 100L * 1'000'000),
+    },
+    {
+        "INTERVAL3",
+        "INTERVAL",
+        "'P0Y0M0DT0H0M0.01S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, 10L * 1'000'000),
+    },
+    {
+        "INTERVAL4",
+        "INTERVAL",
+        "'P0Y0M0DT0H0M0.001S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, 1L * 1'000'000),
+    },
+    {
+        "INTERVAL5",
+        "INTERVAL",
+        "'P0Y0M0DT0H0M0.0001S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, 100'000L),
+    },
+    {
+        "INTERVAL6",
+        "INTERVAL",
+        "'P0Y0M0DT0H0M0.00001S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, 10'000L),
+    },
+    {
+        "INTERVAL7",
+        "INTERVAL",
+        "'P0Y0M0DT0H0M0.000001S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, 1'000L),
+    },
+    {
+        "INTERVAL_YEAR",
+        "INTERVAL YEAR",
+        "'16Y'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(16 * 12, 0, 0),
+    },
+    {
+        "INTERVAL_MONTH",
+        "INTERVAL MONTH",
+        "'P0Y-2M0D'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(-2, 0, 0),
+    },
+    {
+        "INTERVAL_DAY",
+        "INTERVAL DAY",
+        "'-102D'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, -102, 0),
+    },
+    {
+        "INTERVAL_HOUR",
+        "INTERVAL HOUR",
+        "'12H'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, 12L * 60 * 60 * 1'000'000'000),
+    },
+    {
+        "INTERVAL_MINUTE",
+        "INTERVAL MINUTE",
+        "'P0Y0M0DT0H-5M0S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, -5L * 60 * 1'000'000'000),
+    },
+    {
+        "INTERVAL_SECOND",
+        "INTERVAL SECOND",
+        "'P0Y0M0DT0H0M42S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, 42L * 1'000'000'000),
+    },
+    {
+        "INTERVAL_YEAR_TO_MONTH",
+        "INTERVAL YEAR TO MONTH",
+        "'P1Y1M0D'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(13, 0, 0),
+    },
+    {
+        "INTERVAL_DAY_TO_HOUR",
+        "INTERVAL DAY TO HOUR",
+        "'P0Y0M1DT-2H0M0S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 1, -2L * 60 * 60 * 1'000'000'000),
+    },
+    {
+        "INTERVAL_DAY_TO_MINUTE",
+        "INTERVAL DAY TO MINUTE",
+        "'P0Y0M1DT-2H1M0S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 1, (-2L * 60 + 1L) * 60 * 1'000'000'000),
+    },
+    {
+        "INTERVAL_DAY_TO_SECOND",
+        "INTERVAL DAY TO SECOND",
+        "'P0Y0M1DT-2H1M-1S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 1, ((-2L * 60 + 1L) * 60 - 1L) * 1'000'000'000),
+    },
+    {
+        "INTERVAL_HOUR_TO_MINUTE",
+        "INTERVAL HOUR TO MINUTE",
+        "'P0Y0M0DT-2H1M0S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, (-2L * 60 + 1L) * 60 * 1'000'000'000),
+    },
+    {
+        "INTERVAL_HOUR_TO_SECOND",
+        "INTERVAL HOUR TO SECOND",
+        "'P0Y0M0DT-2H1M-1S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, ((-2L * 60 + 1L) * 60 - 1L) * 1'000'000'000),
+    },
+    {
+        "INTERVAL_MINUTE_TO_SECOND",
+        "INTERVAL MINUTE TO SECOND",
+        "'P0Y0M0DT0H1M-1S'",
+        NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
+        MonthDayNano(0, 0, 59L * 1'000'000'000),
+    },
+};
 static std::initializer_list<TypeTestCase> kTimeTypeCases = {
     {"TIME_WITHOUT_TIME_ZONE", "TIME WITHOUT TIME ZONE", "'00:00'", 
NANOARROW_TYPE_TIME64,
      int64_t(0)},
@@ -1644,6 +1802,8 @@ INSTANTIATE_TEST_SUITE_P(NumericType, PostgresTypeTest,
                          testing::ValuesIn(kNumericTypeCases), 
TypeTestCase::FormatName);
 INSTANTIATE_TEST_SUITE_P(DateTypes, PostgresTypeTest, 
testing::ValuesIn(kDateTypeCases),
                          TypeTestCase::FormatName);
+INSTANTIATE_TEST_SUITE_P(IntervalTypes, PostgresTypeTest,
+                         testing::ValuesIn(kIntervalTypeCases), 
TypeTestCase::FormatName);
 INSTANTIATE_TEST_SUITE_P(TimeTypes, PostgresTypeTest, 
testing::ValuesIn(kTimeTypeCases),
                          TypeTestCase::FormatName);
 INSTANTIATE_TEST_SUITE_P(TimestampTypes, PostgresTypeTest,

Reply via email to