Skip to content

Commit b3054cf

Browse files
committed
feat(config): allow generating models from information_schema tables
1 parent ecec179 commit b3054cf

13 files changed

Lines changed: 227 additions & 2 deletions

File tree

docs/reference/config.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ The `gen` mapping supports the following keys:
179179
- `camel` for camelCase, `pascal` for PascalCase, `snake` for snake_case or `none` to use the column name in the DB. Defaults to `none`.
180180
- `omit_unused_structs`:
181181
- If `true`, sqlc won't generate table and enum structs that aren't used in queries for a given package. Defaults to `false`.
182+
- `omit_catalog_schema`:
183+
- If `true`, sqlc won't generate structs for tables and enums in the `pg_catalog` and `information_schema` catalog schemas. Set to `false` to generate models from these schemas. Defaults to `true`.
182184
- `output_batch_file_name`:
183185
- Customize the name of the batch file. Defaults to `batch.go`.
184186
- `output_db_file_name`:
@@ -396,6 +398,7 @@ packages:
396398
build_tags: "some_tag"
397399
json_tags_case_style: "camel"
398400
omit_unused_structs: false
401+
omit_catalog_schema: true
399402
output_batch_file_name: "batch.go"
400403
output_db_file_name: "db.go"
401404
output_models_file_name: "models.go"
@@ -458,6 +461,8 @@ Each mapping in the `packages` collection has the following keys:
458461
- `camel` for camelCase, `pascal` for PascalCase, `snake` for snake_case or `none` to use the column name in the DB. Defaults to `none`.
459462
- `omit_unused_structs`:
460463
- If `true`, sqlc won't generate table and enum structs that aren't used in queries for a given package. Defaults to `false`.
464+
- `omit_catalog_schema`:
465+
- If `true`, sqlc won't generate structs for tables and enums in the `pg_catalog` and `information_schema` catalog schemas. Set to `false` to generate models from these schemas. Defaults to `true`.
461466
- `output_batch_file_name`:
462467
- Customize the name of the batch file. Defaults to `batch.go`.
463468
- `output_db_file_name`:

internal/codegen/golang/opts/options.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type Options struct {
4949
QueryParameterLimit *int32 `json:"query_parameter_limit,omitempty" yaml:"query_parameter_limit"`
5050
OmitSqlcVersion bool `json:"omit_sqlc_version,omitempty" yaml:"omit_sqlc_version"`
5151
OmitUnusedStructs bool `json:"omit_unused_structs,omitempty" yaml:"omit_unused_structs"`
52+
OmitCatalogSchema *bool `json:"omit_catalog_schema,omitempty" yaml:"omit_catalog_schema"`
5253
BuildTags string `json:"build_tags,omitempty" yaml:"build_tags"`
5354
Initialisms *[]string `json:"initialisms,omitempty" yaml:"initialisms"`
5455

@@ -185,6 +186,16 @@ func (o *Options) ModelsEmitEnabled() bool {
185186
return *o.OutputModelsEmit
186187
}
187188

189+
// OmitCatalogSchemaEnabled reports whether the pg_catalog and
190+
// information_schema catalog schemas should be excluded when generating
191+
// models. Defaults to true when the option is unset.
192+
func (o *Options) OmitCatalogSchemaEnabled() bool {
193+
if o.OmitCatalogSchema == nil {
194+
return true
195+
}
196+
return *o.OmitCatalogSchema
197+
}
198+
188199
// ModelsImportAlias is the fixed Go import alias used for the models
189200
// package in query files. Using a constant alias keeps the type qualifier
190201
// consistent regardless of how the user names the actual package.

internal/codegen/golang/result.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
func buildEnums(req *plugin.GenerateRequest, options *opts.Options) []Enum {
1717
var enums []Enum
1818
for _, schema := range req.Catalog.Schemas {
19-
if schema.Name == "pg_catalog" || schema.Name == "information_schema" {
19+
if options.OmitCatalogSchemaEnabled() && (schema.Name == "pg_catalog" || schema.Name == "information_schema") {
2020
continue
2121
}
2222
for _, enum := range schema.Enums {
@@ -63,7 +63,7 @@ func buildEnums(req *plugin.GenerateRequest, options *opts.Options) []Enum {
6363
func buildStructs(req *plugin.GenerateRequest, options *opts.Options) []Struct {
6464
var structs []Struct
6565
for _, schema := range req.Catalog.Schemas {
66-
if schema.Name == "pg_catalog" || schema.Name == "information_schema" {
66+
if options.OmitCatalogSchemaEnabled() && (schema.Name == "pg_catalog" || schema.Name == "information_schema") {
6767
continue
6868
}
6969
for _, table := range schema.Tables {

internal/codegen/golang/result_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,75 @@ package golang
33
import (
44
"testing"
55

6+
"github.com/sqlc-dev/sqlc/internal/codegen/golang/opts"
67
"github.com/sqlc-dev/sqlc/internal/metadata"
78
"github.com/sqlc-dev/sqlc/internal/plugin"
89
)
910

11+
func boolPtr(b bool) *bool { return &b }
12+
13+
func catalogSchemaRequest() *plugin.GenerateRequest {
14+
col := func(name, typ string) *plugin.Column {
15+
return &plugin.Column{Name: name, Type: &plugin.Identifier{Name: typ}}
16+
}
17+
table := func(schema, name string, cols ...*plugin.Column) *plugin.Schema {
18+
return &plugin.Schema{
19+
Name: schema,
20+
Tables: []*plugin.Table{
21+
{Rel: &plugin.Identifier{Schema: schema, Name: name}, Columns: cols},
22+
},
23+
}
24+
}
25+
return &plugin.GenerateRequest{
26+
Settings: &plugin.Settings{Engine: "postgresql"},
27+
Catalog: &plugin.Catalog{
28+
DefaultSchema: "public",
29+
Schemas: []*plugin.Schema{
30+
table("pg_catalog", "pg_class", col("oid", "oid")),
31+
table("information_schema", "tables", col("table_name", "text")),
32+
table("public", "users", col("id", "int4")),
33+
},
34+
},
35+
}
36+
}
37+
38+
func TestBuildStructs_OmitCatalogSchema(t *testing.T) {
39+
req := catalogSchemaRequest()
40+
41+
t.Run("unset (default) skips pg_catalog and information_schema", func(t *testing.T) {
42+
structs := buildStructs(req, &opts.Options{})
43+
for _, s := range structs {
44+
if s.Table != nil && (s.Table.Schema == "pg_catalog" || s.Table.Schema == "information_schema") {
45+
t.Errorf("unexpected catalog struct: %s.%s", s.Table.Schema, s.Table.Name)
46+
}
47+
}
48+
})
49+
50+
t.Run("omit=true skips pg_catalog and information_schema", func(t *testing.T) {
51+
structs := buildStructs(req, &opts.Options{OmitCatalogSchema: boolPtr(true)})
52+
for _, s := range structs {
53+
if s.Table != nil && (s.Table.Schema == "pg_catalog" || s.Table.Schema == "information_schema") {
54+
t.Errorf("unexpected catalog struct: %s.%s", s.Table.Schema, s.Table.Name)
55+
}
56+
}
57+
})
58+
59+
t.Run("omit=false includes pg_catalog and information_schema", func(t *testing.T) {
60+
structs := buildStructs(req, &opts.Options{OmitCatalogSchema: boolPtr(false)})
61+
schemas := make(map[string]bool)
62+
for _, s := range structs {
63+
if s.Table != nil {
64+
schemas[s.Table.Schema] = true
65+
}
66+
}
67+
for _, want := range []string{"pg_catalog", "information_schema", "public"} {
68+
if !schemas[want] {
69+
t.Errorf("expected structs for schema %q, got none", want)
70+
}
71+
}
72+
})
73+
}
74+
1075
func TestPutOutColumns_ForZeroColumns(t *testing.T) {
1176
tests := []struct {
1277
cmd string

internal/config/v_one.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ type v1PackageSettings struct {
6262
QueryParameterLimit *int32 `json:"query_parameter_limit,omitempty" yaml:"query_parameter_limit"`
6363
OmitSqlcVersion bool `json:"omit_sqlc_version,omitempty" yaml:"omit_sqlc_version"`
6464
OmitUnusedStructs bool `json:"omit_unused_structs,omitempty" yaml:"omit_unused_structs"`
65+
OmitCatalogSchema *bool `json:"omit_catalog_schema,omitempty" yaml:"omit_catalog_schema"`
6566
Rules []string `json:"rules" yaml:"rules"`
6667
BuildTags string `json:"build_tags,omitempty" yaml:"build_tags"`
6768
}
@@ -177,6 +178,7 @@ func (c *V1GenerateSettings) Translate() Config {
177178
QueryParameterLimit: pkg.QueryParameterLimit,
178179
OmitSqlcVersion: pkg.OmitSqlcVersion,
179180
OmitUnusedStructs: pkg.OmitUnusedStructs,
181+
OmitCatalogSchema: pkg.OmitCatalogSchema,
180182
BuildTags: pkg.BuildTags,
181183
},
182184
},

internal/config/v_one.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@
263263
"omit_unused_structs": {
264264
"type": "boolean"
265265
},
266+
"omit_catalog_schema": {
267+
"type": "boolean"
268+
},
266269
"rules": {
267270
"type": "array",
268271
"items": {

internal/config/v_two.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,9 @@
280280
},
281281
"omit_unused_structs": {
282282
"type": "boolean"
283+
},
284+
"omit_catalog_schema": {
285+
"type": "boolean"
283286
}
284287
},
285288
"json": {

internal/endtoend/testdata/omit_catalog_schema/postgresql/stdlib/go/db.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/omit_catalog_schema/postgresql/stdlib/go/models.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/omit_catalog_schema/postgresql/stdlib/go/query.sql.go

Lines changed: 69 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)