Skip to content

Commit 8031460

Browse files
authored
Use UNION ALL instead of UNION in nullable check (#3605)
1 parent d4ae6ff commit 8031460

1 file changed

Lines changed: 34 additions & 15 deletions

File tree

sqlx-postgres/src/connection/describe.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -448,26 +448,45 @@ WHERE rngtypid = $1
448448
// This will include columns that don't have a `relation_id` (are not from a table);
449449
// assuming those are a minority of columns, it's less code to _not_ work around it
450450
// and just let Postgres return `NULL`.
451-
let mut nullable_query = QueryBuilder::new("SELECT NOT pg_attribute.attnotnull FROM ( ");
452-
453-
nullable_query.push_values(meta.columns.iter().zip(0i32..), |mut tuple, (column, i)| {
454-
// ({i}::int4, {column.relation_id}::int4, {column.relation_attribute_no}::int2)
455-
tuple.push_bind(i).push_unseparated("::int4");
456-
tuple
457-
.push_bind(column.relation_id)
458-
.push_unseparated("::int4");
459-
tuple
460-
.push_bind(column.relation_attribute_no)
461-
.push_unseparated("::int2");
462-
});
451+
//
452+
// Use `UNION ALL` syntax instead of `VALUES` due to frequent lack of
453+
// support for `VALUES` in pgwire supported databases.
454+
let mut nullable_query = QueryBuilder::new("SELECT NOT attnotnull FROM ( ");
455+
let mut separated = nullable_query.separated("UNION ALL ");
456+
457+
let mut column_iter = meta.columns.iter().zip(0i32..);
458+
if let Some((column, i)) = column_iter.next() {
459+
separated.push("( SELECT ");
460+
separated
461+
.push_bind_unseparated(i)
462+
.push_unseparated("::int4 AS idx, ");
463+
separated
464+
.push_bind_unseparated(column.relation_id)
465+
.push_unseparated("::int4 AS table_id, ");
466+
separated
467+
.push_bind_unseparated(column.relation_attribute_no)
468+
.push_unseparated("::int2 AS col_idx ) ");
469+
}
470+
471+
for (column, i) in column_iter {
472+
separated.push("( SELECT ");
473+
separated
474+
.push_bind_unseparated(i)
475+
.push_unseparated("::int4, ");
476+
separated
477+
.push_bind_unseparated(column.relation_id)
478+
.push_unseparated("::int4, ");
479+
separated
480+
.push_bind_unseparated(column.relation_attribute_no)
481+
.push_unseparated("::int2 ) ");
482+
}
463483

464484
nullable_query.push(
465-
") as col(idx, table_id, col_idx) \
466-
LEFT JOIN pg_catalog.pg_attribute \
485+
") AS col LEFT JOIN pg_catalog.pg_attribute \
467486
ON table_id IS NOT NULL \
468487
AND attrelid = table_id \
469488
AND attnum = col_idx \
470-
ORDER BY col.idx",
489+
ORDER BY idx",
471490
);
472491

473492
let mut nullables: Vec<Option<bool>> = nullable_query

0 commit comments

Comments
 (0)