Skip to content

Commit c2e8705

Browse files
committed
WIP fix(postgres): use non-prepared statements for metadata queries (10)
1 parent 74da942 commit c2e8705

1 file changed

Lines changed: 16 additions & 6 deletions

File tree

sqlx-postgres/src/connection/resolve.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,14 @@ impl PgConnection {
162162
continue;
163163
}
164164

165+
if let PgType::DeclareArrayOf(array_of) = &ty.0 {
166+
// Eagerly bring the element type into cache for array types declared by-name
167+
resolver.push_type(
168+
format_args!("E'{}'", array_of.elem_name),
169+
format_args!("to_regtype(E'{}')", array_of.elem_name),
170+
);
171+
}
172+
165173
resolver.push_type(
166174
// `escape_default()` should produce a valid SQL string literal
167175
// https://doc.rust-lang.org/stable/std/primitive.char.html#method.escape_default
@@ -354,28 +362,29 @@ impl TypeResolver {
354362
if self.query.is_empty() {
355363
write!(
356364
&mut self.query,
365+
// Postgres 13 would return `0` instead of `NULL` for `typelem`, `typbasetype`
357366
"SELECT pg_type.oid,\n\
358367
pg_type.oid::regtype::text pretty_name,\n\
359368
typname catalog_name,\n\
360369
original_name,\n\
361370
typtype,\n\
362371
typcategory,\n\
363-
typelem,\n\
364-
typbasetype,\n\
372+
NULLIF(typelem, 0::oid) typelem,\n\
373+
NULLIF(typbasetype, 0::oid) typbasetype,\n\
365374
rngsubtype,\n\
366375
COALESCE(\
367376
(SELECT array_agg(enumlabel) FROM (SELECT *\n\
368377
FROM pg_catalog.pg_enum\n\
369378
WHERE enumtypid = pg_type.oid\n\
370-
ORDER BY enumsortorder)),\n\
379+
ORDER BY enumsortorder) labels),\n\
371380
'{{}}') enum_labels,\n\
372381
COALESCE(\n\
373382
(SELECT array_agg((attname, atttypid)) FROM (SELECT *\n\
374383
FROM pg_catalog.pg_attribute\n\
375384
WHERE attrelid = pg_type.typrelid\n\
376385
AND NOT attisdropped\n\
377386
AND attnum > 0\n\
378-
ORDER BY attnum)),\n\
387+
ORDER BY attnum) attributes),\n\
379388
'{{}}') record_attributes\n\
380389
FROM (SELECT DISTINCT ON(lookup_oid) original_name, lookup_oid\n\
381390
FROM (VALUES ({original_name}, {oid_expr})"
@@ -409,7 +418,7 @@ impl TypeResolver {
409418
LEFT JOIN pg_catalog.pg_range ON pg_type.oid = pg_range.rngtypid",
410419
);
411420

412-
tracing::trace!(?query, "fill_cache");
421+
tracing::trace!(query, "fill_cache");
413422

414423
let types = raw_sql(AssertSqlSafe(query)).fetch_all(&mut *conn).await?;
415424

@@ -518,10 +527,11 @@ impl ColumnResolver {
518527
if self.query.is_empty() {
519528
write!(
520529
self.query,
530+
// Postgres 13 does not accept `(attnum,attname)` without `ROW`
521531
"SELECT\n\
522532
attrelid table_oid,\n\
523533
attrelid::regclass::text table_name,\n\
524-
array_agg((attnum, attname)) columns\n\
534+
array_agg(ROW(attnum, attname)) AS columns\n\
525535
FROM (VALUES ({}, {attribute_no})",
526536
table_oid.0,
527537
)

0 commit comments

Comments
 (0)