snapshot of https://github.com/sqlc-dev/sqlc.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
This commit is contained in:
118
internal/goldeneye/postgresql/relation.go
Normal file
118
internal/goldeneye/postgresql/relation.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pgx "github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
// Relations are the relations available in pg_tables and pg_views
|
||||
// such as pg_catalog.pg_timezone_names
|
||||
const relationQuery = `
|
||||
with relations as (
|
||||
select schemaname, tablename as name from pg_catalog.pg_tables
|
||||
UNION ALL
|
||||
select schemaname, viewname as name from pg_catalog.pg_views
|
||||
)
|
||||
select
|
||||
relations.schemaname,
|
||||
relations.name as tablename,
|
||||
pg_attribute.attname as column_name,
|
||||
attnotnull as column_notnull,
|
||||
-- An array column's type is its element's, with the array flag set,
|
||||
-- rather than pg_type's own _text spelling of the array type. Only the
|
||||
-- _-prefixed array types count: int2vector and oidvector are in the
|
||||
-- array category and carry an element, but are types of their own.
|
||||
coalesce(element_type.typname, column_type.typname) as column_type,
|
||||
nullif(coalesce(element_type.typlen, column_type.typlen), -1) as column_length,
|
||||
element_type.oid is not null as column_isarray
|
||||
from relations
|
||||
inner join pg_catalog.pg_class on pg_class.relname = relations.name
|
||||
left join pg_catalog.pg_attribute on pg_attribute.attrelid = pg_class.oid
|
||||
inner join pg_catalog.pg_type column_type on pg_attribute.atttypid = column_type.oid
|
||||
left join pg_catalog.pg_type element_type
|
||||
on column_type.typcategory = 'A' and column_type.typname like '\_%'
|
||||
and element_type.oid = column_type.typelem
|
||||
where relations.schemaname = $1
|
||||
-- Make sure these columns are always generated in the same order
|
||||
-- so that the output is stable
|
||||
order by
|
||||
relations.schemaname ASC,
|
||||
relations.name ASC,
|
||||
pg_attribute.attnum ASC
|
||||
`
|
||||
|
||||
type Relation struct {
|
||||
Catalog string
|
||||
SchemaName string
|
||||
Name string
|
||||
Columns []RelationColumn
|
||||
}
|
||||
|
||||
type RelationColumn struct {
|
||||
Name string
|
||||
Type string
|
||||
IsNotNull bool
|
||||
IsArray bool
|
||||
Length *int
|
||||
}
|
||||
|
||||
func scanRelations(rows pgx.Rows) ([]Relation, error) {
|
||||
defer rows.Close()
|
||||
// Iterate through the result set
|
||||
var relations []Relation
|
||||
var prevRel *Relation
|
||||
|
||||
for rows.Next() {
|
||||
var schemaName string
|
||||
var tableName string
|
||||
var columnName string
|
||||
var columnNotNull bool
|
||||
var columnType string
|
||||
var columnLength *int
|
||||
var columnIsArray bool
|
||||
err := rows.Scan(
|
||||
&schemaName,
|
||||
&tableName,
|
||||
&columnName,
|
||||
&columnNotNull,
|
||||
&columnType,
|
||||
&columnLength,
|
||||
&columnIsArray,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if prevRel == nil || tableName != prevRel.Name {
|
||||
// We are on the same table, just keep adding columns
|
||||
r := Relation{
|
||||
Catalog: "pg_catalog",
|
||||
SchemaName: schemaName,
|
||||
Name: tableName,
|
||||
}
|
||||
|
||||
relations = append(relations, r)
|
||||
prevRel = &relations[len(relations)-1]
|
||||
}
|
||||
|
||||
prevRel.Columns = append(prevRel.Columns, RelationColumn{
|
||||
Name: columnName,
|
||||
Type: columnType,
|
||||
IsNotNull: columnNotNull,
|
||||
IsArray: columnIsArray,
|
||||
Length: columnLength,
|
||||
})
|
||||
}
|
||||
|
||||
return relations, rows.Err()
|
||||
}
|
||||
|
||||
func readRelations(ctx context.Context, conn *pgx.Conn, schemaName string) ([]Relation, error) {
|
||||
rows, err := conn.Query(ctx, relationQuery, schemaName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return scanRelations(rows)
|
||||
}
|
||||
Reference in New Issue
Block a user