Skip to content

Commit

Permalink
feat(c/driver/postgresql): add arrow.opaque type metadata
Browse files Browse the repository at this point in the history
Fixes #2099.
  • Loading branch information
lidavidm committed Sep 4, 2024
1 parent 0d6117e commit 5d2f6aa
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
20 changes: 20 additions & 0 deletions c/driver/postgresql/postgres_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ class PostgresType {
std::vector<PostgresType> children_;

static constexpr const char* kPostgresTypeKey = "ADBC:postgresql:typname";
static constexpr const char* kExtensionName = "ARROW:extension:name";
static constexpr const char* kOpaqueExtensionName = "arrow.opaque";
static constexpr const char* kExtensionMetadata = "ARROW:extension:metadata";

ArrowErrorCode AddPostgresTypeMetadata(ArrowSchema* schema) const {
// the typname_ may not always be set: an instance of this class can be
Expand All @@ -322,8 +325,25 @@ class PostgresType {
nanoarrow::UniqueBuffer buffer;

ArrowMetadataBuilderInit(buffer.get(), nullptr);
// TODO(lidavidm): we have deprecated this in favor of arrow.opaque,
// remove once we feel enough time has passed
NANOARROW_RETURN_NOT_OK(ArrowMetadataBuilderAppend(
buffer.get(), ArrowCharView(kPostgresTypeKey), ArrowCharView(typname)));

// Add the Opaque extension type metadata
std::string metadata = R"({"type_name": ")";
metadata += typname;
metadata += R"(", "vendor_name": "PostgreSQL"})";
NANOARROW_RETURN_NOT_OK(
ArrowMetadataBuilderAppend(buffer.get(), ArrowCharView(kExtensionName),
ArrowCharView(kOpaqueExtensionName)));
NANOARROW_RETURN_NOT_OK(
ArrowMetadataBuilderAppend(buffer.get(), ArrowCharView(kExtensionMetadata),
ArrowStringView{
metadata.c_str(),
static_cast<int64_t>(metadata.size()),
}));

NANOARROW_RETURN_NOT_OK(
ArrowSchemaSetMetadata(schema, reinterpret_cast<char*>(buffer->data)));

Expand Down
8 changes: 8 additions & 0 deletions c/driver/postgresql/postgres_type_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ TEST(PostgresTypeTest, PostgresTypeSetSchema) {
&typnameMetadataValue);
EXPECT_EQ(std::string(typnameMetadataValue.data, typnameMetadataValue.size_bytes),
"numeric");
ArrowMetadataGetValue(schema->metadata, ArrowCharView("ARROW:extension:name"),
&typnameMetadataValue);
EXPECT_EQ(std::string(typnameMetadataValue.data, typnameMetadataValue.size_bytes),
"arrow.opaque");
ArrowMetadataGetValue(schema->metadata, ArrowCharView("ARROW:extension:metadata"),
&typnameMetadataValue);
EXPECT_EQ(std::string(typnameMetadataValue.data, typnameMetadataValue.size_bytes),
R"({"type_name": "numeric", "vendor_name": "PostgreSQL"})");
schema.reset();

ArrowSchemaInit(schema.get());
Expand Down
17 changes: 17 additions & 0 deletions docs/source/driver/postgresql.rst
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,23 @@ being read or written.
overflow/underflow; an error will be returned if this would be
the case.
Unknown Types
~~~~~~~~~~~~~

Types without direct Arrow equivalents can still be returned by the driver.
In this case, the Arrow type will be binary, and the contents will be the raw
bytes as provided by the PostgreSQL wire protocol.

For Arrow implementations that support the :external:doc:`Opaque canonical
extension type <format/CanonicalExtensions>`, the extension type metadata is
also always present. This helps differentiate when the driver intentionally
returned a binary column from when it returned a binary column as a fallback.

.. warning:: Currently, the driver also attaches a metadata key named
``ADBC:posgresql:typname`` to the schema field of the unknown
column, but this has been deprecated in favor of the Opaque type
and you should not rely on this key continuing to exist.

Software Versions
=================

Expand Down

0 comments on commit 5d2f6aa

Please sign in to comment.