Skip to content

Commit

Permalink
feat(c/driver/postgresql): UInt(8/16/32) Writer (#1961)
Browse files Browse the repository at this point in the history
More progress towards #1950
  • Loading branch information
WillAyd committed Jul 2, 2024
1 parent d9a92b8 commit 33ebd9d
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
100 changes: 100 additions & 0 deletions c/driver/postgresql/copy/postgres_copy_writer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// specific language governing permissions and limitations
// under the License.

#include <limits>
#include <optional>
#include <tuple>

Expand Down Expand Up @@ -188,6 +189,105 @@ TEST(PostgresCopyUtilsTest, PostgresCopyWriteInt64) {
}
}

// COPY (SELECT CAST("col" AS SMALLINT) AS "col" FROM ( VALUES (0), (255),
// (NULL)) AS drvd("col")) TO STDOUT WITH (FORMAT binary);
static const uint8_t kTestPgCopyUInt8[] = {
0x50, 0x47, 0x43, 0x4f, 0x50, 0x59, 0x0a, 0xff, 0x0d, 0x0a, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
0x00, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

TEST(PostgresCopyUtilsTest, PostgresCopyWriteUInt8) {
adbc_validation::Handle<struct ArrowSchema> schema;
adbc_validation::Handle<struct ArrowArray> array;
struct ArrowError na_error;
ASSERT_EQ(adbc_validation::MakeSchema(&schema.value, {{"col", NANOARROW_TYPE_UINT8}}),
ADBC_STATUS_OK);
ASSERT_EQ(adbc_validation::MakeBatch<uint8_t>(
&schema.value, &array.value, &na_error,
{0, (std::numeric_limits<uint8_t>::max)(), std::nullopt}),
ADBC_STATUS_OK);

PostgresCopyStreamWriteTester tester;
ASSERT_EQ(tester.Init(&schema.value, &array.value), NANOARROW_OK);
ASSERT_EQ(tester.WriteAll(nullptr), ENODATA);

const struct ArrowBuffer buf = tester.WriteBuffer();
// The last 2 bytes of a message can be transmitted via PQputCopyData
// so no need to test those bytes from the Writer
constexpr size_t buf_size = sizeof(kTestPgCopyUInt8) - 2;
ASSERT_EQ(buf.size_bytes, buf_size);
for (size_t i = 0; i < buf_size; i++) {
ASSERT_EQ(buf.data[i], kTestPgCopyUInt8[i]);
}
}

// COPY (SELECT CAST("col" AS INTEGER) AS "col" FROM ( VALUES (0), (65535),
// (NULL)) AS drvd("col")) TO STDOUT WITH (FORMAT binary);
static const uint8_t kTestPgCopyUInt16[] = {
0x50, 0x47, 0x43, 0x4f, 0x50, 0x59, 0x0a, 0xff, 0x0d, 0x0a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00,
0x00, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

TEST(PostgresCopyUtilsTest, PostgresCopyWriteUInt16) {
adbc_validation::Handle<struct ArrowSchema> schema;
adbc_validation::Handle<struct ArrowArray> array;
struct ArrowError na_error;
ASSERT_EQ(adbc_validation::MakeSchema(&schema.value, {{"col", NANOARROW_TYPE_UINT16}}),
ADBC_STATUS_OK);
ASSERT_EQ(adbc_validation::MakeBatch<uint16_t>(
&schema.value, &array.value, &na_error,
{0, (std::numeric_limits<uint16_t>::max)(), std::nullopt}),
ADBC_STATUS_OK);

PostgresCopyStreamWriteTester tester;
ASSERT_EQ(tester.Init(&schema.value, &array.value), NANOARROW_OK);
ASSERT_EQ(tester.WriteAll(nullptr), ENODATA);

const struct ArrowBuffer buf = tester.WriteBuffer();
// The last 2 bytes of a message can be transmitted via PQputCopyData
// so no need to test those bytes from the Writer
constexpr size_t buf_size = sizeof(kTestPgCopyUInt16) - 2;
ASSERT_EQ(buf.size_bytes, buf_size);
for (size_t i = 0; i < buf_size; i++) {
ASSERT_EQ(buf.data[i], kTestPgCopyUInt16[i]);
}
}

// COPY (SELECT CAST("col" AS BIGINT) AS "col" FROM ( VALUES (0), (2^32-1),
// (NULL)) AS drvd("col")) TO STDOUT WITH (FORMAT binary);
static const uint8_t kTestPgCopyUInt32[] = {
0x50, 0x47, 0x43, 0x4f, 0x50, 0x59, 0x0a, 0xff, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

TEST(PostgresCopyUtilsTest, PostgresCopyWriteUInt32) {
adbc_validation::Handle<struct ArrowSchema> schema;
adbc_validation::Handle<struct ArrowArray> array;
struct ArrowError na_error;
ASSERT_EQ(adbc_validation::MakeSchema(&schema.value, {{"col", NANOARROW_TYPE_UINT32}}),
ADBC_STATUS_OK);
ASSERT_EQ(adbc_validation::MakeBatch<uint32_t>(
&schema.value, &array.value, &na_error,
{0, (std::numeric_limits<uint32_t>::max)(), std::nullopt}),
ADBC_STATUS_OK);

PostgresCopyStreamWriteTester tester;
ASSERT_EQ(tester.Init(&schema.value, &array.value), NANOARROW_OK);
ASSERT_EQ(tester.WriteAll(nullptr), ENODATA);

const struct ArrowBuffer buf = tester.WriteBuffer();
// The last 2 bytes of a message can be transmitted via PQputCopyData
// so no need to test those bytes from the Writer
constexpr size_t buf_size = sizeof(kTestPgCopyUInt32) - 2;
ASSERT_EQ(buf.size_bytes, buf_size);
for (size_t i = 0; i < buf_size; i++) {
ASSERT_EQ(buf.data[i], kTestPgCopyUInt32[i]);
}
}

TEST(PostgresCopyUtilsTest, PostgresCopyWriteReal) {
adbc_validation::Handle<struct ArrowSchema> schema;
adbc_validation::Handle<struct ArrowArray> array;
Expand Down
3 changes: 3 additions & 0 deletions c/driver/postgresql/copy/writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,12 +506,15 @@ static inline ArrowErrorCode MakeCopyFieldWriter(
return NANOARROW_OK;
case NANOARROW_TYPE_INT8:
case NANOARROW_TYPE_INT16:
case NANOARROW_TYPE_UINT8:
*out = std::make_unique<PostgresCopyNetworkEndianFieldWriter<int16_t>>();
return NANOARROW_OK;
case NANOARROW_TYPE_INT32:
case NANOARROW_TYPE_UINT16:
*out = std::make_unique<PostgresCopyNetworkEndianFieldWriter<int32_t>>();
return NANOARROW_OK;
case NANOARROW_TYPE_INT64:
case NANOARROW_TYPE_UINT32:
*out = std::make_unique<PostgresCopyNetworkEndianFieldWriter<int64_t>>();
return NANOARROW_OK;
case NANOARROW_TYPE_DATE32: {
Expand Down

0 comments on commit 33ebd9d

Please sign in to comment.