Skip to content

Commit 4a99db5

Browse files
Fix composite scanner composite patch (#296)
Signed-off-by: Aykut Bozkurt <aykut.bozkurt@snowflake.com>
1 parent 5638b9f commit 4a99db5

File tree

2 files changed

+420
-13
lines changed

2 files changed

+420
-13
lines changed

duckdb_pglake/patches/duckdb-postgres/composite-type-resolution.patch

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ index ea04300..38672a9 100644
1010
class PostgresSchemaEntry;
1111
class PostgresTransaction;
1212

13-
@@ -64,7 +65,8 @@ public:
13+
@@ -21,5 +22,6 @@ struct PostgresTypeData {
14+
int64_t type_modifier = 0;
15+
string type_name;
16+
+ int64_t type_oid = 0;
17+
idx_t array_dimensions = 0;
18+
};
19+
20+
@@ -64,7 +66,8 @@ public:
1421
static LogicalType ToPostgresType(const LogicalType &input);
1522
static LogicalType TypeToLogicalType(optional_ptr<PostgresTransaction> transaction,
1623
optional_ptr<PostgresSchemaEntry> schema, const PostgresTypeData &input,
@@ -60,32 +67,39 @@ index 2d9f5d9..6f2a3f2 100644
6067
auto &pgtypename = type_info.type_name;
6168

6269
// postgres array types start with an _
63-
@@ -113,7 +115,7 @@ LogicalType PostgresUtils::TypeToLogicalType(optional_ptr<PostgresTransaction> t
70+
@@ -113,7 +115,14 @@ LogicalType PostgresUtils::TypeToLogicalType(optional_ptr<PostgresTransaction> t
6471
child_type_info.type_name = pgtypename.substr(1);
6572
child_type_info.type_modifier = type_info.type_modifier;
73+
+ if (connection) {
74+
+ D_ASSERT(type_info.type_oid != 0);
75+
+ auto elem_result = connection->Query(StringUtil::Format(
76+
+ "SELECT typelem FROM pg_type WHERE oid = %d", type_info.type_oid));
77+
+ D_ASSERT(elem_result->Count() > 0);
78+
+ child_type_info.type_oid = elem_result->GetInt64(0, 0);
79+
+ }
6680
PostgresType child_pg_type;
6781
- auto child_type = PostgresUtils::TypeToLogicalType(transaction, schema, child_type_info, child_pg_type);
6882
+ auto child_type = PostgresUtils::TypeToLogicalType(transaction, schema, child_type_info, child_pg_type, connection);
6983
// construct the child type based on the number of dimensions
7084
for (idx_t i = 1; i < dimensions; i++) {
7185
PostgresType new_pg_type;
72-
@@ -201,7 +203,51 @@ LogicalType PostgresUtils::TypeToLogicalType(optional_ptr<PostgresTransaction> t
86+
@@ -201,7 +203,52 @@ LogicalType PostgresUtils::TypeToLogicalType(optional_ptr<PostgresTransaction> t
7387
return LogicalType::LIST(LogicalType::DOUBLE);
7488
} else {
7589
if (!transaction) {
7690
- // unsupported so fallback to varchar
7791
+ if (connection) {
78-
+ // try composite type
92+
+ D_ASSERT(type_info.type_oid != 0);
7993
+ auto query = StringUtil::Format(
80-
+ "SELECT a.attname, t.typname, a.atttypmod "
94+
+ "SELECT a.attname, t.typname, a.atttypmod, a.atttypid "
8195
+ "FROM pg_type ct "
8296
+ "JOIN pg_class c ON c.oid = ct.typrelid "
8397
+ "JOIN pg_attribute a ON a.attrelid = ct.typrelid "
8498
+ "JOIN pg_type t ON t.oid = a.atttypid "
85-
+ "WHERE ct.typname = %s AND ct.typtype = 'c' "
99+
+ "WHERE ct.oid = %d AND ct.typtype = 'c' "
86100
+ "AND a.attnum > 0 AND NOT a.attisdropped "
87101
+ "ORDER BY a.attnum",
88-
+ KeywordHelper::WriteQuoted(pgtypename).c_str());
102+
+ type_info.type_oid);
89103
+ auto result = connection->Query(query);
90104
+ auto rows = result->Count();
91105
+ if (rows > 0) {
@@ -95,6 +109,7 @@ index 2d9f5d9..6f2a3f2 100644
95109
+ PostgresTypeData field_type_info;
96110
+ field_type_info.type_name = result->GetString(row, 1);
97111
+ field_type_info.type_modifier = result->GetInt64(row, 2);
112+
+ field_type_info.type_oid = result->GetInt64(row, 3);
98113
+ PostgresType child_pg_type;
99114
+ auto field_type = TypeToLogicalType(nullptr, nullptr, field_type_info,
100115
+ child_pg_type, connection);
@@ -103,18 +118,18 @@ index 2d9f5d9..6f2a3f2 100644
103118
+ }
104119
+ return LogicalType::STRUCT(std::move(child_types));
105120
+ }
106-
+ // try domain type — resolve to base type
107121
+ auto domain_query = StringUtil::Format(
108-
+ "SELECT bt.typname, t.typtypmod "
122+
+ "SELECT bt.typname, t.typtypmod, bt.oid "
109123
+ "FROM pg_type t "
110124
+ "JOIN pg_type bt ON bt.oid = t.typbasetype "
111-
+ "WHERE t.typname = %s AND t.typtype = 'd'",
112-
+ KeywordHelper::WriteQuoted(pgtypename).c_str());
125+
+ "WHERE t.oid = %d AND t.typtype = 'd'",
126+
+ type_info.type_oid);
113127
+ auto domain_result = connection->Query(domain_query);
114128
+ if (domain_result->Count() > 0) {
115129
+ PostgresTypeData base_type_info;
116130
+ base_type_info.type_name = domain_result->GetString(0, 0);
117131
+ base_type_info.type_modifier = domain_result->GetInt64(0, 1);
132+
+ base_type_info.type_oid = domain_result->GetInt64(0, 2);
118133
+ return TypeToLogicalType(nullptr, nullptr, base_type_info,
119134
+ postgres_type, connection);
120135
+ }
@@ -126,7 +141,27 @@ diff --git a/src/storage/postgres_table_set.cpp b/src/storage/postgres_table_set
126141
index efe37a1..07d3ee6 100644
127142
--- a/src/storage/postgres_table_set.cpp
128143
+++ b/src/storage/postgres_table_set.cpp
129-
@@ -53,7 +53,7 @@ ORDER BY namespace_id, relname, attnum, constraint_id;
144+
@@ -24,16 +24,16 @@ SELECT pg_namespace.oid AS namespace_id, relname, relpages, attname,
145+
- pg_type.typname type_name, atttypmod type_modifier, pg_attribute.attndims ndim,
146+
- attnum, pg_attribute.attnotnull AS notnull, NULL constraint_id,
147+
+ pg_type.typname type_name, atttypmod type_modifier, pg_attribute.attndims ndim,
148+
+ atttypid type_oid, attnum, pg_attribute.attnotnull AS notnull, NULL constraint_id,
149+
NULL constraint_type, NULL constraint_key
150+
FROM pg_class
151+
JOIN pg_namespace ON relnamespace = pg_namespace.oid
152+
JOIN pg_attribute ON pg_class.oid=pg_attribute.attrelid
153+
JOIN pg_type ON atttypid=pg_type.oid
154+
WHERE attnum > 0 AND relkind IN ('r', 'v', 'm', 'f', 'p') ${CONDITION}
155+
UNION ALL
156+
SELECT pg_namespace.oid AS namespace_id, relname, NULL relpages, NULL attname, NULL type_name,
157+
- NULL type_modifier, NULL ndim, NULL attnum, NULL AS notnull,
158+
+ NULL type_modifier, NULL ndim, NULL type_oid, NULL attnum, NULL AS notnull,
159+
pg_constraint.oid AS constraint_id, contype AS constraint_type,
160+
conkey AS constraint_key
161+
FROM pg_class
162+
JOIN pg_namespace ON relnamespace = pg_namespace.oid
163+
JOIN pg_constraint ON (pg_class.oid=pg_constraint.conrelid)
164+
@@ -53,18 +53,19 @@ ORDER BY namespace_id, relname, attnum, constraint_id;
130165

131166
void PostgresTableSet::AddColumn(optional_ptr<PostgresTransaction> transaction,
132167
optional_ptr<PostgresSchemaEntry> schema, PostgresResult &result, idx_t row,
@@ -135,7 +170,12 @@ index efe37a1..07d3ee6 100644
135170
PostgresTypeData type_info;
136171
idx_t column_index = 3;
137172
auto column_name = result.GetString(row, column_index);
138-
@@ -64,7 +64,7 @@ void PostgresTableSet::AddColumn(optional_ptr<PostgresTransaction> transaction,
173+
type_info.type_name = result.GetString(row, column_index + 1);
174+
type_info.type_modifier = result.GetInt64(row, column_index + 2);
175+
type_info.array_dimensions = result.GetInt64(row, column_index + 3);
176+
+ type_info.type_oid = result.GetInt64(row, column_index + 4);
177+
- bool is_not_null = result.GetBool(row, column_index + 5);
178+
+ bool is_not_null = result.GetBool(row, column_index + 6);
139179
string default_value;
140180

141181
PostgresType postgres_type;
@@ -144,6 +184,11 @@ index efe37a1..07d3ee6 100644
144184
table_info.postgres_types.push_back(std::move(postgres_type));
145185
table_info.postgres_names.push_back(column_name);
146186
ColumnDefinition column(std::move(column_name), std::move(column_type));
187+
@@ -87,3 +87,3 @@ void PostgresTableSet::AddConstraint(PostgresResult &result, idx_t row, Postgres
188+
void PostgresTableSet::AddConstraint(PostgresResult &result, idx_t row, PostgresTableInfo &table_info) {
189+
- idx_t column_index = 9;
190+
+ idx_t column_index = 10;
191+
auto constraint_type = result.GetString(row, column_index + 1);
147192
@@ -109,12 +109,13 @@ void PostgresTableSet::AddConstraint(PostgresResult &result, idx_t row, Postgres
148193

149194
void PostgresTableSet::AddColumnOrConstraint(optional_ptr<PostgresTransaction> transaction,

0 commit comments

Comments
 (0)