Skip to content

Commit cb0c1e2

Browse files
authored
Add pg type type info to schema (#592)
Adding `PostgresType` into read_schema output and filling it with info obtained from `typtype` column of `pg_catalog.pg_type`. Adding a test with different type types and fixing the already existing ones. partially fixes #385 for reference: > `typtype char` typtype is b for a base type, c for a composite type (e.g., a table's row type), d for a domain, e for an enum type, p for a pseudo-type, r for a range type, or m for a multirange type. See also typrelid and typbasetype. from: https://www.postgresql.org/docs/current/catalog-pg-type.html#CATALOG-PG-TYPE
1 parent 177de22 commit cb0c1e2

File tree

3 files changed

+178
-79
lines changed

3 files changed

+178
-79
lines changed

pkg/schema/schema.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ type Column struct {
8383

8484
// Whether or not the column has been deleted in the virtual schema
8585
Deleted bool `json:"-"`
86+
87+
// Postgres type type, e.g enum, composite, range
88+
PostgresType string `json:"postgresType"`
8689
}
8790

8891
// Index represents an index on a table

pkg/state/init.sql

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,21 @@ BEGIN
163163
array_agg(e.enumlabel ORDER BY e.enumsortorder)
164164
FROM pg_enum AS e
165165
WHERE
166-
e.enumtypid = tp.oid) AS enumValues FROM pg_attribute AS attr
166+
e.enumtypid = tp.oid) AS enumValues, CASE WHEN tp.typtype = 'b' THEN
167+
'base'
168+
WHEN tp.typtype = 'c' THEN
169+
'composite'
170+
WHEN tp.typtype = 'd' THEN
171+
'domain'
172+
WHEN tp.typtype = 'e' THEN
173+
'enum'
174+
WHEN tp.typtype = 'p' THEN
175+
'pseudo'
176+
WHEN tp.typtype = 'r' THEN
177+
'range'
178+
WHEN tp.typtype = 'm' THEN
179+
'multirange'
180+
END AS postgresType FROM pg_attribute AS attr
167181
INNER JOIN pg_type AS tp ON attr.atttypid = tp.oid
168182
LEFT JOIN pg_attrdef AS def ON attr.attrelid = def.adrelid
169183
AND attr.attnum = def.adnum

pkg/state/state_test.go

Lines changed: 160 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -408,9 +408,10 @@ func TestReadSchema(t *testing.T) {
408408
Name: "table1",
409409
Columns: map[string]*schema.Column{
410410
"id": {
411-
Name: "id",
412-
Type: "integer",
413-
Nullable: true,
411+
Name: "id",
412+
Type: "integer",
413+
Nullable: true,
414+
PostgresType: "base",
414415
},
415416
},
416417
PrimaryKey: []string{},
@@ -432,10 +433,11 @@ func TestReadSchema(t *testing.T) {
432433
Name: "table1",
433434
Columns: map[string]*schema.Column{
434435
"id": {
435-
Name: "id",
436-
Type: "integer",
437-
Nullable: false,
438-
Unique: true,
436+
Name: "id",
437+
Type: "integer",
438+
Nullable: false,
439+
Unique: true,
440+
PostgresType: "base",
439441
},
440442
},
441443
PrimaryKey: []string{},
@@ -470,14 +472,16 @@ func TestReadSchema(t *testing.T) {
470472
Name: "table1",
471473
Columns: map[string]*schema.Column{
472474
"id": {
473-
Name: "id",
474-
Type: "integer",
475-
Nullable: true,
475+
Name: "id",
476+
Type: "integer",
477+
Nullable: true,
478+
PostgresType: "base",
476479
},
477480
"name": {
478-
Name: "name",
479-
Type: "text",
480-
Nullable: true,
481+
Name: "name",
482+
Type: "text",
483+
Nullable: true,
484+
PostgresType: "base",
481485
},
482486
},
483487
PrimaryKey: []string{},
@@ -507,10 +511,11 @@ func TestReadSchema(t *testing.T) {
507511
Name: "table1",
508512
Columns: map[string]*schema.Column{
509513
"id": {
510-
Name: "id",
511-
Type: "integer",
512-
Nullable: false,
513-
Unique: true,
514+
Name: "id",
515+
Type: "integer",
516+
Nullable: false,
517+
Unique: true,
518+
PostgresType: "base",
514519
},
515520
},
516521
PrimaryKey: []string{"id"},
@@ -531,9 +536,10 @@ func TestReadSchema(t *testing.T) {
531536
Name: "table2",
532537
Columns: map[string]*schema.Column{
533538
"fk": {
534-
Name: "fk",
535-
Type: "integer",
536-
Nullable: false,
539+
Name: "fk",
540+
Type: "integer",
541+
Nullable: false,
542+
PostgresType: "base",
537543
},
538544
},
539545
PrimaryKey: []string{},
@@ -563,10 +569,11 @@ func TestReadSchema(t *testing.T) {
563569
Name: "table1",
564570
Columns: map[string]*schema.Column{
565571
"id": {
566-
Name: "id",
567-
Type: "integer",
568-
Nullable: false,
569-
Unique: true,
572+
Name: "id",
573+
Type: "integer",
574+
Nullable: false,
575+
Unique: true,
576+
PostgresType: "base",
570577
},
571578
},
572579
PrimaryKey: []string{"id"},
@@ -587,9 +594,10 @@ func TestReadSchema(t *testing.T) {
587594
Name: "table2",
588595
Columns: map[string]*schema.Column{
589596
"fk": {
590-
Name: "fk",
591-
Type: "integer",
592-
Nullable: false,
597+
Name: "fk",
598+
Type: "integer",
599+
Nullable: false,
600+
PostgresType: "base",
593601
},
594602
},
595603
PrimaryKey: []string{},
@@ -619,15 +627,17 @@ func TestReadSchema(t *testing.T) {
619627
Name: "table1",
620628
Columns: map[string]*schema.Column{
621629
"id": {
622-
Name: "id",
623-
Type: "integer",
624-
Nullable: false,
625-
Unique: true,
630+
Name: "id",
631+
Type: "integer",
632+
Nullable: false,
633+
Unique: true,
634+
PostgresType: "base",
626635
},
627636
"age": {
628-
Name: "age",
629-
Type: "integer",
630-
Nullable: true,
637+
Name: "age",
638+
Type: "integer",
639+
Nullable: true,
640+
PostgresType: "base",
631641
},
632642
},
633643
PrimaryKey: []string{"id"},
@@ -663,16 +673,18 @@ func TestReadSchema(t *testing.T) {
663673
Name: "table1",
664674
Columns: map[string]*schema.Column{
665675
"id": {
666-
Name: "id",
667-
Type: "integer",
668-
Nullable: false,
669-
Unique: true,
676+
Name: "id",
677+
Type: "integer",
678+
Nullable: false,
679+
Unique: true,
680+
PostgresType: "base",
670681
},
671682
"name": {
672-
Name: "name",
673-
Type: "text",
674-
Unique: true,
675-
Nullable: true,
683+
Name: "name",
684+
Type: "text",
685+
Unique: true,
686+
Nullable: true,
687+
PostgresType: "base",
676688
},
677689
},
678690
PrimaryKey: []string{"id"},
@@ -714,16 +726,18 @@ func TestReadSchema(t *testing.T) {
714726
Name: "table1",
715727
Columns: map[string]*schema.Column{
716728
"id": {
717-
Name: "id",
718-
Type: "integer",
719-
Nullable: false,
720-
Unique: true,
729+
Name: "id",
730+
Type: "integer",
731+
Nullable: false,
732+
Unique: true,
733+
PostgresType: "base",
721734
},
722735
"name": {
723-
Name: "name",
724-
Type: "text",
725-
Nullable: true,
726-
Unique: false,
736+
Name: "name",
737+
Type: "text",
738+
Nullable: true,
739+
Unique: false,
740+
PostgresType: "base",
727741
},
728742
},
729743
PrimaryKey: []string{"id"},
@@ -773,14 +787,16 @@ func TestReadSchema(t *testing.T) {
773787
Name: "products",
774788
Columns: map[string]*schema.Column{
775789
"customer_id": {
776-
Name: "customer_id",
777-
Type: "integer",
778-
Nullable: false,
790+
Name: "customer_id",
791+
Type: "integer",
792+
Nullable: false,
793+
PostgresType: "base",
779794
},
780795
"product_id": {
781-
Name: "product_id",
782-
Type: "integer",
783-
Nullable: false,
796+
Name: "product_id",
797+
Type: "integer",
798+
Nullable: false,
799+
PostgresType: "base",
784800
},
785801
},
786802
PrimaryKey: []string{"customer_id", "product_id"},
@@ -801,14 +817,16 @@ func TestReadSchema(t *testing.T) {
801817
Name: "orders",
802818
Columns: map[string]*schema.Column{
803819
"customer_id": {
804-
Name: "customer_id",
805-
Type: "integer",
806-
Nullable: false,
820+
Name: "customer_id",
821+
Type: "integer",
822+
Nullable: false,
823+
PostgresType: "base",
807824
},
808825
"product_id": {
809-
Name: "product_id",
810-
Type: "integer",
811-
Nullable: false,
826+
Name: "product_id",
827+
Type: "integer",
828+
Nullable: false,
829+
PostgresType: "base",
812830
},
813831
},
814832
PrimaryKey: []string{},
@@ -838,14 +856,16 @@ func TestReadSchema(t *testing.T) {
838856
Name: "table1",
839857
Columns: map[string]*schema.Column{
840858
"a": {
841-
Name: "a",
842-
Type: "text",
843-
Nullable: true,
859+
Name: "a",
860+
Type: "text",
861+
Nullable: true,
862+
PostgresType: "base",
844863
},
845864
"b": {
846-
Name: "b",
847-
Type: "text",
848-
Nullable: true,
865+
Name: "b",
866+
Type: "text",
867+
Nullable: true,
868+
PostgresType: "base",
849869
},
850870
},
851871
PrimaryKey: []string{},
@@ -875,9 +895,10 @@ func TestReadSchema(t *testing.T) {
875895
Name: "table1",
876896
Columns: map[string]*schema.Column{
877897
"a": {
878-
Name: "a",
879-
Type: "public.email_type",
880-
Nullable: true,
898+
Name: "a",
899+
Type: "public.email_type",
900+
Nullable: true,
901+
PostgresType: "domain",
881902
},
882903
},
883904
PrimaryKey: []string{},
@@ -899,15 +920,76 @@ func TestReadSchema(t *testing.T) {
899920
Name: "table1",
900921
Columns: map[string]*schema.Column{
901922
"name": {
902-
Name: "name",
903-
Type: "text",
904-
Nullable: true,
923+
Name: "name",
924+
Type: "text",
925+
Nullable: true,
926+
PostgresType: "base",
905927
},
906928
"review": {
907-
Name: "review",
908-
Type: "public.review",
909-
Nullable: true,
910-
EnumValues: []string{"good", "bad", "ugly"},
929+
Name: "review",
930+
Type: "public.review",
931+
Nullable: true,
932+
EnumValues: []string{"good", "bad", "ugly"},
933+
PostgresType: "enum",
934+
},
935+
},
936+
PrimaryKey: []string{},
937+
Indexes: map[string]*schema.Index{},
938+
ForeignKeys: map[string]*schema.ForeignKey{},
939+
CheckConstraints: map[string]*schema.CheckConstraint{},
940+
UniqueConstraints: map[string]*schema.UniqueConstraint{},
941+
},
942+
},
943+
},
944+
},
945+
{
946+
name: "postgres type types",
947+
createStmt: `
948+
CREATE TYPE comptype AS (f1 int, f2 text);
949+
CREATE TYPE review AS ENUM ('good', 'bad', 'ugly');
950+
CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);
951+
CREATE DOMAIN us_postal_code AS TEXT
952+
CHECK(
953+
VALUE ~ '^\d{5}$'
954+
OR VALUE ~ '^\d{5}-\d{4}$'
955+
);
956+
CREATE TABLE public.table1 (id bigint, comp_col comptype, enum_col review, range_col float8_range, domain_col us_postal_code);`,
957+
wantSchema: &schema.Schema{
958+
Name: "public",
959+
Tables: map[string]*schema.Table{
960+
"table1": {
961+
Name: "table1",
962+
Columns: map[string]*schema.Column{
963+
"id": {
964+
Name: "id",
965+
Type: "bigint",
966+
Nullable: true,
967+
PostgresType: "base",
968+
},
969+
"comp_col": {
970+
Name: "comp_col",
971+
Type: "public.comptype",
972+
Nullable: true,
973+
PostgresType: "composite",
974+
},
975+
"enum_col": {
976+
Name: "enum_col",
977+
Type: "public.review",
978+
Nullable: true,
979+
PostgresType: "enum",
980+
EnumValues: []string{"good", "bad", "ugly"},
981+
},
982+
"range_col": {
983+
Name: "range_col",
984+
Type: "public.float8_range",
985+
Nullable: true,
986+
PostgresType: "range",
987+
},
988+
"domain_col": {
989+
Name: "domain_col",
990+
Type: "public.us_postal_code",
991+
Nullable: true,
992+
PostgresType: "domain",
911993
},
912994
},
913995
PrimaryKey: []string{},

0 commit comments

Comments
 (0)