Instance Property
columns
A
PostgresColumns collection containing metadata about the columns in the query result.var columns: PostgresColumns { get }
Discussion
This property allows you to access metadata about the columns in a query result, such as their names and data types, which can be useful when exploring a database without knowing its schema upfront.
// 1. Discover all user tables via the Postgres metadata tables
let tables = try await client.query("""
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
"""
)
for try await tableName in tables.decode(String.self) {
print("## \(tableName)")
// 2. Load rows from each table without knowing the schema upfront
// > Note: table names are identifiers, not values — they cannot be passed as bind parameters, so we must use `unsafeSQL` here.
let rows = try await client.query(
PostgresQuery(unsafeSQL: #"SELECT * FROM "\#(tableName)""#)
)
for try await row in rows {
// 3. Access column metadata via `rows.columns`
for (column, metadata) in zip(row, rows.columns) {
let value: Any
// 4. Dynamically decode column values based on their metadata data type
switch metadata.dataType {
case .int2:
value = try column.decode(Int16.self)
case .int4:
value = try column.decode(Int32.self)
case .int8:
value = try column.decode(Int64.self)
case .float4:
value = try column.decode(Float.self)
case .text:
value = try column.decode(String.self)
case .timestamp, .timestamptz:
value = try column.decode(Date.self)
case .bytea:
value = "<\(try column.decode(ByteBuffer.self).readableBytes) bytes>"
default:
// Fallback: most types can be decoded as String
value = (try? column.decode(String.self)) ?? "<unknown>"
}
print(" `\(metadata.name)` (\(metadata.dataType), value: `\(value)`)")
}
}
}