Repository: ariga/atlas
Pull request #478 (2022-01-24 15:46:21)

internal: move typedoc to its own package


Patch:
diff --git a/internal/integration/go.mod b/internal/integration/go.mod
index 43a33c39..6b32c6e0 100644
--- a/internal/integration/go.mod
+++ b/internal/integration/go.mod
@@ -1,4 +1,4 @@
-module ariga.io/atlas/integration
+module ariga.io/atlas/internal/integration
 
 go 1.17
 
diff --git a/internal/typedoc/go.mod b/internal/typedoc/go.mod
new file mode 100644
index 00000000..e16970a8
--- /dev/null
+++ b/internal/typedoc/go.mod
@@ -0,0 +1,19 @@
+module ariga.io/atlas/internal/typedoc
+
+go 1.17
+
+replace ariga.io/atlas => ../../
+
+require ariga.io/atlas v0.0.0
+
+require (
+	github.com/agext/levenshtein v1.2.1 // indirect
+	github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
+	github.com/go-openapi/inflect v0.19.0 // indirect
+	github.com/google/go-cmp v0.5.6 // indirect
+	github.com/hashicorp/hcl/v2 v2.10.0 // indirect
+	github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
+	github.com/zclconf/go-cty v1.8.0 // indirect
+	golang.org/x/mod v0.5.0 // indirect
+	golang.org/x/text v0.3.7 // indirect
+)
diff --git a/internal/typedoc/go.sum b/internal/typedoc/go.sum
new file mode 100644
index 00000000..d02b659d
--- /dev/null
+++ b/internal/typedoc/go.sum
@@ -0,0 +1,57 @@
+github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
+github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
+github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
+github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
+github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
+github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
+github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
+github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
+github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/hashicorp/hcl/v2 v2.10.0 h1:1S1UnuhDGlv3gRFV4+0EdwB+znNP5HmcGbIqwnSCByg=
+github.com/hashicorp/hcl/v2 v2.10.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
+github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
+github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
+github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
+github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
+github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
+github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
+github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA=
+github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
+github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q=
+golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
+golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/internal/integration/typedoc/main.go b/internal/typedoc/main.go
similarity index 98%
rename from internal/integration/typedoc/main.go
rename to internal/typedoc/main.go
index 37cb6d56..2356fa23 100644
--- a/internal/integration/typedoc/main.go
+++ b/internal/typedoc/main.go
@@ -64,7 +64,7 @@ enum "my_enum" &#123;
 			return drv.Types[i].Name < drv.Types[j].Name
 		})
 	}
-	f, err := os.Create("../../../doc/md/ddl/sql_types.md")
+	f, err := os.Create("../../doc/md/ddl/sql_types.md")
 	if err != nil {
 		log.Fatalf("error: %s", err)
 	}
diff --git a/internal/integration/typedoc/output.tmpl b/internal/typedoc/output.tmpl
similarity index 100%
rename from internal/integration/typedoc/output.tmpl
rename to internal/typedoc/output.tmpl
diff --git a/sql/postgres/convert.go b/sql/postgres/convert.go
index be045698..5e3fba04 100644
--- a/sql/postgres/convert.go
+++ b/sql/postgres/convert.go
@@ -184,14 +184,15 @@ func arrayType(t string) (string, bool) {
 
 // columnDesc represents a column descriptor.
 type columnDesc struct {
-	typ       string
-	size      int64
-	udt       string
-	precision int64
-	scale     int64
-	typtype   string
-	typid     int64
-	parts     []string
+	typ           string
+	size          int64
+	udt           string
+	precision     int64
+	timePrecision int64
+	scale         int64
+	typtype       string
+	typid         int64
+	parts         []string
 }
 
 func parseColumn(s string) (*columnDesc, error) {
diff --git a/sql/postgres/inspect.go b/sql/postgres/inspect.go
index 255896a8..94655bd1 100644
--- a/sql/postgres/inspect.go
+++ b/sql/postgres/inspect.go
@@ -173,10 +173,13 @@ func (i *inspect) columns(ctx context.Context, t *schema.Table) error {
 // addColumn scans the current row and adds a new column from it to the table.
 func (i *inspect) addColumn(t *schema.Table, rows *sql.Rows) error {
 	var (
-		typid, maxlen, precision, scale, seqstart, seqinc                                              sql.NullInt64
+		typid, maxlen, precision, timeprecision, scale, seqstart, seqinc                               sql.NullInt64
 		name, typ, nullable, defaults, udt, identity, generation, charset, collation, comment, typtype sql.NullString
 	)
-	if err := rows.Scan(&name, &typ, &nullable, &defaults, &maxlen, &precision, &scale, &charset, &collation, &udt, &identity, &seqstart, &seqinc, &generation, &comment, &typtype, &typid); err != nil {
+	if err := rows.Scan(
+		&name, &typ, &nullable, &defaults, &maxlen, &precision, &timeprecision, &scale, &charset,
+		&collation, &udt, &identity, &seqstart, &seqinc, &generation, &comment, &typtype, &typid,
+	); err != nil {
 		return err
 	}
 	c := &schema.Column{
@@ -187,13 +190,14 @@ func (i *inspect) addColumn(t *schema.Table, rows *sql.Rows) error {
 		},
 	}
 	c.Type.Type = columnType(&columnDesc{
-		typ:       typ.String,
-		size:      maxlen.Int64,
-		udt:       udt.String,
-		precision: precision.Int64,
-		scale:     scale.Int64,
-		typtype:   typtype.String,
-		typid:     typid.Int64,
+		typ:           typ.String,
+		size:          maxlen.Int64,
+		udt:           udt.String,
+		precision:     precision.Int64,
+		timePrecision: timeprecision.Int64,
+		scale:         scale.Int64,
+		typtype:       typtype.String,
+		typid:         typid.Int64,
 	})
 	if sqlx.ValidString(defaults) {
 		c.Default = defaultExpr(c, defaults.String)
@@ -247,7 +251,7 @@ func columnType(c *columnDesc) schema.Type {
 		typ = &schema.SpatialType{T: t}
 	case TypeDate, TypeTime, TypeTimeWTZ, TypeTimeWOTZ,
 		TypeTimestamp, TypeTimestampTZ, TypeTimestampWTZ, TypeTimestampWOTZ:
-		typ = &schema.TimeType{T: t}
+		typ = &schema.TimeType{T: t, Precision: int(c.timePrecision)}
 	case TypeInterval:
 		// TODO: get 'interval_type' from query above before implementing.
 		typ = &schema.UnsupportedType{T: t}
@@ -755,6 +759,7 @@ SELECT
 	t1.column_default,
 	t1.character_maximum_length,
 	t1.numeric_precision,
+	t1.datetime_precision,
 	t1.numeric_scale,
 	t1.character_set_name,
 	t1.collation_name,
diff --git a/sql/postgres/sqlspec.go b/sql/postgres/sqlspec.go
index d29f458d..c695e56a 100644
--- a/sql/postgres/sqlspec.go
+++ b/sql/postgres/sqlspec.go
@@ -339,6 +339,7 @@ var TypeRegistry = specutil.NewRegistry(
 		specutil.TypeSpec(TypeTime),
 		specutil.AliasTypeSpec("time_with_time_zone", TypeTimeWTZ),
 		specutil.AliasTypeSpec("time_without_time_zone", TypeTimeWOTZ),
+		specutil.TypeSpec(TypeTimestampTZ),
 		specutil.TypeSpec(TypeTimestamp),
 		specutil.AliasTypeSpec("timestamp_with_time_zone", TypeTimestampWTZ),
 		specutil.AliasTypeSpec("timestamp_without_time_zone", TypeTimestampWOTZ),


Test patch:
diff --git a/internal/integration/postgres_test.go b/internal/integration/postgres_test.go
index c833ec29..f9fa5013 100644
--- a/internal/integration/postgres_test.go
+++ b/internal/integration/postgres_test.go
@@ -546,6 +546,7 @@ create table atlas_types_sanity
     "tTimestampTZ"         timestamptz                 default now()                                    null,
     "tTimestampWTZ"        timestamp with time zone    default now()                                    null,
     "tTimestampWOTZ"       timestamp without time zone default now()                                    null,
+    "tTimestampPrec"       timestamp(4)                default now()                                    null,
     "tDouble"              double precision            default 0                                        null,
     "tReal"                real                        default 0                                        null,
     "tFloat8"              float8                      default 0                                        null,
@@ -716,37 +717,42 @@ create table atlas_types_sanity
 				},
 				{
 					Name:    "tTime",
-					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "time without time zone"}, Raw: "time without time zone", Null: true},
+					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "time without time zone", Precision: 6}, Raw: "time without time zone", Null: true},
 					Default: &schema.RawExpr{X: "CURRENT_TIME"},
 				},
 				{
 					Name:    "tTimeWTZ",
-					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "time with time zone"}, Raw: "time with time zone", Null: true},
+					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "time with time zone", Precision: 6}, Raw: "time with time zone", Null: true},
 					Default: &schema.RawExpr{X: "CURRENT_TIME"},
 				},
 				{
 					Name:    "tTimeWOTZ",
-					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "time without time zone"}, Raw: "time without time zone", Null: true},
+					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "time without time zone", Precision: 6}, Raw: "time without time zone", Null: true},
 					Default: &schema.RawExpr{X: "CURRENT_TIME"},
 				},
 				{
 					Name:    "tTimestamp",
-					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "timestamp without time zone"}, Raw: "timestamp without time zone", Null: true},
+					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "timestamp without time zone", Precision: 6}, Raw: "timestamp without time zone", Null: true},
 					Default: &schema.RawExpr{X: "now()"},
 				},
 				{
 					Name:    "tTimestampTZ",
-					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "timestamp with time zone"}, Raw: "timestamp with time zone", Null: true},
+					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "timestamp with time zone", Precision: 6}, Raw: "timestamp with time zone", Null: true},
 					Default: &schema.RawExpr{X: "now()"},
 				},
 				{
 					Name:    "tTimestampWTZ",
-					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "timestamp with time zone"}, Raw: "timestamp with time zone", Null: true},
+					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "timestamp with time zone", Precision: 6}, Raw: "timestamp with time zone", Null: true},
 					Default: &schema.RawExpr{X: "now()"},
 				},
 				{
 					Name:    "tTimestampWOTZ",
-					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "timestamp without time zone"}, Raw: "timestamp without time zone", Null: true},
+					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "timestamp without time zone", Precision: 6}, Raw: "timestamp without time zone", Null: true},
+					Default: &schema.RawExpr{X: "now()"},
+				},
+				{
+					Name:    "tTimestampPrec",
+					Type:    &schema.ColumnType{Type: &schema.TimeType{T: "timestamp without time zone", Precision: 4}, Raw: "timestamp without time zone", Null: true},
 					Default: &schema.RawExpr{X: "now()"},
 				},
 				{
diff --git a/sql/postgres/inspect_test.go b/sql/postgres/inspect_test.go
index 641f99be..b76e1063 100644
--- a/sql/postgres/inspect_test.go
+++ b/sql/postgres/inspect_test.go
@@ -58,34 +58,37 @@ func TestDriver_InspectTable(t *testing.T) {
 				m.ExpectQuery(sqltest.Escape(columnsQuery)).
 					WithArgs("public", "users").
 					WillReturnRows(sqltest.Rows(`
- column_name |      data_type      | is_nullable |         column_default          | character_maximum_length | numeric_precision | numeric_scale | character_set_name | collation_name | udt_name | is_identity | identity_start | identity_increment | identity_generation | comment | typtype |  oid  
--------------+---------------------+-------------+---------------------------------+--------------------------+-------------------+---------------+--------------------+----------------+----------+-------------+----------------+--------------------+---------------------+---------+---------+-------
- id          | bigint              | NO          |                                 |                          |                64 |             0 |                    |                | int8     | YES         |      100       |          1         |    BY DEFAULT       |         | b       |    20
- rank        | integer             | YES         |                                 |                          |                32 |             0 |                    |                | int4     | NO          |                |                    |                     | rank    | b       |    23
- c1          | smallint            | NO          |           1000                  |                          |                16 |             0 |                    |                | int2     | NO          |                |                    |                     |         | b       |    21
- c2          | bit                 | NO          |                                 |                        1 |                   |               |                    |                | bit      | NO          |                |                    |                     |         | b       |  1560
- c3          | bit varying         | NO          |                                 |                       10 |                   |               |                    |                | varbit   | NO          |                |                    |                     |         | b       |  1562
- c4          | boolean             | NO          |                                 |                          |                   |               |                    |                | bool     | NO          |                |                    |                     |         | b       |    16
- c5          | bytea               | NO          |                                 |                          |                   |               |                    |                | bytea    | NO          |                |                    |                     |         | b       |    17
- c6          | character           | NO          |                                 |                      100 |                   |               |                    |                | bpchar   | NO          |                |                    |                     |         | b       |  1042
- c7          | character varying   | NO          |                                 |                          |                   |               |                    |                | varchar  | NO          |                |                    |                     |         | b       |  1043
- c8          | cidr                | NO          |                                 |                          |                   |               |                    |                | cidr     | NO          |                |                    |                     |         | b       |   650
- c9          | circle              | NO          |                                 |                          |                   |               |                    |                | circle   | NO          |                |                    |                     |         | b       |   718
- c10         | date                | NO          |                                 |                          |                   |               |                    |                | date     | NO          |                |                    |                     |         | b       |  1082
- c11         | time with time zone | NO          |                                 |                          |                   |               |                    |                | timetz   | NO          |                |                    |                     |         | b       |  1266
- c12         | double precision    | NO          |                                 |                          |                53 |               |                    |                | float8   | NO          |                |                    |                     |         | b       |   701
- c13         | real                | NO          |           random()              |                          |                24 |               |                    |                | float4   | NO          |                |                    |                     |         | b       |   700
- c14         | json                | NO          |           '{}'::json            |                          |                   |               |                    |                | json     | NO          |                |                    |                     |         | b       |   114
- c15         | jsonb               | NO          |           '{}'::jsonb           |                          |                   |               |                    |                | jsonb    | NO          |                |                    |                     |         | b       |  3802
- c16         | money               | NO          |                                 |                          |                   |               |                    |                | money    | NO          |                |                    |                     |         | b       |   790
- c17         | numeric             | NO          |                                 |                          |                   |               |                    |                | numeric  | NO          |                |                    |                     |         | b       |  1700
- c18         | numeric             | NO          |                                 |                          |                 4 |             4 |                    |                | numeric  | NO          |                |                    |                     |         | b       |  1700
- c19         | integer             | NO          | nextval('t1_c19_seq'::regclass) |                          |                32 |             0 |                    |                | int4     | NO          |                |                    |                     |         | b       |    23
- c20         | uuid                | NO          |                                 |                          |                   |               |                    |                | uuid     | NO          |                |                    |                     |         | b       |  2950
- c21         | xml                 | NO          |                                 |                          |                   |               |                    |                | xml      | NO          |                |                    |                     |         | b       |   142
- c22         | ARRAY               | YES         |                                 |                          |                   |               |                    |                | _int4    | NO          |                |                    |                     |         | b       |  1007
- c23         | USER-DEFINED        | YES         |                                 |                          |                   |               |                    |                | ltree    | NO          |                |                    |                     |         | b       | 16535
- c24         | USER-DEFINED        | NO          |                                 |                          |                   |               |                    |                | state    | NO          |                |                    |                     |         | e       | 16774
+ column_name |          data_type          | is_nullable |         column_default          | character_maximum_length | numeric_precision | datetime_precision | numeric_scale | character_set_name | collation_name |  udt_name   | is_identity | identity_start | identity_increment | identity_generation | comment | typtype |  oid  
+-------------+-----------------------------+-------------+---------------------------------+--------------------------+-------------------+--------------------+---------------+--------------------+----------------+-------------+-------------+----------------+--------------------+---------------------+---------+---------+-------
+ id          | bigint                      | NO          |                                 |                          |                64 |                    |             0 |                    |                | int8        | YES         |      100       |          1         |    BY DEFAULT       |         | b       |    20
+ rank        | integer                     | YES         |                                 |                          |                32 |                    |             0 |                    |                | int4        | NO          |                |                    |                     | rank    | b       |    23
+ c1          | smallint                    | NO          |           1000                  |                          |                16 |                    |             0 |                    |                | int2        | NO          |                |                    |                     |         | b       |    21
+ c2          | bit                         | NO          |                                 |                        1 |                   |                    |               |                    |                | bit         | NO          |                |                    |                     |         | b       |  1560
+ c3          | bit varying                 | NO          |                                 |                       10 |                   |                    |               |                    |                | varbit      | NO          |                |                    |                     |         | b       |  1562
+ c4          | boolean                     | NO          |                                 |                          |                   |                    |               |                    |                | bool        | NO          |                |                    |                     |         | b       |    16
+ c5          | bytea                       | NO          |                                 |                          |                   |                    |               |                    |                | bytea       | NO          |                |                    |                     |         | b       |    17
+ c6          | character                   | NO          |                                 |                      100 |                   |                    |               |                    |                | bpchar      | NO          |                |                    |                     |         | b       |  1042
+ c7          | character varying           | NO          |                                 |                          |                   |                    |               |                    |                | varchar     | NO          |                |                    |                     |         | b       |  1043
+ c8          | cidr                        | NO          |                                 |                          |                   |                    |               |                    |                | cidr        | NO          |                |                    |                     |         | b       |   650
+ c9          | circle                      | NO          |                                 |                          |                   |                    |               |                    |                | circle      | NO          |                |                    |                     |         | b       |   718
+ c10         | date                        | NO          |                                 |                          |                   |                    |               |                    |                | date        | NO          |                |                    |                     |         | b       |  1082
+ c11         | time with time zone         | NO          |                                 |                          |                   |                    |               |                    |                | timetz      | NO          |                |                    |                     |         | b       |  1266
+ c12         | double precision            | NO          |                                 |                          |                53 |                    |               |                    |                | float8      | NO          |                |                    |                     |         | b       |   701
+ c13         | real                        | NO          |           random()              |                          |                24 |                    |               |                    |                | float4      | NO          |                |                    |                     |         | b       |   700
+ c14         | json                        | NO          |           '{}'::json            |                          |                   |                    |               |                    |                | json        | NO          |                |                    |                     |         | b       |   114
+ c15         | jsonb                       | NO          |           '{}'::jsonb           |                          |                   |                    |               |                    |                | jsonb       | NO          |                |                    |                     |         | b       |  3802
+ c16         | money                       | NO          |                                 |                          |                   |                    |               |                    |                | money       | NO          |                |                    |                     |         | b       |   790
+ c17         | numeric                     | NO          |                                 |                          |                   |                    |               |                    |                | numeric     | NO          |                |                    |                     |         | b       |  1700
+ c18         | numeric                     | NO          |                                 |                          |                 4 |                    |             4 |                    |                | numeric     | NO          |                |                    |                     |         | b       |  1700
+ c19         | integer                     | NO          | nextval('t1_c19_seq'::regclass) |                          |                32 |                    |             0 |                    |                | int4        | NO          |                |                    |                     |         | b       |    23
+ c20         | uuid                        | NO          |                                 |                          |                   |                    |               |                    |                | uuid        | NO          |                |                    |                     |         | b       |  2950
+ c21         | xml                         | NO          |                                 |                          |                   |                    |               |                    |                | xml         | NO          |                |                    |                     |         | b       |   142
+ c22         | ARRAY                       | YES         |                                 |                          |                   |                    |               |                    |                | _int4       | NO          |                |                    |                     |         | b       |  1007
+ c23         | USER-DEFINED                | YES         |                                 |                          |                   |                    |               |                    |                | ltree       | NO          |                |                    |                     |         | b       | 16535
+ c24         | USER-DEFINED                | NO          |                                 |                          |                   |                    |               |                    |                | state       | NO          |                |                    |                     |         | e       | 16774
+ c25         | timestamp without time zone | NO          |            now()                |                          |                   |                  4 |               |                    |                | timestamp   | NO          |                |                    |                     |         | b       |  1114
+ c26         | timestamp with time zone    | NO          |                                 |                          |                   |                  6 |               |                    |                | timestamptz | NO          |                |                    |                     |         | b       |  1184
+ c27         | time without time zone      | NO          |                                 |                          |                   |                  6 |               |                    |                | time        | NO          |                |                    |                     |         | b       |  1266
 `))
 				m.ExpectQuery(sqltest.Escape(`SELECT enumtypid, enumlabel FROM pg_enum WHERE enumtypid IN ($1)`)).
 					WithArgs(16774).
@@ -129,6 +132,9 @@ func TestDriver_InspectTable(t *testing.T) {
 					{Name: "c22", Type: &schema.ColumnType{Raw: "ARRAY", Null: true, Type: &ArrayType{T: "int4[]"}}},
 					{Name: "c23", Type: &schema.ColumnType{Raw: "USER-DEFINED", Null: true, Type: &UserDefinedType{T: "ltree"}}},
 					{Name: "c24", Type: &schema.ColumnType{Raw: "state", Type: &schema.EnumType{T: "state", Values: []string{"on", "off"}}}},
+					{Name: "c25", Type: &schema.ColumnType{Raw: "timestamp without time zone", Type: &schema.TimeType{T: "timestamp without time zone", Precision: 4}}, Default: &schema.RawExpr{X: "now()"}},
+					{Name: "c26", Type: &schema.ColumnType{Raw: "timestamp with time zone", Type: &schema.TimeType{T: "timestamp with time zone", Precision: 6}}},
+					{Name: "c27", Type: &schema.ColumnType{Raw: "time without time zone", Type: &schema.TimeType{T: "time without time zone", Precision: 6}}},
 				}, t.Columns)
 			},
 		},
@@ -140,10 +146,10 @@ func TestDriver_InspectTable(t *testing.T) {
 				m.ExpectQuery(sqltest.Escape(columnsQuery)).
 					WithArgs("public", "users").
 					WillReturnRows(sqltest.Rows(`
- column_name |      data_type      | is_nullable |         column_default          | character_maximum_length | numeric_precision | numeric_scale | character_set_name | collation_name | udt_name | is_identity | identity_start | identity_increment | identity_generation | comment | typtype |  oid
--------------+---------------------+-------------+---------------------------------+--------------------------+-------------------+---------------+--------------------+----------------+----------+-------------+----------------+--------------------+---------------------+---------+---------+-------
- id          | bigint              | NO          |                                 |                          |                64 |             0 |                    |                | int8     | NO          |                |                    |                     |         | b       |    20
- c1          | smallint            | NO          |                                 |                          |                16 |             0 |                    |                | int2     | NO          |                |                    |                     |         | b       |    21
+ column_name |      data_type      | is_nullable |         column_default          | character_maximum_length | numeric_precision | datetime_precision | numeric_scale | character_set_name | collation_name | udt_name | is_identity | identity_start | identity_increment | identity_generation | comment | typtype |  oid
+-------------+---------------------+-------------+---------------------------------+--------------------------+-------------------+--------------------+---------------+--------------------+----------------+----------+-------------+----------------+--------------------+---------------------+---------+---------+-------
+ id          | bigint              | NO          |                                 |                          |                64 |                    |             0 |                    |                | int8     | NO          |                |                    |                     |         | b       |    20
+ c1          | smallint            | NO          |                                 |                          |                16 |                    |             0 |                    |                | int2     | NO          |                |                    |                     |         | b       |    21
 `))
 				m.ExpectQuery(sqltest.Escape(indexesQuery)).
 					WithArgs("public", "users").
@@ -197,11 +203,11 @@ func TestDriver_InspectTable(t *testing.T) {
 					WithArgs("public", "users").
 					WithArgs("public", "users").
 					WillReturnRows(sqltest.Rows(`
- column_name |      data_type      | is_nullable |         column_default          | character_maximum_length | numeric_precision | numeric_scale | character_set_name | collation_name | udt_name | is_identity | identity_start | identity_increment | identity_generation | comment | typtype |  oid
--------------+---------------------+-------------+---------------------------------+--------------------------+-------------------+---------------+--------------------+----------------+----------+-------------+----------------+--------------------+---------------------+---------+---------+-------
- id          | integer             | NO          |                                 |                          |                32 |             0 |                    |                | int      | NO          |                |                    |                     |         | b       |    20
- oid         | integer             | NO          |                                 |                          |                32 |             0 |                    |                | int      | NO          |                |                    |                     |         | b       |    21
- uid         | integer             | NO          |                                 |                          |                32 |             0 |                    |                | int      | NO          |                |                    |                     |         | b       |    21
+ column_name |      data_type      | is_nullable |         column_default          | character_maximum_length | numeric_precision | datetime_precision | numeric_scale | character_set_name | collation_name | udt_name | is_identity | identity_start | identity_increment | identity_generation | comment | typtype |  oid
+-------------+---------------------+-------------+---------------------------------+--------------------------+-------------------+--------------------+---------------+--------------------+----------------+----------+-------------+----------------+--------------------+---------------------+---------+---------+-------
+ id          | integer             | NO          |                                 |                          |                32 |                    |             0 |                    |                | int      | NO          |                |                    |                     |         | b       |    20
+ oid         | integer             | NO          |                                 |                          |                32 |                    |             0 |                    |                | int      | NO          |                |                    |                     |         | b       |    21
+ uid         | integer             | NO          |                                 |                          |                32 |                    |             0 |                    |                | int      | NO          |                |                    |                     |         | b       |    21
 `))
 				m.noIndexes()
 				m.ExpectQuery(sqltest.Escape(fksQuery)).
@@ -247,11 +253,11 @@ func TestDriver_InspectTable(t *testing.T) {
 					WithArgs("public", "users").
 					WithArgs("public", "users").
 					WillReturnRows(sqltest.Rows(`
- column_name | data_type | is_nullable | column_default | character_maximum_length | numeric_precision | numeric_scale | character_set_name | collation_name | udt_name | is_identity | identity_start | identity_increment | identity_generation | comment | typtype | oid
--------------+-----------+-------------+----------------+--------------------------+-------------------+---------------+--------------------+----------------+----------+-------------+----------------+--------------------+---------------------+---------+---------+-----
- c1          | integer   | NO          |                |                          |                32 |             0 |                    |                | int4     | NO          |                |                    |                     |         | b       |  23
- c2          | integer   | NO          |                |                          |                32 |             0 |                    |                | int4     | NO          |                |                    |                     |         | b       |  23
- c3          | integer   | NO          |                |                          |                32 |             0 |                    |                | int4     | NO          |                |                    |                     |         | b       |  23
+ column_name | data_type | is_nullable | column_default | character_maximum_length | numeric_precision | datetime_precision | numeric_scale | character_set_name | collation_name | udt_name | is_identity | identity_start | identity_increment | identity_generation | comment | typtype | oid
+-------------+-----------+-------------+----------------+--------------------------+-------------------+--------------------+---------------+--------------------+----------------+----------+-------------+----------------+--------------------+---------------------+---------+---------+-----
+ c1          | integer   | NO          |                |                          |                32 |                    |             0 |                    |                | int4     | NO          |                |                    |                     |         | b       |  23
+ c2          | integer   | NO          |                |                          |                32 |                    |             0 |                    |                | int4     | NO          |                |                    |                     |         | b       |  23
+ c3          | integer   | NO          |                |                          |                32 |                    |             0 |                    |                | int4     | NO          |                |                    |                     |         | b       |  23
 `))
 				m.noIndexes()
 				m.noFKs()
diff --git a/sql/postgres/sqlspec_test.go b/sql/postgres/sqlspec_test.go
index 694af026..65c9f4e8 100644
--- a/sql/postgres/sqlspec_test.go
+++ b/sql/postgres/sqlspec_test.go
@@ -232,7 +232,7 @@ enum "account_type" {
 }
 
 func TestTypes(t *testing.T) {
-	// TODO(rotemtam): enum, timestamptz, interval
+	// TODO(rotemtam) interval
 	for _, tt := range []struct {
 		typeExpr string
 		expected schema.Type
@@ -366,6 +366,10 @@ func TestTypes(t *testing.T) {
 			typeExpr: "timestamp",
 			expected: &schema.TimeType{T: TypeTimestamp},
 		},
+		{
+			typeExpr: "timestamptz",
+			expected: &schema.TimeType{T: TypeTimestampTZ},
+		},
 		{
 			typeExpr: "timestamp_with_time_zone",
 			expected: &schema.TimeType{T: TypeTimestampWTZ},