Repository: schemahero/schemahero
Pull request #288 (2020-10-10 14:30:07)

Add support for postgres triggers
Add support for triggers to postgres (https://www.postgresql.org/docs/9.1/sql-createtrigger.html)

The common structs have been diverging too much with conditional logic, and mysql and postgres are starting to get into engine-specific features. Adding trigger support makes this more obvious.



Patch:
diff --git a/Makefile b/Makefile
index b47dbda5..963bde1a 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@ endef
 export GO111MODULE=on
 # export GOPROXY=https://proxy.golang.org
 
-all: generate fmt vet manifests bin/kubectl-schemahero manager
+all: generate fmt vet manifests bin/kubectl-schemahero manager test
 
 .PHONY: clean-and-tidy
 clean-and-tidy:
diff --git a/config/crds/v1/schemas.schemahero.io_tables.yaml b/config/crds/v1/schemas.schemahero.io_tables.yaml
index 7ae14595..a3bbf5a1 100644
--- a/config/crds/v1/schemas.schemahero.io_tables.yaml
+++ b/config/crds/v1/schemas.schemahero.io_tables.yaml
@@ -90,9 +90,13 @@ spec:
                           comment:
                             type: string
                           compaction:
-                            type: string
+                            additionalProperties:
+                              type: string
+                            type: object
                           compression:
-                            type: string
+                            additionalProperties:
+                              type: string
+                            type: object
                           crcCheckChance:
                             type: string
                           dcLocalReadRepairChance:
@@ -186,6 +190,34 @@ spec:
                         type: array
                       isDeleted:
                         type: boolean
+                      json:triggers:
+                        items:
+                          properties:
+                            arguments:
+                              items:
+                                type: string
+                              type: array
+                            condition:
+                              type: string
+                            constraintTrigger:
+                              type: boolean
+                            events:
+                              items:
+                                type: string
+                              type: array
+                            executeProcedure:
+                              type: string
+                            forEachRun:
+                              type: boolean
+                            forEachStatement:
+                              type: boolean
+                            name:
+                              type: string
+                          required:
+                          - events
+                          - executeProcedure
+                          type: object
+                        type: array
                       primaryKey:
                         items:
                           type: string
@@ -350,6 +382,34 @@ spec:
                         type: array
                       isDeleted:
                         type: boolean
+                      json:triggers:
+                        items:
+                          properties:
+                            arguments:
+                              items:
+                                type: string
+                              type: array
+                            condition:
+                              type: string
+                            constraintTrigger:
+                              type: boolean
+                            events:
+                              items:
+                                type: string
+                              type: array
+                            executeProcedure:
+                              type: string
+                            forEachRun:
+                              type: boolean
+                            forEachStatement:
+                              type: boolean
+                            name:
+                              type: string
+                          required:
+                          - events
+                          - executeProcedure
+                          type: object
+                        type: array
                       primaryKey:
                         items:
                           type: string
diff --git a/config/crds/v1beta1/schemas.schemahero.io_tables.yaml b/config/crds/v1beta1/schemas.schemahero.io_tables.yaml
index dd723146..67f1c01d 100644
--- a/config/crds/v1beta1/schemas.schemahero.io_tables.yaml
+++ b/config/crds/v1beta1/schemas.schemahero.io_tables.yaml
@@ -88,9 +88,13 @@ spec:
                         comment:
                           type: string
                         compaction:
-                          type: string
+                          additionalProperties:
+                            type: string
+                          type: object
                         compression:
-                          type: string
+                          additionalProperties:
+                            type: string
+                          type: object
                         crcCheckChance:
                           type: string
                         dcLocalReadRepairChance:
@@ -184,6 +188,34 @@ spec:
                       type: array
                     isDeleted:
                       type: boolean
+                    json:triggers:
+                      items:
+                        properties:
+                          arguments:
+                            items:
+                              type: string
+                            type: array
+                          condition:
+                            type: string
+                          constraintTrigger:
+                            type: boolean
+                          events:
+                            items:
+                              type: string
+                            type: array
+                          executeProcedure:
+                            type: string
+                          forEachRun:
+                            type: boolean
+                          forEachStatement:
+                            type: boolean
+                          name:
+                            type: string
+                        required:
+                        - events
+                        - executeProcedure
+                        type: object
+                      type: array
                     primaryKey:
                       items:
                         type: string
@@ -348,6 +380,34 @@ spec:
                       type: array
                     isDeleted:
                       type: boolean
+                    json:triggers:
+                      items:
+                        properties:
+                          arguments:
+                            items:
+                              type: string
+                            type: array
+                          condition:
+                            type: string
+                          constraintTrigger:
+                            type: boolean
+                          events:
+                            items:
+                              type: string
+                            type: array
+                          executeProcedure:
+                            type: string
+                          forEachRun:
+                            type: boolean
+                          forEachStatement:
+                            type: boolean
+                          name:
+                            type: string
+                        required:
+                        - events
+                        - executeProcedure
+                        type: object
+                      type: array
                     primaryKey:
                       items:
                         type: string
diff --git a/go.mod b/go.mod
index 2b45f077..7f829101 100644
--- a/go.mod
+++ b/go.mod
@@ -15,6 +15,7 @@ require (
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/common v0.4.1
 	github.com/spf13/cobra v0.0.5
+	github.com/spf13/pflag v1.0.5
 	github.com/spf13/viper v1.4.0
 	github.com/stretchr/testify v1.5.1
 	github.com/xo/dburl v0.0.0-20200124232849-e9ec94f52bc3
diff --git a/go.sum b/go.sum
index 624cd9ab..70127261 100644
--- a/go.sum
+++ b/go.sum
@@ -3,12 +3,17 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
 cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
 cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
+github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
 github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
 github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
+github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
 github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
 github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
 github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
 github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
+github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
 github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -66,6 +71,7 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
 github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
@@ -201,6 +207,7 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC
 github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
 github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
+github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o=
 github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
diff --git a/pkg/apis/databases/v1alpha4/vault.go b/pkg/apis/databases/v1alpha4/vault.go
index db946ba9..1201f1b8 100644
--- a/pkg/apis/databases/v1alpha4/vault.go
+++ b/pkg/apis/databases/v1alpha4/vault.go
@@ -108,6 +108,8 @@ postgres://{{ .Data.username }}:{{ .Data.password }}@postgres:5432/%s{{- end }}`
 		annotations["vault.hashicorp.com/agent-inject-template-schemaherouri"] = t
 	case "cassandra":
 		return nil, errors.New("not implemented")
+	default:
+		return nil, fmt.Errorf("unknown database driver: %q", t)
 	}
 
 	annotations["vault.hashicorp.com/agent-inject"] = "true"
diff --git a/pkg/apis/schemas/v1alpha4/mysql.go b/pkg/apis/schemas/v1alpha4/mysql.go
index 5bb8ce24..18f61daa 100644
--- a/pkg/apis/schemas/v1alpha4/mysql.go
+++ b/pkg/apis/schemas/v1alpha4/mysql.go
@@ -16,22 +16,49 @@ limitations under the License.
 
 package v1alpha4
 
-type MysqlSQLTableColumn struct {
-	Name        string                     `json:"name" yaml:"name"`
-	Type        string                     `json:"type" yaml:"type"`
-	Constraints *SQLTableColumnConstraints `json:"constraints,omitempty" yaml:"constraints,omitempty"`
-	Attributes  *SQLTableColumnAttributes  `json:"attributes,omitempty" yaml:"attributes,omitempty"`
-	Default     *string                    `json:"default,omitempty" yaml:"default,omitempty"`
-	Charset     string                     `json:"charset,omitempty" yaml:"charset,omitempty"`
-	Collation   string                     `json:"collation,omitempty" yaml:"collation,omitempty"`
+type MysqlTableColumnConstraints struct {
+	NotNull *bool `json:"notNull,omitempty" yaml:"notNull,omitempty"`
 }
 
-type MysqlSQLTableSchema struct {
-	PrimaryKey     []string               `json:"primaryKey,omitempty" yaml:"primaryKey,omitempty"`
-	ForeignKeys    []*SQLTableForeignKey  `json:"foreignKeys,omitempty" yaml:"foreignKeys,omitempty"`
-	Indexes        []*SQLTableIndex       `json:"indexes,omitempty" yaml:"indexes,omitempty"`
-	Columns        []*MysqlSQLTableColumn `json:"columns,omitempty" yaml:"columns,omitempty"`
-	IsDeleted      bool                   `json:"isDeleted,omitempty" yaml:"isDeleted,omitempty"`
-	DefaultCharset string                 `json:"defaultCharset,omitempty" yaml:"defaultCharset,omitempty"`
-	Collation      string                 `json:"collation,omitempty" yaml:"collation,omitempty"`
+type MysqlTableColumnAttributes struct {
+	AutoIncrement *bool `json:"autoIncrement,omitempty" yaml:"autoIncrement,omitempty"`
+}
+
+type MysqlTableForeignKeyReferences struct {
+	Table   string   `json:"table"`
+	Columns []string `json:"columns"`
+}
+
+type MysqlTableForeignKey struct {
+	Columns    []string                       `json:"columns" yaml:"columns"`
+	References MysqlTableForeignKeyReferences `json:"references" yaml:"references"`
+	OnDelete   string                         `json:"onDelete,omitempty" yaml:"onDelete,omitempty"`
+	Name       string                         `json:"name,omitempty" yaml:"name,omitempty"`
+}
+
+type MysqlTableIndex struct {
+	Columns  []string `json:"columns" yaml:"columns"`
+	Name     string   `json:"name,omitempty" yaml:"name,omitempty"`
+	IsUnique bool     `json:"isUnique,omitempty" yaml:"isUnique,omitempty"`
+	Type     string   `json:"type,omitempty" yaml:"type,omitempty"`
+}
+
+type MysqlTableColumn struct {
+	Name        string                       `json:"name" yaml:"name"`
+	Type        string                       `json:"type" yaml:"type"`
+	Constraints *MysqlTableColumnConstraints `json:"constraints,omitempty" yaml:"constraints,omitempty"`
+	Attributes  *MysqlTableColumnAttributes  `json:"attributes,omitempty" yaml:"attributes,omitempty"`
+	Default     *string                      `json:"default,omitempty" yaml:"default,omitempty"`
+	Charset     string                       `json:"charset,omitempty" yaml:"charset,omitempty"`
+	Collation   string                       `json:"collation,omitempty" yaml:"collation,omitempty"`
+}
+
+type MysqlTableSchema struct {
+	PrimaryKey     []string                `json:"primaryKey,omitempty" yaml:"primaryKey,omitempty"`
+	ForeignKeys    []*MysqlTableForeignKey `json:"foreignKeys,omitempty" yaml:"foreignKeys,omitempty"`
+	Indexes        []*MysqlTableIndex      `json:"indexes,omitempty" yaml:"indexes,omitempty"`
+	Columns        []*MysqlTableColumn     `json:"columns,omitempty" yaml:"columns,omitempty"`
+	IsDeleted      bool                    `json:"isDeleted,omitempty" yaml:"isDeleted,omitempty"`
+	DefaultCharset string                  `json:"defaultCharset,omitempty" yaml:"defaultCharset,omitempty"`
+	Collation      string                  `json:"collation,omitempty" yaml:"collation,omitempty"`
 }
diff --git a/pkg/apis/schemas/v1alpha4/postgresql.go b/pkg/apis/schemas/v1alpha4/postgresql.go
new file mode 100644
index 00000000..17725227
--- /dev/null
+++ b/pkg/apis/schemas/v1alpha4/postgresql.go
@@ -0,0 +1,72 @@
+/*
+Copyright 2019 Replicated, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha4
+
+type PostgresqlTableTrigger struct {
+	Name              string   `json:"name,omitempty" yaml:"name,omitempty"`
+	ConstraintTrigger *bool    `json:"constraintTrigger,omitempty" yaml:"constraintTrigger,omitempty"`
+	Events            []string `json:"events" yaml:"events"`
+	ForEachStatement  *bool    `json:"forEachStatement,omitempty" yaml:"forEachStatement,omitempty"`
+	ForEachRow        *bool    `json:"forEachRun,omitempty" yaml:"forEachRow,omitempty"`
+	Condition         *string  `json:"condition,omitempty" yaml:"condition,omitempty"`
+	ExecuteProcedure  string   `json:"executeProcedure" yaml:"executeProcedure"`
+	Arguments         []string `json:"arguments,omitempty" yaml:"arguments,omitempty"`
+}
+
+type PostgresqlTableForeignKeyReferences struct {
+	Table   string   `json:"table"`
+	Columns []string `json:"columns"`
+}
+
+type PostgresqlTableForeignKey struct {
+	Columns    []string                            `json:"columns" yaml:"columns"`
+	References PostgresqlTableForeignKeyReferences `json:"references" yaml:"references"`
+	OnDelete   string                              `json:"onDelete,omitempty" yaml:"onDelete,omitempty"`
+	Name       string                              `json:"name,omitempty" yaml:"name,omitempty"`
+}
+
+type PostgresqlTableIndex struct {
+	Columns  []string `json:"columns" yaml:"columns"`
+	Name     string   `json:"name,omitempty" yaml:"name,omitempty"`
+	IsUnique bool     `json:"isUnique,omitempty" yaml:"isUnique,omitempty"`
+	Type     string   `json:"type,omitempty" yaml:"type,omitempty"`
+}
+
+type PostgresqlTableColumnConstraints struct {
+	NotNull *bool `json:"notNull,omitempty" yaml:"notNull,omitempty"`
+}
+
+type PostgresqlTableColumnAttributes struct {
+	AutoIncrement *bool `json:"autoIncrement,omitempty" yaml:"autoIncrement,omitempty"`
+}
+
+type PostgresqlTableColumn struct {
+	Name        string                            `json:"name" yaml:"name"`
+	Type        string                            `json:"type" yaml:"type"`
+	Constraints *PostgresqlTableColumnConstraints `json:"constraints,omitempty" yaml:"constraints,omitempty"`
+	Attributes  *PostgresqlTableColumnAttributes  `json:"attributes,omitempty" yaml:"attributes,omitempty"`
+	Default     *string                           `json:"default,omitempty" yaml:"default,omitempty"`
+}
+
+type PostgresqlTableSchema struct {
+	PrimaryKey  []string                     `json:"primaryKey,omitempty" yaml:"primaryKey,omitempty"`
+	ForeignKeys []*PostgresqlTableForeignKey `json:"foreignKeys,omitempty" yaml:"foreignKeys,omitempty"`
+	Indexes     []*PostgresqlTableIndex      `json:"indexes,omitempty" yaml:"indexes,omitempty"`
+	Columns     []*PostgresqlTableColumn     `json:"columns,omitempty" yaml:"columns,omitempty"`
+	IsDeleted   bool                         `json:"isDeleted,omitempty" yaml:"isDeleted,omitempty"`
+	Triggers    []*PostgresqlTableTrigger    `json:"json:triggers,omitempty" yaml:"triggers,omitempty"`
+}
diff --git a/pkg/apis/schemas/v1alpha4/sql.go b/pkg/apis/schemas/v1alpha4/sql.go
deleted file mode 100644
index 6f00a398..00000000
--- a/pkg/apis/schemas/v1alpha4/sql.go
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1alpha4
-
-type SQLTableForeignKeyReferences struct {
-	Table   string   `json:"table"`
-	Columns []string `json:"columns"`
-}
-
-type SQLTableForeignKey struct {
-	Columns    []string                     `json:"columns" yaml:"columns"`
-	References SQLTableForeignKeyReferences `json:"references" yaml:"references"`
-	OnDelete   string                       `json:"onDelete,omitempty" yaml:"onDelete,omitempty"`
-	Name       string                       `json:"name,omitempty" yaml:"name,omitempty"`
-}
-
-type SQLTableIndex struct {
-	Columns  []string `json:"columns" yaml:"columns"`
-	Name     string   `json:"name,omitempty" yaml:"name,omitempty"`
-	IsUnique bool     `json:"isUnique,omitempty" yaml:"isUnique,omitempty"`
-	Type     string   `json:"type,omitempty" yaml:"type,omitempty"`
-}
-
-type SQLTableColumnConstraints struct {
-	NotNull *bool `json:"notNull,omitempty" yaml:"notNull,omitempty"`
-}
-
-type SQLTableColumnAttributes struct {
-	AutoIncrement *bool `json:"autoIncrement,omitempty" yaml:"autoIncrement,omitempty"`
-}
-
-type SQLTableColumn struct {
-	Name        string                     `json:"name" yaml:"name"`
-	Type        string                     `json:"type" yaml:"type"`
-	Constraints *SQLTableColumnConstraints `json:"constraints,omitempty" yaml:"constraints,omitempty"`
-	Attributes  *SQLTableColumnAttributes  `json:"attributes,omitempty" yaml:"attributes,omitempty"`
-	Default     *string                    `json:"default,omitempty" yaml:"default,omitempty"`
-}
-
-type SQLTableSchema struct {
-	PrimaryKey  []string              `json:"primaryKey,omitempty" yaml:"primaryKey,omitempty"`
-	ForeignKeys []*SQLTableForeignKey `json:"foreignKeys,omitempty" yaml:"foreignKeys,omitempty"`
-	Indexes     []*SQLTableIndex      `json:"indexes,omitempty" yaml:"indexes,omitempty"`
-	Columns     []*SQLTableColumn     `json:"columns,omitempty" yaml:"columns,omitempty"`
-	IsDeleted   bool                  `json:"isDeleted,omitempty" yaml:"isDeleted,omitempty"`
-}
diff --git a/pkg/apis/schemas/v1alpha4/table_types.go b/pkg/apis/schemas/v1alpha4/table_types.go
index fccebda0..81ead9b9 100644
--- a/pkg/apis/schemas/v1alpha4/table_types.go
+++ b/pkg/apis/schemas/v1alpha4/table_types.go
@@ -26,10 +26,10 @@ import (
 )
 
 type TableSchema struct {
-	Postgres    *SQLTableSchema       `json:"postgres,omitempty" yaml:"postgres,omitempty"`
-	Mysql       *MysqlSQLTableSchema  `json:"mysql,omitempty" yaml:"mysql,omitempty"`
-	CockroachDB *SQLTableSchema       `json:"cockroachdb,omitempty" yaml:"cockroachdb,omitempty"`
-	Cassandra   *CassandraTableSchema `json:"cassandra,omitempty" yaml:"cassandra,omitempty"`
+	Postgres    *PostgresqlTableSchema `json:"postgres,omitempty" yaml:"postgres,omitempty"`
+	Mysql       *MysqlTableSchema      `json:"mysql,omitempty" yaml:"mysql,omitempty"`
+	CockroachDB *PostgresqlTableSchema `json:"cockroachdb,omitempty" yaml:"cockroachdb,omitempty"`
+	Cassandra   *CassandraTableSchema  `json:"cassandra,omitempty" yaml:"cassandra,omitempty"`
 }
 
 // TableSpec defines the desired state of Table
diff --git a/pkg/apis/schemas/v1alpha4/zz_generated.deepcopy.go b/pkg/apis/schemas/v1alpha4/zz_generated.deepcopy.go
index b3e72dfc..fc718ed6 100644
--- a/pkg/apis/schemas/v1alpha4/zz_generated.deepcopy.go
+++ b/pkg/apis/schemas/v1alpha4/zz_generated.deepcopy.go
@@ -115,6 +115,20 @@ func (in *CassandraTableProperties) DeepCopyInto(out *CassandraTableProperties)
 			(*out)[key] = val
 		}
 	}
+	if in.Compaction != nil {
+		in, out := &in.Compaction, &out.Compaction
+		*out = make(map[string]string, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	if in.Compression != nil {
+		in, out := &in.Compression, &out.Compression
+		*out = make(map[string]string, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
 	if in.DefaultTTL != nil {
 		in, out := &in.DefaultTTL, &out.DefaultTTL
 		*out = new(int)
@@ -403,16 +417,16 @@ func (in *MigrationStatus) DeepCopy() *MigrationStatus {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MysqlSQLTableColumn) DeepCopyInto(out *MysqlSQLTableColumn) {
+func (in *MysqlTableColumn) DeepCopyInto(out *MysqlTableColumn) {
 	*out = *in
 	if in.Constraints != nil {
 		in, out := &in.Constraints, &out.Constraints
-		*out = new(SQLTableColumnConstraints)
+		*out = new(MysqlTableColumnConstraints)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Attributes != nil {
 		in, out := &in.Attributes, &out.Attributes
-		*out = new(SQLTableColumnAttributes)
+		*out = new(MysqlTableColumnAttributes)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Default != nil {
@@ -422,18 +436,119 @@ func (in *MysqlSQLTableColumn) DeepCopyInto(out *MysqlSQLTableColumn) {
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MysqlSQLTableColumn.
-func (in *MysqlSQLTableColumn) DeepCopy() *MysqlSQLTableColumn {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MysqlTableColumn.
+func (in *MysqlTableColumn) DeepCopy() *MysqlTableColumn {
+	if in == nil {
+		return nil
+	}
+	out := new(MysqlTableColumn)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MysqlTableColumnAttributes) DeepCopyInto(out *MysqlTableColumnAttributes) {
+	*out = *in
+	if in.AutoIncrement != nil {
+		in, out := &in.AutoIncrement, &out.AutoIncrement
+		*out = new(bool)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MysqlTableColumnAttributes.
+func (in *MysqlTableColumnAttributes) DeepCopy() *MysqlTableColumnAttributes {
+	if in == nil {
+		return nil
+	}
+	out := new(MysqlTableColumnAttributes)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MysqlTableColumnConstraints) DeepCopyInto(out *MysqlTableColumnConstraints) {
+	*out = *in
+	if in.NotNull != nil {
+		in, out := &in.NotNull, &out.NotNull
+		*out = new(bool)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MysqlTableColumnConstraints.
+func (in *MysqlTableColumnConstraints) DeepCopy() *MysqlTableColumnConstraints {
+	if in == nil {
+		return nil
+	}
+	out := new(MysqlTableColumnConstraints)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MysqlTableForeignKey) DeepCopyInto(out *MysqlTableForeignKey) {
+	*out = *in
+	if in.Columns != nil {
+		in, out := &in.Columns, &out.Columns
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	in.References.DeepCopyInto(&out.References)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MysqlTableForeignKey.
+func (in *MysqlTableForeignKey) DeepCopy() *MysqlTableForeignKey {
 	if in == nil {
 		return nil
 	}
-	out := new(MysqlSQLTableColumn)
+	out := new(MysqlTableForeignKey)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MysqlSQLTableSchema) DeepCopyInto(out *MysqlSQLTableSchema) {
+func (in *MysqlTableForeignKeyReferences) DeepCopyInto(out *MysqlTableForeignKeyReferences) {
+	*out = *in
+	if in.Columns != nil {
+		in, out := &in.Columns, &out.Columns
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MysqlTableForeignKeyReferences.
+func (in *MysqlTableForeignKeyReferences) DeepCopy() *MysqlTableForeignKeyReferences {
+	if in == nil {
+		return nil
+	}
+	out := new(MysqlTableForeignKeyReferences)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MysqlTableIndex) DeepCopyInto(out *MysqlTableIndex) {
+	*out = *in
+	if in.Columns != nil {
+		in, out := &in.Columns, &out.Columns
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MysqlTableIndex.
+func (in *MysqlTableIndex) DeepCopy() *MysqlTableIndex {
+	if in == nil {
+		return nil
+	}
+	out := new(MysqlTableIndex)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MysqlTableSchema) DeepCopyInto(out *MysqlTableSchema) {
 	*out = *in
 	if in.PrimaryKey != nil {
 		in, out := &in.PrimaryKey, &out.PrimaryKey
@@ -442,60 +557,60 @@ func (in *MysqlSQLTableSchema) DeepCopyInto(out *MysqlSQLTableSchema) {
 	}
 	if in.ForeignKeys != nil {
 		in, out := &in.ForeignKeys, &out.ForeignKeys
-		*out = make([]*SQLTableForeignKey, len(*in))
+		*out = make([]*MysqlTableForeignKey, len(*in))
 		for i := range *in {
 			if (*in)[i] != nil {
 				in, out := &(*in)[i], &(*out)[i]
-				*out = new(SQLTableForeignKey)
+				*out = new(MysqlTableForeignKey)
 				(*in).DeepCopyInto(*out)
 			}
 		}
 	}
 	if in.Indexes != nil {
 		in, out := &in.Indexes, &out.Indexes
-		*out = make([]*SQLTableIndex, len(*in))
+		*out = make([]*MysqlTableIndex, len(*in))
 		for i := range *in {
 			if (*in)[i] != nil {
 				in, out := &(*in)[i], &(*out)[i]
-				*out = new(SQLTableIndex)
+				*out = new(MysqlTableIndex)
 				(*in).DeepCopyInto(*out)
 			}
 		}
 	}
 	if in.Columns != nil {
 		in, out := &in.Columns, &out.Columns
-		*out = make([]*MysqlSQLTableColumn, len(*in))
+		*out = make([]*MysqlTableColumn, len(*in))
 		for i := range *in {
 			if (*in)[i] != nil {
 				in, out := &(*in)[i], &(*out)[i]
-				*out = new(MysqlSQLTableColumn)
+				*out = new(MysqlTableColumn)
 				(*in).DeepCopyInto(*out)
 			}
 		}
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MysqlSQLTableSchema.
-func (in *MysqlSQLTableSchema) DeepCopy() *MysqlSQLTableSchema {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MysqlTableSchema.
+func (in *MysqlTableSchema) DeepCopy() *MysqlTableSchema {
 	if in == nil {
 		return nil
 	}
-	out := new(MysqlSQLTableSchema)
+	out := new(MysqlTableSchema)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SQLTableColumn) DeepCopyInto(out *SQLTableColumn) {
+func (in *PostgresqlTableColumn) DeepCopyInto(out *PostgresqlTableColumn) {
 	*out = *in
 	if in.Constraints != nil {
 		in, out := &in.Constraints, &out.Constraints
-		*out = new(SQLTableColumnConstraints)
+		*out = new(PostgresqlTableColumnConstraints)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Attributes != nil {
 		in, out := &in.Attributes, &out.Attributes
-		*out = new(SQLTableColumnAttributes)
+		*out = new(PostgresqlTableColumnAttributes)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Default != nil {
@@ -505,18 +620,18 @@ func (in *SQLTableColumn) DeepCopyInto(out *SQLTableColumn) {
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLTableColumn.
-func (in *SQLTableColumn) DeepCopy() *SQLTableColumn {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgresqlTableColumn.
+func (in *PostgresqlTableColumn) DeepCopy() *PostgresqlTableColumn {
 	if in == nil {
 		return nil
 	}
-	out := new(SQLTableColumn)
+	out := new(PostgresqlTableColumn)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SQLTableColumnAttributes) DeepCopyInto(out *SQLTableColumnAttributes) {
+func (in *PostgresqlTableColumnAttributes) DeepCopyInto(out *PostgresqlTableColumnAttributes) {
 	*out = *in
 	if in.AutoIncrement != nil {
 		in, out := &in.AutoIncrement, &out.AutoIncrement
@@ -525,18 +640,18 @@ func (in *SQLTableColumnAttributes) DeepCopyInto(out *SQLTableColumnAttributes)
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLTableColumnAttributes.
-func (in *SQLTableColumnAttributes) DeepCopy() *SQLTableColumnAttributes {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgresqlTableColumnAttributes.
+func (in *PostgresqlTableColumnAttributes) DeepCopy() *PostgresqlTableColumnAttributes {
 	if in == nil {
 		return nil
 	}
-	out := new(SQLTableColumnAttributes)
+	out := new(PostgresqlTableColumnAttributes)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SQLTableColumnConstraints) DeepCopyInto(out *SQLTableColumnConstraints) {
+func (in *PostgresqlTableColumnConstraints) DeepCopyInto(out *PostgresqlTableColumnConstraints) {
 	*out = *in
 	if in.NotNull != nil {
 		in, out := &in.NotNull, &out.NotNull
@@ -545,18 +660,18 @@ func (in *SQLTableColumnConstraints) DeepCopyInto(out *SQLTableColumnConstraints
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLTableColumnConstraints.
-func (in *SQLTableColumnConstraints) DeepCopy() *SQLTableColumnConstraints {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgresqlTableColumnConstraints.
+func (in *PostgresqlTableColumnConstraints) DeepCopy() *PostgresqlTableColumnConstraints {
 	if in == nil {
 		return nil
 	}
-	out := new(SQLTableColumnConstraints)
+	out := new(PostgresqlTableColumnConstraints)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SQLTableForeignKey) DeepCopyInto(out *SQLTableForeignKey) {
+func (in *PostgresqlTableForeignKey) DeepCopyInto(out *PostgresqlTableForeignKey) {
 	*out = *in
 	if in.Columns != nil {
 		in, out := &in.Columns, &out.Columns
@@ -566,18 +681,18 @@ func (in *SQLTableForeignKey) DeepCopyInto(out *SQLTableForeignKey) {
 	in.References.DeepCopyInto(&out.References)
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLTableForeignKey.
-func (in *SQLTableForeignKey) DeepCopy() *SQLTableForeignKey {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgresqlTableForeignKey.
+func (in *PostgresqlTableForeignKey) DeepCopy() *PostgresqlTableForeignKey {
 	if in == nil {
 		return nil
 	}
-	out := new(SQLTableForeignKey)
+	out := new(PostgresqlTableForeignKey)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SQLTableForeignKeyReferences) DeepCopyInto(out *SQLTableForeignKeyReferences) {
+func (in *PostgresqlTableForeignKeyReferences) DeepCopyInto(out *PostgresqlTableForeignKeyReferences) {
 	*out = *in
 	if in.Columns != nil {
 		in, out := &in.Columns, &out.Columns
@@ -586,18 +701,18 @@ func (in *SQLTableForeignKeyReferences) DeepCopyInto(out *SQLTableForeignKeyRefe
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLTableForeignKeyReferences.
-func (in *SQLTableForeignKeyReferences) DeepCopy() *SQLTableForeignKeyReferences {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgresqlTableForeignKeyReferences.
+func (in *PostgresqlTableForeignKeyReferences) DeepCopy() *PostgresqlTableForeignKeyReferences {
 	if in == nil {
 		return nil
 	}
-	out := new(SQLTableForeignKeyReferences)
+	out := new(PostgresqlTableForeignKeyReferences)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SQLTableIndex) DeepCopyInto(out *SQLTableIndex) {
+func (in *PostgresqlTableIndex) DeepCopyInto(out *PostgresqlTableIndex) {
 	*out = *in
 	if in.Columns != nil {
 		in, out := &in.Columns, &out.Columns
@@ -606,18 +721,18 @@ func (in *SQLTableIndex) DeepCopyInto(out *SQLTableIndex) {
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLTableIndex.
-func (in *SQLTableIndex) DeepCopy() *SQLTableIndex {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgresqlTableIndex.
+func (in *PostgresqlTableIndex) DeepCopy() *PostgresqlTableIndex {
 	if in == nil {
 		return nil
 	}
-	out := new(SQLTableIndex)
+	out := new(PostgresqlTableIndex)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SQLTableSchema) DeepCopyInto(out *SQLTableSchema) {
+func (in *PostgresqlTableSchema) DeepCopyInto(out *PostgresqlTableSchema) {
 	*out = *in
 	if in.PrimaryKey != nil {
 		in, out := &in.PrimaryKey, &out.PrimaryKey
@@ -626,45 +741,101 @@ func (in *SQLTableSchema) DeepCopyInto(out *SQLTableSchema) {
 	}
 	if in.ForeignKeys != nil {
 		in, out := &in.ForeignKeys, &out.ForeignKeys
-		*out = make([]*SQLTableForeignKey, len(*in))
+		*out = make([]*PostgresqlTableForeignKey, len(*in))
 		for i := range *in {
 			if (*in)[i] != nil {
 				in, out := &(*in)[i], &(*out)[i]
-				*out = new(SQLTableForeignKey)
+				*out = new(PostgresqlTableForeignKey)
 				(*in).DeepCopyInto(*out)
 			}
 		}
 	}
 	if in.Indexes != nil {
 		in, out := &in.Indexes, &out.Indexes
-		*out = make([]*SQLTableIndex, len(*in))
+		*out = make([]*PostgresqlTableIndex, len(*in))
 		for i := range *in {
 			if (*in)[i] != nil {
 				in, out := &(*in)[i], &(*out)[i]
-				*out = new(SQLTableIndex)
+				*out = new(PostgresqlTableIndex)
 				(*in).DeepCopyInto(*out)
 			}
 		}
 	}
 	if in.Columns != nil {
 		in, out := &in.Columns, &out.Columns
-		*out = make([]*SQLTableColumn, len(*in))
+		*out = make([]*PostgresqlTableColumn, len(*in))
 		for i := range *in {
 			if (*in)[i] != nil {
 				in, out := &(*in)[i], &(*out)[i]
-				*out = new(SQLTableColumn)
+				*out = new(PostgresqlTableColumn)
 				(*in).DeepCopyInto(*out)
 			}
 		}
 	}
+	if in.Triggers != nil {
+		in, out := &in.Triggers, &out.Triggers
+		*out = make([]*PostgresqlTableTrigger, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(PostgresqlTableTrigger)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgresqlTableSchema.
+func (in *PostgresqlTableSchema) DeepCopy() *PostgresqlTableSchema {
+	if in == nil {
+		return nil
+	}
+	out := new(PostgresqlTableSchema)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PostgresqlTableTrigger) DeepCopyInto(out *PostgresqlTableTrigger) {
+	*out = *in
+	if in.ConstraintTrigger != nil {
+		in, out := &in.ConstraintTrigger, &out.ConstraintTrigger
+		*out = new(bool)
+		**out = **in
+	}
+	if in.Events != nil {
+		in, out := &in.Events, &out.Events
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.ForEachStatement != nil {
+		in, out := &in.ForEachStatement, &out.ForEachStatement
+		*out = new(bool)
+		**out = **in
+	}
+	if in.ForEachRow != nil {
+		in, out := &in.ForEachRow, &out.ForEachRow
+		*out = new(bool)
+		**out = **in
+	}
+	if in.Condition != nil {
+		in, out := &in.Condition, &out.Condition
+		*out = new(string)
+		**out = **in
+	}
+	if in.Arguments != nil {
+		in, out := &in.Arguments, &out.Arguments
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLTableSchema.
-func (in *SQLTableSchema) DeepCopy() *SQLTableSchema {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgresqlTableTrigger.
+func (in *PostgresqlTableTrigger) DeepCopy() *PostgresqlTableTrigger {
 	if in == nil {
 		return nil
 	}
-	out := new(SQLTableSchema)
+	out := new(PostgresqlTableTrigger)
 	in.DeepCopyInto(out)
 	return out
 }
@@ -733,17 +904,17 @@ func (in *TableSchema) DeepCopyInto(out *TableSchema) {
 	*out = *in
 	if in.Postgres != nil {
 		in, out := &in.Postgres, &out.Postgres
-		*out = new(SQLTableSchema)
+		*out = new(PostgresqlTableSchema)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Mysql != nil {
 		in, out := &in.Mysql, &out.Mysql
-		*out = new(MysqlSQLTableSchema)
+		*out = new(MysqlTableSchema)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.CockroachDB != nil {
 		in, out := &in.CockroachDB, &out.CockroachDB
-		*out = new(SQLTableSchema)
+		*out = new(PostgresqlTableSchema)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Cassandra != nil {
diff --git a/pkg/database/cassandra/create.go b/pkg/database/cassandra/create.go
index 0652a04a..35abf5a1 100644
--- a/pkg/database/cassandra/create.go
+++ b/pkg/database/cassandra/create.go
@@ -24,12 +24,12 @@ func CreateTypeStatement(keyspace string, typeName string, typeSchema *schemasv1
 	return query, nil
 }
 
-func CreateTableStatement(keyspace string, tableName string, tableSchema *schemasv1alpha4.CassandraTableSchema) (string, error) {
+func CreateTableStatements(keyspace string, tableName string, tableSchema *schemasv1alpha4.CassandraTableSchema) ([]string, error) {
 	columns := []string{}
 	for _, desiredColumn := range tableSchema.Columns {
 		columnsFields, err := cassandraColumnAsInsert(desiredColumn)
 		if err != nil {
-			return "", err
+			return nil, err
 		}
 		columns = append(columns, columnsFields)
 	}
@@ -74,7 +74,7 @@ func CreateTableStatement(keyspace string, tableName string, tableSchema *schema
 		if tableSchema.Properties.Caching != nil {
 			b, err := json.Marshal(tableSchema.Properties.Caching)
 			if err != nil {
-				return "", errors.Wrap(err, "failed to marshal caching property")
+				return nil, errors.Wrap(err, "failed to marshal caching property")
 			}
 			tableProperty := fmt.Sprintf(`caching = %s`, b)
 			tableProperties = append(tableProperties, tableProperty)
@@ -86,7 +86,7 @@ func CreateTableStatement(keyspace string, tableName string, tableSchema *schema
 		if tableSchema.Properties.Compaction != nil {
 			b, err := json.Marshal(tableSchema.Properties.Compaction)
 			if err != nil {
-				return "", errors.Wrap(err, "failed to marshal compaction property")
+				return nil, errors.Wrap(err, "failed to marshal compaction property")
 			}
 			tableProperty := fmt.Sprintf(`compaction = %s`, b)
 			tableProperties = append(tableProperties, tableProperty)
@@ -94,7 +94,7 @@ func CreateTableStatement(keyspace string, tableName string, tableSchema *schema
 		if tableSchema.Properties.Compression != nil {
 			b, err := json.Marshal(tableSchema.Properties.Compression)
 			if err != nil {
-				return "", errors.Wrap(err, "failed to marshal compression property")
+				return nil, errors.Wrap(err, "failed to marshal compression property")
 			}
 			tableProperty := fmt.Sprintf(`compression = %s`, b)
 			tableProperties = append(tableProperties, tableProperty)
@@ -141,5 +141,5 @@ func CreateTableStatement(keyspace string, tableName string, tableSchema *schema
 		query = fmt.Sprintf("%s with %s", query, strings.Join(tableProperties, " AND "))
 	}
 
-	return query, nil
+	return []string{query}, nil
 }
diff --git a/pkg/database/cassandra/deploy.go b/pkg/database/cassandra/deploy.go
index ceb96219..16d0d833 100644
--- a/pkg/database/cassandra/deploy.go
+++ b/pkg/database/cassandra/deploy.go
@@ -72,12 +72,12 @@ func PlanCassandraTable(hosts []string, username string, password string, keyspa
 
 	if tableExists == 0 {
 		// shortcut to just create it
-		query, err := CreateTableStatement(keyspace, tableName, cassandraTableSchema)
+		queries, err := CreateTableStatements(keyspace, tableName, cassandraTableSchema)
 		if err != nil {
 			return nil, errors.Wrap(err, "failed to create table statement")
 		}
 
-		return []string{query}, nil
+		return queries, nil
 	}
 
 	statements := []string{}
diff --git a/pkg/database/database.go b/pkg/database/database.go
index 53bd7def..6e292761 100644
--- a/pkg/database/database.go
+++ b/pkg/database/database.go
@@ -74,34 +74,34 @@ func (d *Database) CreateFixturesSync() error {
 				return nil
 			}
 
-			statement, err := postgres.CreateTableStatement(spec.Name, spec.Schema.Postgres)
+			createStatements, err := postgres.CreateTableStatements(spec.Name, spec.Schema.Postgres)
 			if err != nil {
 				return err
 			}
 
-			statements = append(statements, statement)
+			statements = append(statements, createStatements...)
 		} else if d.Driver == "mysql" {
 			if spec.Schema.Mysql == nil {
 				return nil
 			}
 
-			statement, err := mysql.CreateTableStatement(spec.Name, spec.Schema.Mysql)
+			createStatements, err := mysql.CreateTableStatements(spec.Name, spec.Schema.Mysql)
 			if err != nil {
 				return err
 			}
 
-			statements = append(statements, statement)
+			statements = append(statements, createStatements...)
 		} else if d.Driver == "cockroachdb" {
 			if spec.Schema.CockroachDB == nil {
 				return nil
 			}
 
-			statement, err := postgres.CreateTableStatement(spec.Name, spec.Schema.CockroachDB)
+			createStatements, err := postgres.CreateTableStatements(spec.Name, spec.Schema.CockroachDB)
 			if err != nil {
 				return err
 			}
 
-			statements = append(statements, statement)
+			statements = append(statements, createStatements...)
 		} else if d.Driver == "cassandra" {
 			return errors.New("not implemented")
 		}
diff --git a/pkg/database/mysql/alter.go b/pkg/database/mysql/alter.go
index 15f6f17d..4b5d6692 100644
--- a/pkg/database/mysql/alter.go
+++ b/pkg/database/mysql/alter.go
@@ -5,7 +5,7 @@ import (
 	"github.com/schemahero/schemahero/pkg/database/types"
 )
 
-func AlterColumnStatements(tableName string, primaryKeys []string, desiredColumns []*schemasv1alpha4.MysqlSQLTableColumn, existingColumn *types.Column) ([]string, error) {
+func AlterColumnStatements(tableName string, primaryKeys []string, desiredColumns []*schemasv1alpha4.MysqlTableColumn, existingColumn *types.Column) ([]string, error) {
 	// this could be an alter or a drop column command
 	for _, desiredColumn := range desiredColumns {
 		if desiredColumn.Name == existingColumn.Name {
diff --git a/pkg/database/mysql/column.go b/pkg/database/mysql/column.go
index dbada007..e2e89ccc 100644
--- a/pkg/database/mysql/column.go
+++ b/pkg/database/mysql/column.go
@@ -7,7 +7,7 @@ import (
 	"github.com/schemahero/schemahero/pkg/database/types"
 )
 
-func schemaColumnToColumn(schemaColumn *schemasv1alpha4.MysqlSQLTableColumn) (*types.Column, error) {
+func schemaColumnToColumn(schemaColumn *schemasv1alpha4.MysqlTableColumn) (*types.Column, error) {
 	column := &types.Column{
 		Name:          schemaColumn.Name,
 		ColumnDefault: schemaColumn.Default,
@@ -56,7 +56,7 @@ func schemaColumnToColumn(schemaColumn *schemasv1alpha4.MysqlSQLTableColumn) (*t
 	return nil, fmt.Errorf("unknown column type. cannot validate column type %q", schemaColumn.Type)
 }
 
-func mysqlColumnAsInsert(column *schemasv1alpha4.MysqlSQLTableColumn) (string, error) {
+func mysqlColumnAsInsert(column *schemasv1alpha4.MysqlTableColumn) (string, error) {
 	mysqlColumn, err := schemaColumnToColumn(column)
 	if err != nil {
 		return "", err
@@ -102,7 +102,7 @@ func mysqlColumnAsInsert(column *schemasv1alpha4.MysqlSQLTableColumn) (string, e
 	return formatted, nil
 }
 
-func InsertColumnStatement(tableName string, desiredColumn *schemasv1alpha4.MysqlSQLTableColumn) (string, error) {
+func InsertColumnStatement(tableName string, desiredColumn *schemasv1alpha4.MysqlTableColumn) (string, error) {
 	columnFields, err := mysqlColumnAsInsert(desiredColumn)
 	if err != nil {
 		return "", err
diff --git a/pkg/database/mysql/create.go b/pkg/database/mysql/create.go
index 24784afe..731cf48f 100644
--- a/pkg/database/mysql/create.go
+++ b/pkg/database/mysql/create.go
@@ -7,12 +7,12 @@ import (
 	schemasv1alpha4 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha4"
 )
 
-func CreateTableStatement(tableName string, tableSchema *schemasv1alpha4.MysqlSQLTableSchema) (string, error) {
+func CreateTableStatements(tableName string, tableSchema *schemasv1alpha4.MysqlTableSchema) ([]string, error) {
 	columns := []string{}
 	for _, desiredColumn := range tableSchema.Columns {
 		columnFields, err := mysqlColumnAsInsert(desiredColumn)
 		if err != nil {
-			return "", err
+			return nil, err
 		}
 		columns = append(columns, columnFields)
 	}
@@ -42,5 +42,5 @@ func CreateTableStatement(tableName string, tableSchema *schemasv1alpha4.MysqlSQ
 		query = fmt.Sprintf("%s collate %s", query, tableSchema.Collation)
 	}
 
-	return query, nil
+	return []string{query}, nil
 }
diff --git a/pkg/database/mysql/deploy.go b/pkg/database/mysql/deploy.go
index 09bf0c01..b7fc76bd 100644
--- a/pkg/database/mysql/deploy.go
+++ b/pkg/database/mysql/deploy.go
@@ -11,7 +11,7 @@ import (
 	"github.com/schemahero/schemahero/pkg/database/types"
 )
 
-func PlanMysqlTable(uri string, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlSQLTableSchema) ([]string, error) {
+func PlanMysqlTable(uri string, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlTableSchema) ([]string, error) {
 	m, err := Connect(uri)
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to connect to mysql")
@@ -36,12 +36,12 @@ func PlanMysqlTable(uri string, tableName string, mysqlTableSchema *schemasv1alp
 
 	if tableExists == 0 {
 		// shortcut to just create it
-		query, err := CreateTableStatement(tableName, mysqlTableSchema)
+		queries, err := CreateTableStatements(tableName, mysqlTableSchema)
 		if err != nil {
 			return nil, errors.Wrap(err, "failed to create table statement")
 		}
 
-		return []string{query}, nil
+		return queries, nil
 	}
 
 	statements := []string{}
@@ -113,7 +113,7 @@ func executeStatements(m *MysqlConnection, statements []string) error {
 	return nil
 }
 
-func buildTableCharsetAndCollationStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlSQLTableSchema) ([]string, error) {
+func buildTableCharsetAndCollationStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlTableSchema) ([]string, error) {
 	query := `select 
 t.TABLE_COLLATION,
 c.character_set_name FROM information_schema.TABLES t,
@@ -199,7 +199,7 @@ WHERE schema_name = ?`
 	}, nil
 }
 
-func buildColumnStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlSQLTableSchema) ([]string, error) {
+func buildColumnStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlTableSchema) ([]string, error) {
 	query := `select
 COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, EXTRA, COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH
 from information_schema.COLUMNS
@@ -292,7 +292,7 @@ where TABLE_NAME = ?`
 	return alterAndDropStatements, nil
 }
 
-func buildPrimaryKeyStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlSQLTableSchema) ([]string, error) {
+func buildPrimaryKeyStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlTableSchema) ([]string, error) {
 	currentPrimaryKey, err := m.GetTablePrimaryKey(tableName)
 	if err != nil {
 		return nil, err
@@ -327,7 +327,7 @@ func buildPrimaryKeyStatements(m *MysqlConnection, tableName string, mysqlTableS
 	return statements, nil
 }
 
-func buildForeignKeyStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlSQLTableSchema) ([]string, error) {
+func buildForeignKeyStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlTableSchema) ([]string, error) {
 	foreignKeyStatements := []string{}
 	currentForeignKeys, err := m.ListTableForeignKeys(m.databaseName, tableName)
 	if err != nil {
@@ -338,7 +338,7 @@ func buildForeignKeyStatements(m *MysqlConnection, tableName string, mysqlTableS
 		var statement string
 		var matchedForeignKey *types.ForeignKey
 		for _, currentForeignKey := range currentForeignKeys {
-			if currentForeignKey.Equals(types.SchemaForeignKeyToForeignKey(foreignKey)) {
+			if currentForeignKey.Equals(types.MysqlSchemaForeignKeyToForeignKey(foreignKey)) {
 				goto Next
 			}
 
@@ -361,7 +361,7 @@ func buildForeignKeyStatements(m *MysqlConnection, tableName string, mysqlTableS
 	for _, currentForeignKey := range currentForeignKeys {
 		var statement string
 		for _, foreignKey := range mysqlTableSchema.ForeignKeys {
-			if currentForeignKey.Equals(types.SchemaForeignKeyToForeignKey(foreignKey)) {
+			if currentForeignKey.Equals(types.MysqlSchemaForeignKeyToForeignKey(foreignKey)) {
 				goto NextCurrentFK
 			}
 		}
@@ -375,7 +375,7 @@ func buildForeignKeyStatements(m *MysqlConnection, tableName string, mysqlTableS
 	return foreignKeyStatements, nil
 }
 
-func buildIndexStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlSQLTableSchema) ([]string, error) {
+func buildIndexStatements(m *MysqlConnection, tableName string, mysqlTableSchema *schemasv1alpha4.MysqlTableSchema) ([]string, error) {
 	indexStatements := []string{}
 	currentIndexes, err := m.ListTableIndexes(m.databaseName, tableName)
 	if err != nil {
@@ -385,7 +385,7 @@ func buildIndexStatements(m *MysqlConnection, tableName string, mysqlTableSchema
 	for _, currentIndex := range currentIndexes {
 		isMatch := false
 		for _, desiredIndex := range mysqlTableSchema.Indexes {
-			if currentIndex.Equals(types.SchemaIndexToIndex(desiredIndex)) {
+			if currentIndex.Equals(types.MysqlSchemaIndexToIndex(desiredIndex)) {
 				isMatch = true
 			}
 		}
@@ -398,7 +398,7 @@ func buildIndexStatements(m *MysqlConnection, tableName string, mysqlTableSchema
 	for _, desiredIndex := range mysqlTableSchema.Indexes {
 		isMatch := false
 		for _, currentIndex := range currentIndexes {
-			if currentIndex.Equals(types.SchemaIndexToIndex(desiredIndex)) {
+			if currentIndex.Equals(types.MysqlSchemaIndexToIndex(desiredIndex)) {
 				isMatch = true
 			}
 		}
diff --git a/pkg/database/mysql/foreignkey.go b/pkg/database/mysql/foreignkey.go
index 60f00741..e1393c5d 100644
--- a/pkg/database/mysql/foreignkey.go
+++ b/pkg/database/mysql/foreignkey.go
@@ -12,18 +12,18 @@ func RemoveForeignKeyStatement(tableName string, foreignKey *types.ForeignKey) s
 	return fmt.Sprintf("alter table %s drop constraint %s", tableName, foreignKey.Name)
 }
 
-func AddForeignKeyStatement(tableName string, schemaForeignKey *schemasv1alpha4.SQLTableForeignKey) string {
+func AddForeignKeyStatement(tableName string, schemaForeignKey *schemasv1alpha4.MysqlTableForeignKey) string {
 	return fmt.Sprintf("alter table %s add %s", tableName, foreignKeyConstraintClause(tableName, schemaForeignKey))
 }
 
-func foreignKeyConstraintClause(tableName string, schemaForeignKey *schemasv1alpha4.SQLTableForeignKey) string {
+func foreignKeyConstraintClause(tableName string, schemaForeignKey *schemasv1alpha4.MysqlTableForeignKey) string {
 	onDelete := ""
 	if schemaForeignKey.OnDelete != "" {
 		onDelete = fmt.Sprintf(" on delete %s", schemaForeignKey.OnDelete)
 	}
 
 	return fmt.Sprintf("constraint %s foreign key (%s) references %s (%s)%s",
-		types.GenerateFKName(tableName, schemaForeignKey),
+		types.GenerateMysqlFKName(tableName, schemaForeignKey),
 		strings.Join(schemaForeignKey.Columns, ", "),
 		schemaForeignKey.References.Table,
 		strings.Join(schemaForeignKey.References.Columns, ", "),
diff --git a/pkg/database/mysql/index.go b/pkg/database/mysql/index.go
index 24d4c0de..7a09db8a 100644
--- a/pkg/database/mysql/index.go
+++ b/pkg/database/mysql/index.go
@@ -12,7 +12,7 @@ func RemoveIndexStatement(tableName string, index *types.Index) string {
 	return fmt.Sprintf("alter table %q drop index %q", tableName, index.Name)
 }
 
-func AddIndexStatement(tableName string, schemaIndex *schemasv1alpha4.SQLTableIndex) string {
+func AddIndexStatement(tableName string, schemaIndex *schemasv1alpha4.MysqlTableIndex) string {
 	unique := ""
 	if schemaIndex.IsUnique {
 		unique = "unique "
@@ -20,12 +20,12 @@ func AddIndexStatement(tableName string, schemaIndex *schemasv1alpha4.SQLTableIn
 
 	name := schemaIndex.Name
 	if name == "" {
-		name = types.GenerateIndexName(tableName, schemaIndex)
+		name = types.GenerateMysqlIndexName(tableName, schemaIndex)
 	}
 
 	return fmt.Sprintf("create %sindex %s on %s (%s)", unique, name, tableName, strings.Join(schemaIndex.Columns, ", "))
 }
 
-func RenameIndexStatement(tableName string, index *types.Index, schemaIndex *schemasv1alpha4.SQLTableIndex) string {
+func RenameIndexStatement(tableName string, index *types.Index, schemaIndex *schemasv1alpha4.MysqlTableIndex) string {
 	return fmt.Sprintf("alter index %s rename to %s", index.Name, schemaIndex.Name)
 }
diff --git a/pkg/database/postgres/alter.go b/pkg/database/postgres/alter.go
index 7ea09874..aba4c9a7 100644
--- a/pkg/database/postgres/alter.go
+++ b/pkg/database/postgres/alter.go
@@ -9,7 +9,7 @@ import (
 	"github.com/schemahero/schemahero/pkg/database/types"
 )
 
-func AlterColumnStatements(tableName string, primaryKeys []string, desiredColumns []*schemasv1alpha4.SQLTableColumn, existingColumn *types.Column) ([]string, error) {
+func AlterColumnStatements(tableName string, primaryKeys []string, desiredColumns []*schemasv1alpha4.PostgresqlTableColumn, existingColumn *types.Column) ([]string, error) {
 	alterStatement := fmt.Sprintf("alter column %s", pgx.Identifier{existingColumn.Name}.Sanitize())
 
 	// this could be an alter or a drop column command
diff --git a/pkg/database/postgres/column.go b/pkg/database/postgres/column.go
index 37a90005..4239aa8f 100644
--- a/pkg/database/postgres/column.go
+++ b/pkg/database/postgres/column.go
@@ -9,7 +9,7 @@ import (
 	"github.com/schemahero/schemahero/pkg/database/types"
 )
 
-func schemaColumnToColumn(schemaColumn *schemasv1alpha4.SQLTableColumn) (*types.Column, error) {
+func schemaColumnToColumn(schemaColumn *schemasv1alpha4.PostgresqlTableColumn) (*types.Column, error) {
 	column := &types.Column{
 		Name:          schemaColumn.Name,
 		ColumnDefault: schemaColumn.Default,
@@ -56,7 +56,7 @@ func schemaColumnToColumn(schemaColumn *schemasv1alpha4.SQLTableColumn) (*types.
 	return nil, fmt.Errorf("unknown column type. cannot validate column type %q", schemaColumn.Type)
 }
 
-func postgresColumnAsInsert(column *schemasv1alpha4.SQLTableColumn) (string, error) {
+func columnAsInsert(column *schemasv1alpha4.PostgresqlTableColumn) (string, error) {
 	// Note, we don't always quote the column type because of how pg handles these two statement very differently:
 
 	// 1. create table "users" ("id" "bigint","login" "varchar(255)","name" "varchar(255)")
@@ -91,8 +91,8 @@ func postgresColumnAsInsert(column *schemasv1alpha4.SQLTableColumn) (string, err
 	return formatted, nil
 }
 
-func InsertColumnStatement(tableName string, desiredColumn *schemasv1alpha4.SQLTableColumn) (string, error) {
-	columnFields, err := postgresColumnAsInsert(desiredColumn)
+func InsertColumnStatement(tableName string, desiredColumn *schemasv1alpha4.PostgresqlTableColumn) (string, error) {
+	columnFields, err := columnAsInsert(desiredColumn)
 	if err != nil {
 		return "", err
 	}
diff --git a/pkg/database/postgres/create.go b/pkg/database/postgres/create.go
index b2c21496..0e62195a 100644
--- a/pkg/database/postgres/create.go
+++ b/pkg/database/postgres/create.go
@@ -5,17 +5,18 @@ import (
 	"strings"
 
 	"github.com/jackc/pgx/v4"
+	"github.com/pkg/errors"
 
 	schemasv1alpha4 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha4"
 	"github.com/schemahero/schemahero/pkg/database/types"
 )
 
-func CreateTableStatement(tableName string, tableSchema *schemasv1alpha4.SQLTableSchema) (string, error) {
+func CreateTableStatements(tableName string, tableSchema *schemasv1alpha4.PostgresqlTableSchema) ([]string, error) {
 	columns := []string{}
 	for _, desiredColumn := range tableSchema.Columns {
-		columnFields, err := postgresColumnAsInsert(desiredColumn)
+		columnFields, err := columnAsInsert(desiredColumn)
 		if err != nil {
-			return "", err
+			return nil, err
 		}
 		columns = append(columns, columnFields)
 	}
@@ -36,7 +37,7 @@ func CreateTableStatement(tableName string, tableSchema *schemasv1alpha4.SQLTabl
 				for _, indexColumn := range index.Columns {
 					uniqueColumns = append(uniqueColumns, pgx.Identifier{indexColumn}.Sanitize())
 				}
-				columns = append(columns, fmt.Sprintf("constraint %q unique (%s)", types.GenerateIndexName(tableName, index), strings.Join(uniqueColumns, ", ")))
+				columns = append(columns, fmt.Sprintf("constraint %q unique (%s)", types.GeneratePostgresqlIndexName(tableName, index), strings.Join(uniqueColumns, ", ")))
 			} else {
 				// non unique indexes are not supported in fixtures
 			}
@@ -49,7 +50,18 @@ func CreateTableStatement(tableName string, tableSchema *schemasv1alpha4.SQLTabl
 		}
 	}
 
-	query := fmt.Sprintf(`create table %s (%s)`, pgx.Identifier{tableName}.Sanitize(), strings.Join(columns, ", "))
+	queries := []string{
+		fmt.Sprintf(`create table %s (%s)`, pgx.Identifier{tableName}.Sanitize(), strings.Join(columns, ", ")),
+	}
 
-	return query, nil
+	// Add any triggers that are defined
+	for _, trigger := range tableSchema.Triggers {
+		statement, err := triggerCreateStatement(trigger, tableName)
+		if err != nil {
+			return nil, errors.Wrap(err, "failed to create trigger statement")
+		}
+
+		queries = append(queries, statement)
+	}
+	return queries, nil
 }
diff --git a/pkg/database/postgres/deploy.go b/pkg/database/postgres/deploy.go
index e1bfb553..8dbef19f 100644
--- a/pkg/database/postgres/deploy.go
+++ b/pkg/database/postgres/deploy.go
@@ -11,7 +11,7 @@ import (
 	"github.com/schemahero/schemahero/pkg/database/types"
 )
 
-func PlanPostgresTable(uri string, tableName string, postgresTableSchema *schemasv1alpha4.SQLTableSchema) ([]string, error) {
+func PlanPostgresTable(uri string, tableName string, postgresTableSchema *schemasv1alpha4.PostgresqlTableSchema) ([]string, error) {
 	p, err := Connect(uri)
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to connect to postgres")
@@ -36,12 +36,12 @@ func PlanPostgresTable(uri string, tableName string, postgresTableSchema *schema
 
 	if tableExists == 0 {
 		// shortcut to just create it
-		query, err := CreateTableStatement(tableName, postgresTableSchema)
+		queries, err := CreateTableStatements(tableName, postgresTableSchema)
 		if err != nil {
 			return nil, errors.Wrap(err, "failed to create table statement")
 		}
 
-		return []string{query}, nil
+		return queries, nil
 	}
 
 	statements := []string{}
@@ -106,7 +106,7 @@ func executeStatements(p *PostgresConnection, statements []string) error {
 	return nil
 }
 
-func buildColumnStatements(p *PostgresConnection, tableName string, postgresTableSchema *schemasv1alpha4.SQLTableSchema) ([]string, error) {
+func buildColumnStatements(p *PostgresConnection, tableName string, postgresTableSchema *schemasv1alpha4.PostgresqlTableSchema) ([]string, error) {
 	query := `select
 column_name, column_default, is_nullable, data_type, udt_name, character_maximum_length
 from information_schema.columns
@@ -183,7 +183,7 @@ where table_name = $1`
 	return alterAndDropStatements, nil
 }
 
-func buildPrimaryKeyStatements(p *PostgresConnection, tableName string, postgresTableSchema *schemasv1alpha4.SQLTableSchema) ([]string, error) {
+func buildPrimaryKeyStatements(p *PostgresConnection, tableName string, postgresTableSchema *schemasv1alpha4.PostgresqlTableSchema) ([]string, error) {
 	currentPrimaryKey, err := p.GetTablePrimaryKey(tableName)
 	if err != nil {
 		return nil, err
@@ -212,7 +212,7 @@ func buildPrimaryKeyStatements(p *PostgresConnection, tableName string, postgres
 	return statements, nil
 }
 
-func buildForeignKeyStatements(p *PostgresConnection, tableName string, postgresTableSchema *schemasv1alpha4.SQLTableSchema) ([]string, error) {
+func buildForeignKeyStatements(p *PostgresConnection, tableName string, postgresTableSchema *schemasv1alpha4.PostgresqlTableSchema) ([]string, error) {
 	foreignKeyStatements := []string{}
 	droppedKeys := []string{}
 	currentForeignKeys, err := p.ListTableForeignKeys(p.databaseName, tableName)
@@ -224,7 +224,7 @@ func buildForeignKeyStatements(p *PostgresConnection, tableName string, postgres
 		var statement string
 		var matchedForeignKey *types.ForeignKey
 		for _, currentForeignKey := range currentForeignKeys {
-			if currentForeignKey.Equals(types.SchemaForeignKeyToForeignKey(foreignKey)) {
+			if currentForeignKey.Equals(types.PostgresqlSchemaForeignKeyToForeignKey(foreignKey)) {
 				goto Next
 			}
 
@@ -248,7 +248,7 @@ func buildForeignKeyStatements(p *PostgresConnection, tableName string, postgres
 	for _, currentForeignKey := range currentForeignKeys {
 		var statement string
 		for _, foreignKey := range postgresTableSchema.ForeignKeys {
-			if currentForeignKey.Equals(types.SchemaForeignKeyToForeignKey(foreignKey)) {
+			if currentForeignKey.Equals(types.PostgresqlSchemaForeignKeyToForeignKey(foreignKey)) {
 				goto NextCurrentFK
 			}
 		}
@@ -268,7 +268,7 @@ func buildForeignKeyStatements(p *PostgresConnection, tableName string, postgres
 	return foreignKeyStatements, nil
 }
 
-func buildIndexStatements(p *PostgresConnection, tableName string, postgresTableSchema *schemasv1alpha4.SQLTableSchema) ([]string, error) {
+func buildIndexStatements(p *PostgresConnection, tableName string, postgresTableSchema *schemasv1alpha4.PostgresqlTableSchema) ([]string, error) {
 	indexStatements := []string{}
 	droppedIndexes := []string{}
 	currentIndexes, err := p.ListTableIndexes(p.databaseName, tableName)
@@ -282,13 +282,13 @@ func buildIndexStatements(p *PostgresConnection, tableName string, postgresTable
 
 	for _, index := range postgresTableSchema.Indexes {
 		if index.Name == "" {
-			index.Name = types.GenerateIndexName(tableName, index)
+			index.Name = types.GeneratePostgresqlIndexName(tableName, index)
 		}
 
 		var statement string
 		var matchedIndex *types.Index
 		for _, currentIndex := range currentIndexes {
-			if currentIndex.Equals(types.SchemaIndexToIndex(index)) {
+			if currentIndex.Equals(types.PostgresqlSchemaIndexToIndex(index)) {
 				goto Next
 			}
 
@@ -326,7 +326,7 @@ func buildIndexStatements(p *PostgresConnection, tableName string, postgresTable
 		isConstraint := false
 
 		for _, index := range postgresTableSchema.Indexes {
-			if currentIndex.Equals(types.SchemaIndexToIndex(index)) {
+			if currentIndex.Equals(types.PostgresqlSchemaIndexToIndex(index)) {
 				goto NextCurrentIdx
 			}
 		}
diff --git a/pkg/database/postgres/foreignkey.go b/pkg/database/postgres/foreignkey.go
index f85989c3..7e0ded86 100644
--- a/pkg/database/postgres/foreignkey.go
+++ b/pkg/database/postgres/foreignkey.go
@@ -13,18 +13,18 @@ func RemoveForeignKeyStatement(tableName string, foreignKey *types.ForeignKey) s
 	return fmt.Sprintf("alter table %s drop constraint %s", tableName, pgx.Identifier{foreignKey.Name}.Sanitize())
 }
 
-func AddForeignKeyStatement(tableName string, schemaForeignKey *schemasv1alpha4.SQLTableForeignKey) string {
+func AddForeignKeyStatement(tableName string, schemaForeignKey *schemasv1alpha4.PostgresqlTableForeignKey) string {
 	return fmt.Sprintf("alter table %s add %s", tableName, foreignKeyConstraintClause(tableName, schemaForeignKey))
 }
 
-func foreignKeyConstraintClause(tableName string, schemaForeignKey *schemasv1alpha4.SQLTableForeignKey) string {
+func foreignKeyConstraintClause(tableName string, schemaForeignKey *schemasv1alpha4.PostgresqlTableForeignKey) string {
 	onDelete := ""
 	if schemaForeignKey.OnDelete != "" {
 		onDelete = fmt.Sprintf(" on delete %s", schemaForeignKey.OnDelete)
 	}
 
 	return fmt.Sprintf("constraint %s foreign key (%s) references %s (%s)%s",
-		types.GenerateFKName(tableName, schemaForeignKey),
+		types.GeneratePostgresqlFKName(tableName, schemaForeignKey),
 		strings.Join(schemaForeignKey.Columns, ", "),
 		schemaForeignKey.References.Table,
 		strings.Join(schemaForeignKey.References.Columns, ", "),
diff --git a/pkg/database/postgres/index.go b/pkg/database/postgres/index.go
index 7f094529..da21d14f 100644
--- a/pkg/database/postgres/index.go
+++ b/pkg/database/postgres/index.go
@@ -20,7 +20,7 @@ func RemoveIndexStatement(tableName string, index *types.Index) string {
 	return fmt.Sprintf("drop index %s", pgx.Identifier{index.Name}.Sanitize())
 }
 
-func AddIndexStatement(tableName string, schemaIndex *schemasv1alpha4.SQLTableIndex) string {
+func AddIndexStatement(tableName string, schemaIndex *schemasv1alpha4.PostgresqlTableIndex) string {
 	unique := ""
 	if schemaIndex.IsUnique {
 		unique = "unique "
@@ -28,7 +28,7 @@ func AddIndexStatement(tableName string, schemaIndex *schemasv1alpha4.SQLTableIn
 
 	name := schemaIndex.Name
 	if name == "" {
-		name = types.GenerateIndexName(tableName, schemaIndex)
+		name = types.GeneratePostgresqlIndexName(tableName, schemaIndex)
 	}
 
 	return fmt.Sprintf("create %sindex %s on %s (%s)",
@@ -38,6 +38,6 @@ func AddIndexStatement(tableName string, schemaIndex *schemasv1alpha4.SQLTableIn
 		strings.Join(schemaIndex.Columns, ", "))
 }
 
-func RenameIndexStatement(tableName string, index *types.Index, schemaIndex *schemasv1alpha4.SQLTableIndex) string {
+func RenameIndexStatement(tableName string, index *types.Index, schemaIndex *schemasv1alpha4.PostgresqlTableIndex) string {
 	return fmt.Sprintf("alter index %s rename to %s", pgx.Identifier{index.Name}.Sanitize(), pgx.Identifier{schemaIndex.Name}.Sanitize())
 }
diff --git a/pkg/database/postgres/trigger.go b/pkg/database/postgres/trigger.go
new file mode 100644
index 00000000..f882c722
--- /dev/null
+++ b/pkg/database/postgres/trigger.go
@@ -0,0 +1,81 @@
+package postgres
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/pkg/errors"
+	schemasv1alpha4 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha4"
+)
+
+func triggerCreateStatement(trigger *schemasv1alpha4.PostgresqlTableTrigger, tableName string) (string, error) {
+	triggerEventSyntax, err := triggerEvent(trigger)
+	if err != nil {
+		return "", errors.Wrap(err, "failed to create trigger event syntax")
+	}
+
+	o := "trigger"
+	if trigger.ConstraintTrigger != nil && *trigger.ConstraintTrigger == true {
+		o = "constraint trigger"
+	}
+
+	stmt := fmt.Sprintf(`create %s %q %s on %q`, o, trigger.Name, triggerEventSyntax, tableName)
+
+	forEachStatement := true // pg default
+	if trigger.ForEachRow != nil && *trigger.ForEachRow == true {
+		forEachStatement = false
+	}
+
+	if forEachStatement {
+		stmt = fmt.Sprintf("%s for each statement", stmt)
+	} else {
+		stmt = fmt.Sprintf("%s for each row", stmt)
+	}
+
+	if trigger.Condition != nil {
+		stmt = fmt.Sprintf("%s when (%s)", stmt, *trigger.Condition)
+	}
+
+	stmt = fmt.Sprintf("%s execute procedure %s", stmt, trigger.ExecuteProcedure)
+
+	return stmt, nil
+}
+
+func triggerEvent(trigger *schemasv1alpha4.PostgresqlTableTrigger) (string, error) {
+	if len(trigger.Events) == 0 {
+		return "", errors.New("trigger missing events")
+	}
+
+	// build the event which could be like:
+	//   after insert or update of col1, col2
+
+	// all triggers must be the same temporal event (after, before, instead of)
+	temporal := ""
+	if strings.HasPrefix(strings.ToLower(trigger.Events[0]), "after") {
+		temporal = "after"
+	} else if strings.HasPrefix(strings.ToLower(trigger.Events[0]), "before") {
+		temporal = "before"
+	} else if strings.HasPrefix(strings.ToLower(trigger.Events[0]), "instead of") {
+		temporal = "instead of"
+	} else {
+		return "", errors.New("unable to parse trigger")
+	}
+
+	events := []string{}
+	for _, event := range trigger.Events {
+		event := strings.TrimSpace(strings.ToLower(event))
+
+		if strings.HasPrefix(event, "after") {
+			events = append(events, strings.TrimPrefix(event, "after"))
+			continue
+		} else if strings.HasPrefix(event, "before") {
+			events = append(events, strings.TrimPrefix(event, "before"))
+			continue
+		} else if strings.HasPrefix(event, "instead of") {
+			events = append(events, strings.TrimPrefix(event, "instead of"))
+			continue
+		}
+	}
+
+	return fmt.Sprintf("%s%s", temporal, strings.Join(events, " or")), nil
+}
diff --git a/pkg/database/types/column.go b/pkg/database/types/column.go
index c296261b..a65f6a93 100644
--- a/pkg/database/types/column.go
+++ b/pkg/database/types/column.go
@@ -31,20 +31,20 @@ type Column struct {
 	IsStatic      bool
 }
 
-func ColumnToMysqlSchemaColumn(column *Column) (*schemasv1alpha4.MysqlSQLTableColumn, error) {
-	schemaColumn := &schemasv1alpha4.MysqlSQLTableColumn{
+func ColumnToMysqlSchemaColumn(column *Column) (*schemasv1alpha4.MysqlTableColumn, error) {
+	schemaColumn := &schemasv1alpha4.MysqlTableColumn{
 		Name: column.Name,
 		Type: column.DataType,
 	}
 
 	if column.Constraints != nil {
-		schemaColumn.Constraints = &schemasv1alpha4.SQLTableColumnConstraints{
+		schemaColumn.Constraints = &schemasv1alpha4.MysqlTableColumnConstraints{
 			NotNull: column.Constraints.NotNull,
 		}
 	}
 
 	if column.Attributes != nil {
-		schemaColumn.Attributes = &schemasv1alpha4.SQLTableColumnAttributes{
+		schemaColumn.Attributes = &schemasv1alpha4.MysqlTableColumnAttributes{
 			AutoIncrement: column.Attributes.AutoIncrement,
 		}
 	}
@@ -57,20 +57,20 @@ func ColumnToMysqlSchemaColumn(column *Column) (*schemasv1alpha4.MysqlSQLTableCo
 	return schemaColumn, nil
 }
 
-func ColumnToSchemaColumn(column *Column) (*schemasv1alpha4.SQLTableColumn, error) {
-	schemaColumn := &schemasv1alpha4.SQLTableColumn{
+func ColumnToPostgresqlSchemaColumn(column *Column) (*schemasv1alpha4.PostgresqlTableColumn, error) {
+	schemaColumn := &schemasv1alpha4.PostgresqlTableColumn{
 		Name: column.Name,
 		Type: column.DataType,
 	}
 
 	if column.Constraints != nil {
-		schemaColumn.Constraints = &schemasv1alpha4.SQLTableColumnConstraints{
+		schemaColumn.Constraints = &schemasv1alpha4.PostgresqlTableColumnConstraints{
 			NotNull: column.Constraints.NotNull,
 		}
 	}
 
 	if column.Attributes != nil {
-		schemaColumn.Attributes = &schemasv1alpha4.SQLTableColumnAttributes{
+		schemaColumn.Attributes = &schemasv1alpha4.PostgresqlTableColumnAttributes{
 			AutoIncrement: column.Attributes.AutoIncrement,
 		}
 	}
diff --git a/pkg/database/types/foreignkey.go b/pkg/database/types/foreignkey.go
index 32b60ae9..f85045bf 100644
--- a/pkg/database/types/foreignkey.go
+++ b/pkg/database/types/foreignkey.go
@@ -21,10 +21,10 @@ func (fk *ForeignKey) Equals(other *ForeignKey) bool {
 	return false
 }
 
-func ForeignKeyToSchemaForeignKey(foreignKey *ForeignKey) *schemasv1alpha4.SQLTableForeignKey {
-	schemaForeignKey := schemasv1alpha4.SQLTableForeignKey{
+func ForeignKeyToMysqlSchemaForeignKey(foreignKey *ForeignKey) *schemasv1alpha4.MysqlTableForeignKey {
+	schemaForeignKey := schemasv1alpha4.MysqlTableForeignKey{
 		Columns: foreignKey.ChildColumns,
-		References: schemasv1alpha4.SQLTableForeignKeyReferences{
+		References: schemasv1alpha4.MysqlTableForeignKeyReferences{
 			Table:   foreignKey.ParentTable,
 			Columns: foreignKey.ParentColumns,
 		},
@@ -35,7 +35,21 @@ func ForeignKeyToSchemaForeignKey(foreignKey *ForeignKey) *schemasv1alpha4.SQLTa
 	return &schemaForeignKey
 }
 
-func SchemaForeignKeyToForeignKey(schemaForeignKey *schemasv1alpha4.SQLTableForeignKey) *ForeignKey {
+func ForeignKeyToPostgresqlSchemaForeignKey(foreignKey *ForeignKey) *schemasv1alpha4.PostgresqlTableForeignKey {
+	schemaForeignKey := schemasv1alpha4.PostgresqlTableForeignKey{
+		Columns: foreignKey.ChildColumns,
+		References: schemasv1alpha4.PostgresqlTableForeignKeyReferences{
+			Table:   foreignKey.ParentTable,
+			Columns: foreignKey.ParentColumns,
+		},
+		Name:     foreignKey.Name,
+		OnDelete: foreignKey.OnDelete,
+	}
+
+	return &schemaForeignKey
+}
+
+func MysqlSchemaForeignKeyToForeignKey(schemaForeignKey *schemasv1alpha4.MysqlTableForeignKey) *ForeignKey {
 	foreignKey := ForeignKey{
 		ChildColumns:  schemaForeignKey.Columns,
 		ParentTable:   schemaForeignKey.References.Table,
@@ -47,7 +61,27 @@ func SchemaForeignKeyToForeignKey(schemaForeignKey *schemasv1alpha4.SQLTableFore
 	return &foreignKey
 }
 
-func GenerateFKName(tableName string, schemaForeignKey *schemasv1alpha4.SQLTableForeignKey) string {
+func PostgresqlSchemaForeignKeyToForeignKey(schemaForeignKey *schemasv1alpha4.PostgresqlTableForeignKey) *ForeignKey {
+	foreignKey := ForeignKey{
+		ChildColumns:  schemaForeignKey.Columns,
+		ParentTable:   schemaForeignKey.References.Table,
+		ParentColumns: schemaForeignKey.References.Columns,
+		Name:          schemaForeignKey.Name,
+		OnDelete:      schemaForeignKey.OnDelete,
+	}
+
+	return &foreignKey
+}
+
+func GenerateMysqlFKName(tableName string, schemaForeignKey *schemasv1alpha4.MysqlTableForeignKey) string {
+	if schemaForeignKey.Name != "" {
+		return schemaForeignKey.Name
+	}
+
+	return fmt.Sprintf("%s_%s_fkey", tableName, strings.Join(schemaForeignKey.Columns, "_"))
+}
+
+func GeneratePostgresqlFKName(tableName string, schemaForeignKey *schemasv1alpha4.PostgresqlTableForeignKey) string {
 	if schemaForeignKey.Name != "" {
 		return schemaForeignKey.Name
 	}
diff --git a/pkg/database/types/index.go b/pkg/database/types/index.go
index 8f098432..32fd3ed3 100644
--- a/pkg/database/types/index.go
+++ b/pkg/database/types/index.go
@@ -41,8 +41,8 @@ func (idx *Index) Equals(other *Index) bool {
 	return true
 }
 
-func IndexToSchemaIndex(index *Index) *schemasv1alpha4.SQLTableIndex {
-	schemaIndex := schemasv1alpha4.SQLTableIndex{
+func IndexToMysqlSchemaIndex(index *Index) *schemasv1alpha4.MysqlTableIndex {
+	schemaIndex := schemasv1alpha4.MysqlTableIndex{
 		Columns:  index.Columns,
 		Name:     index.Name,
 		IsUnique: index.IsUnique,
@@ -51,7 +51,27 @@ func IndexToSchemaIndex(index *Index) *schemasv1alpha4.SQLTableIndex {
 	return &schemaIndex
 }
 
-func SchemaIndexToIndex(schemaIndex *schemasv1alpha4.SQLTableIndex) *Index {
+func IndexToPostgresqlSchemaIndex(index *Index) *schemasv1alpha4.PostgresqlTableIndex {
+	schemaIndex := schemasv1alpha4.PostgresqlTableIndex{
+		Columns:  index.Columns,
+		Name:     index.Name,
+		IsUnique: index.IsUnique,
+	}
+
+	return &schemaIndex
+}
+
+func MysqlSchemaIndexToIndex(schemaIndex *schemasv1alpha4.MysqlTableIndex) *Index {
+	index := Index{
+		Columns:  schemaIndex.Columns,
+		Name:     schemaIndex.Name,
+		IsUnique: schemaIndex.IsUnique,
+	}
+
+	return &index
+}
+
+func PostgresqlSchemaIndexToIndex(schemaIndex *schemasv1alpha4.PostgresqlTableIndex) *Index {
 	index := Index{
 		Columns:  schemaIndex.Columns,
 		Name:     schemaIndex.Name,
@@ -61,6 +81,10 @@ func SchemaIndexToIndex(schemaIndex *schemasv1alpha4.SQLTableIndex) *Index {
 	return &index
 }
 
-func GenerateIndexName(tableName string, schemaIndex *schemasv1alpha4.SQLTableIndex) string {
+func GenerateMysqlIndexName(tableName string, schemaIndex *schemasv1alpha4.MysqlTableIndex) string {
+	return fmt.Sprintf("idx_%s_%s", tableName, strings.Join(schemaIndex.Columns, "_"))
+}
+
+func GeneratePostgresqlIndexName(tableName string, schemaIndex *schemasv1alpha4.PostgresqlTableIndex) string {
 	return fmt.Sprintf("idx_%s_%s", tableName, strings.Join(schemaIndex.Columns, "_"))
 }
diff --git a/pkg/generate/generate.go b/pkg/generate/generate.go
index 5cf2840d..d7597103 100644
--- a/pkg/generate/generate.go
+++ b/pkg/generate/generate.go
@@ -128,23 +128,23 @@ func generateTableYAML(driver string, dbName string, table *types.Table, primary
 		return generateMysqlTableYAML(dbName, table, primaryKey, foreignKeys, indexes, columns)
 	}
 
-	return generateGenericTableYAML(driver, dbName, table, primaryKey, foreignKeys, indexes, columns)
+	return generatePostgresqlTableYAML(driver, dbName, table, primaryKey, foreignKeys, indexes, columns)
 }
 
 func generateMysqlTableYAML(dbName string, table *types.Table, primaryKey []string, foreignKeys []*types.ForeignKey, indexes []*types.Index, columns []*types.Column) (string, error) {
-	schemaForeignKeys := make([]*schemasv1alpha4.SQLTableForeignKey, 0, 0)
+	schemaForeignKeys := make([]*schemasv1alpha4.MysqlTableForeignKey, 0, 0)
 	for _, foreignKey := range foreignKeys {
-		schemaForeignKey := types.ForeignKeyToSchemaForeignKey(foreignKey)
+		schemaForeignKey := types.ForeignKeyToMysqlSchemaForeignKey(foreignKey)
 		schemaForeignKeys = append(schemaForeignKeys, schemaForeignKey)
 	}
 
-	schemaIndexes := make([]*schemasv1alpha4.SQLTableIndex, 0, 0)
+	schemaIndexes := make([]*schemasv1alpha4.MysqlTableIndex, 0, 0)
 	for _, index := range indexes {
-		schemaIndex := types.IndexToSchemaIndex(index)
+		schemaIndex := types.IndexToMysqlSchemaIndex(index)
 		schemaIndexes = append(schemaIndexes, schemaIndex)
 	}
 
-	schemaTableColumns := make([]*schemasv1alpha4.MysqlSQLTableColumn, 0, 0)
+	schemaTableColumns := make([]*schemasv1alpha4.MysqlTableColumn, 0, 0)
 	for _, column := range columns {
 		schemaTableColumn, err := types.ColumnToMysqlSchemaColumn(column)
 		if err != nil {
@@ -155,7 +155,7 @@ func generateMysqlTableYAML(dbName string, table *types.Table, primaryKey []stri
 		schemaTableColumns = append(schemaTableColumns, schemaTableColumn)
 	}
 
-	tableSchema := &schemasv1alpha4.MysqlSQLTableSchema{
+	tableSchema := &schemasv1alpha4.MysqlTableSchema{
 		PrimaryKey:     primaryKey,
 		Columns:        schemaTableColumns,
 		ForeignKeys:    schemaForeignKeys,
@@ -198,22 +198,22 @@ metadata:
 
 }
 
-func generateGenericTableYAML(driver string, dbName string, table *types.Table, primaryKey []string, foreignKeys []*types.ForeignKey, indexes []*types.Index, columns []*types.Column) (string, error) {
-	schemaForeignKeys := make([]*schemasv1alpha4.SQLTableForeignKey, 0, 0)
+func generatePostgresqlTableYAML(driver string, dbName string, table *types.Table, primaryKey []string, foreignKeys []*types.ForeignKey, indexes []*types.Index, columns []*types.Column) (string, error) {
+	schemaForeignKeys := make([]*schemasv1alpha4.PostgresqlTableForeignKey, 0, 0)
 	for _, foreignKey := range foreignKeys {
-		schemaForeignKey := types.ForeignKeyToSchemaForeignKey(foreignKey)
+		schemaForeignKey := types.ForeignKeyToPostgresqlSchemaForeignKey(foreignKey)
 		schemaForeignKeys = append(schemaForeignKeys, schemaForeignKey)
 	}
 
-	schemaIndexes := make([]*schemasv1alpha4.SQLTableIndex, 0, 0)
+	schemaIndexes := make([]*schemasv1alpha4.PostgresqlTableIndex, 0, 0)
 	for _, index := range indexes {
-		schemaIndex := types.IndexToSchemaIndex(index)
+		schemaIndex := types.IndexToPostgresqlSchemaIndex(index)
 		schemaIndexes = append(schemaIndexes, schemaIndex)
 	}
 
-	schemaTableColumns := make([]*schemasv1alpha4.SQLTableColumn, 0, 0)
+	schemaTableColumns := make([]*schemasv1alpha4.PostgresqlTableColumn, 0, 0)
 	for _, column := range columns {
-		schemaTableColumn, err := types.ColumnToSchemaColumn(column)
+		schemaTableColumn, err := types.ColumnToPostgresqlSchemaColumn(column)
 		if err != nil {
 			fmt.Printf("%#v\n", err)
 			return "", err
@@ -222,7 +222,7 @@ func generateGenericTableYAML(driver string, dbName string, table *types.Table,
 		schemaTableColumns = append(schemaTableColumns, schemaTableColumn)
 	}
 
-	tableSchema := &schemasv1alpha4.SQLTableSchema{
+	tableSchema := &schemasv1alpha4.PostgresqlTableSchema{
 		PrimaryKey:  primaryKey,
 		Columns:     schemaTableColumns,
 		ForeignKeys: schemaForeignKeys,
diff --git a/pkg/installer/table_objects.go b/pkg/installer/table_objects.go
index 357dd1c5..df1c794c 100644
--- a/pkg/installer/table_objects.go
+++ b/pkg/installer/table_objects.go
@@ -90,9 +90,13 @@ spec:
                         comment:
                           type: string
                         compaction:
-                          type: string
+                          additionalProperties:
+                            type: string
+                          type: object
                         compression:
-                          type: string
+                          additionalProperties:
+                            type: string
+                          type: object
                         crcCheckChance:
                           type: string
                         dcLocalReadRepairChance:
@@ -186,6 +190,34 @@ spec:
                       type: array
                     isDeleted:
                       type: boolean
+                    json:triggers:
+                      items:
+                        properties:
+                          arguments:
+                            items:
+                              type: string
+                            type: array
+                          condition:
+                            type: string
+                          constraintTrigger:
+                            type: boolean
+                          events:
+                            items:
+                              type: string
+                            type: array
+                          executeProcedure:
+                            type: string
+                          forEachRun:
+                            type: boolean
+                          forEachStatement:
+                            type: boolean
+                          name:
+                            type: string
+                        required:
+                        - events
+                        - executeProcedure
+                        type: object
+                      type: array
                     primaryKey:
                       items:
                         type: string
@@ -350,6 +382,34 @@ spec:
                       type: array
                     isDeleted:
                       type: boolean
+                    json:triggers:
+                      items:
+                        properties:
+                          arguments:
+                            items:
+                              type: string
+                            type: array
+                          condition:
+                            type: string
+                          constraintTrigger:
+                            type: boolean
+                          events:
+                            items:
+                              type: string
+                            type: array
+                          executeProcedure:
+                            type: string
+                          forEachRun:
+                            type: boolean
+                          forEachStatement:
+                            type: boolean
+                          name:
+                            type: string
+                        required:
+                        - events
+                        - executeProcedure
+                        type: object
+                      type: array
                     primaryKey:
                       items:
                         type: string
@@ -476,9 +536,13 @@ spec:
                           comment:
                             type: string
                           compaction:
-                            type: string
+                            additionalProperties:
+                              type: string
+                            type: object
                           compression:
-                            type: string
+                            additionalProperties:
+                              type: string
+                            type: object
                           crcCheckChance:
                             type: string
                           dcLocalReadRepairChance:
@@ -572,6 +636,34 @@ spec:
                         type: array
                       isDeleted:
                         type: boolean
+                      json:triggers:
+                        items:
+                          properties:
+                            arguments:
+                              items:
+                                type: string
+                              type: array
+                            condition:
+                              type: string
+                            constraintTrigger:
+                              type: boolean
+                            events:
+                              items:
+                                type: string
+                              type: array
+                            executeProcedure:
+                              type: string
+                            forEachRun:
+                              type: boolean
+                            forEachStatement:
+                              type: boolean
+                            name:
+                              type: string
+                          required:
+                          - events
+                          - executeProcedure
+                          type: object
+                        type: array
                       primaryKey:
                         items:
                           type: string
@@ -736,6 +828,34 @@ spec:
                         type: array
                       isDeleted:
                         type: boolean
+                      json:triggers:
+                        items:
+                          properties:
+                            arguments:
+                              items:
+                                type: string
+                              type: array
+                            condition:
+                              type: string
+                            constraintTrigger:
+                              type: boolean
+                            events:
+                              items:
+                                type: string
+                              type: array
+                            executeProcedure:
+                              type: string
+                            forEachRun:
+                              type: boolean
+                            forEachStatement:
+                              type: boolean
+                            name:
+                              type: string
+                          required:
+                          - events
+                          - executeProcedure
+                          type: object
+                        type: array
                       primaryKey:
                         items:
                           type: string


Test patch:
diff --git a/pkg/apis/databases/v1alpha4/database_types_test.go b/pkg/apis/databases/v1alpha4/database_types_test.go
index a00e5f2e..0abf2fea 100644
--- a/pkg/apis/databases/v1alpha4/database_types_test.go
+++ b/pkg/apis/databases/v1alpha4/database_types_test.go
@@ -3,6 +3,7 @@ package v1alpha4
 import (
 	"testing"
 
+	"github.com/stretchr/testify/require"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -24,7 +25,9 @@ func TestVaultConnectionURI(t *testing.T) {
 							URI: ValueOrValueFrom{
 								ValueFrom: &ValueFrom{
 									Vault: &Vault{
-										Secret: "database/creds/test",
+										AgentInject: true,
+										Role:        "test",
+										Secret:      "database/creds/test",
 									},
 								},
 							},
@@ -48,7 +51,9 @@ postgres://{{ .Data.username }}:{{ .Data.password }}@postgres:5432/testdb{{- end
 							URI: ValueOrValueFrom{
 								ValueFrom: &ValueFrom{
 									Vault: &Vault{
-										Secret: "database/creds/test",
+										AgentInject: true,
+										Role:        "test",
+										Secret:      "database/creds/test",
 									},
 								},
 							},
@@ -58,7 +63,7 @@ postgres://{{ .Data.username }}:{{ .Data.password }}@postgres:5432/testdb{{- end
 			},
 			want: `
 {{- with secret "database/creds/test" -}}
-mysql://{{ .Data.username }}:{{ .Data.password }}@mysql:3306/testdb{{- end }}`,
+{{ .Data.username }}:{{ .Data.password }}@tcp(mysql:3306)/testdb{{- end }}`,
 		},
 		{
 			name: "CockroachDB",
@@ -72,7 +77,9 @@ mysql://{{ .Data.username }}:{{ .Data.password }}@mysql:3306/testdb{{- end }}`,
 							URI: ValueOrValueFrom{
 								ValueFrom: &ValueFrom{
 									Vault: &Vault{
-										Secret: "database/creds/test",
+										AgentInject: true,
+										Role:        "test",
+										Secret:      "database/creds/test",
 									},
 								},
 							},
@@ -88,14 +95,10 @@ postgres://{{ .Data.username }}:{{ .Data.password }}@postgres:5432/testdb{{- end
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			test := test
-			t.Parallel()
+			req := require.New(t)
 
 			a, err := test.db.GetVaultAnnotations()
-
-			if err != nil {
-				t.Fatal(err)
-			}
+			req.NoError(err)
 
 			if got := a["vault.hashicorp.com/agent-inject-template-schemaherouri"]; got != test.want {
 				t.Fatalf("Expected:\n%s\ngot:\n%s", test.want, got)
diff --git a/pkg/apis/schemas/v1alpha4/sql_types_test.go b/pkg/apis/schemas/v1alpha4/postgresql_types_test.go
similarity index 97%
rename from pkg/apis/schemas/v1alpha4/sql_types_test.go
rename to pkg/apis/schemas/v1alpha4/postgresql_types_test.go
index 0c7286f9..741945a7 100644
--- a/pkg/apis/schemas/v1alpha4/sql_types_test.go
+++ b/pkg/apis/schemas/v1alpha4/postgresql_types_test.go
@@ -44,7 +44,7 @@ foreignKeys:
 
 	g := gomega.NewGomegaWithT(t)
 
-	table := SQLTableSchema{}
+	table := PostgresqlTableSchema{}
 	err := yaml.Unmarshal([]byte(fk), &table)
 	g.Expect(err).NotTo(gomega.HaveOccurred())
 	g.Expect(table.Columns).To(gomega.HaveLen(2))
diff --git a/pkg/controller/table/reconcile_table_test.go b/pkg/controller/table/reconcile_table_test.go
index f8b5ec93..d44e7417 100644
--- a/pkg/controller/table/reconcile_table_test.go
+++ b/pkg/controller/table/reconcile_table_test.go
@@ -25,7 +25,7 @@ func Test_checkDatabaseTypeMatches(t *testing.T) {
 				},
 			},
 			tableSchema: schemasv1alpha4.TableSchema{
-				Postgres: &schemasv1alpha4.SQLTableSchema{},
+				Postgres: &schemasv1alpha4.PostgresqlTableSchema{},
 			},
 			expect: true,
 		},
@@ -39,7 +39,7 @@ func Test_checkDatabaseTypeMatches(t *testing.T) {
 				},
 			},
 			tableSchema: schemasv1alpha4.TableSchema{
-				Mysql: &schemasv1alpha4.MysqlSQLTableSchema{},
+				Mysql: &schemasv1alpha4.MysqlTableSchema{},
 			},
 			expect: true,
 		},
@@ -53,7 +53,7 @@ func Test_checkDatabaseTypeMatches(t *testing.T) {
 				},
 			},
 			tableSchema: schemasv1alpha4.TableSchema{
-				Postgres: &schemasv1alpha4.SQLTableSchema{},
+				Postgres: &schemasv1alpha4.PostgresqlTableSchema{},
 			},
 			expect: false,
 		},
@@ -67,7 +67,7 @@ func Test_checkDatabaseTypeMatches(t *testing.T) {
 				},
 			},
 			tableSchema: schemasv1alpha4.TableSchema{
-				Mysql: &schemasv1alpha4.MysqlSQLTableSchema{},
+				Mysql: &schemasv1alpha4.MysqlTableSchema{},
 			},
 			expect: false,
 		},
diff --git a/pkg/database/cassandra/create_test.go b/pkg/database/cassandra/create_test.go
index e78aa0fa..6191db3a 100644
--- a/pkg/database/cassandra/create_test.go
+++ b/pkg/database/cassandra/create_test.go
@@ -9,13 +9,13 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
-func Test_CreateTableStatement(t *testing.T) {
+func Test_CreateTableStatements(t *testing.T) {
 	tests := []struct {
-		name              string
-		keyspace          string
-		tableName         string
-		tableSchema       schemasv1alpha4.CassandraTableSchema
-		expectedStatement string
+		name               string
+		keyspace           string
+		tableName          string
+		tableSchema        schemasv1alpha4.CassandraTableSchema
+		expectedStatements []string
 	}{
 		{
 			name:      "simple",
@@ -29,7 +29,9 @@ func Test_CreateTableStatement(t *testing.T) {
 					},
 				},
 			},
-			expectedStatement: `create table t (a int)`,
+			expectedStatements: []string{
+				`create table "k.t" (a int)`,
+			},
 		},
 		{
 			name:      "with pk",
@@ -48,7 +50,9 @@ func Test_CreateTableStatement(t *testing.T) {
 					},
 				},
 			},
-			expectedStatement: `create table t (a int, primary key (a))`,
+			expectedStatements: []string{
+				`create table "k.t" (a int, primary key (a))`,
+			},
 		},
 		{
 			name:      "with compound pk",
@@ -74,7 +78,9 @@ func Test_CreateTableStatement(t *testing.T) {
 					},
 				},
 			},
-			expectedStatement: `create table t (a int, b int, primary key (a, b))`,
+			expectedStatements: []string{
+				`create table "k.t" (a int, b int, primary key (a, b))`,
+			},
 		},
 		{
 			name:      "with composite partition pk",
@@ -104,7 +110,9 @@ func Test_CreateTableStatement(t *testing.T) {
 					},
 				},
 			},
-			expectedStatement: `create table t (a int, b int, c int, primary key ((a, b), c))`,
+			expectedStatements: []string{
+				`create table "k.t" (a int, b int, c int, primary key ((a, b), c))`,
+			},
 		},
 		{
 			name:      "clustering order",
@@ -121,7 +129,9 @@ func Test_CreateTableStatement(t *testing.T) {
 					},
 				},
 			},
-			expectedStatement: `create table t (a int) with clustering order by (a)`,
+			expectedStatements: []string{
+				`create table "k.t" (a int) with clustering order by (a)`,
+			},
 		},
 		{
 			name:      "clustering order desc",
@@ -139,7 +149,9 @@ func Test_CreateTableStatement(t *testing.T) {
 					},
 				},
 			},
-			expectedStatement: `create table t (a int) with clustering order by (a desc)`,
+			expectedStatements: []string{
+				`create table "k.t" (a int) with clustering order by (a desc)`,
+			},
 		},
 	}
 
@@ -147,9 +159,9 @@ func Test_CreateTableStatement(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			req := require.New(t)
 
-			generatedStatement, err := CreateTableStatement(test.keyspace, test.tableName, &test.tableSchema)
+			generatedStatements, err := CreateTableStatements(test.keyspace, test.tableName, &test.tableSchema)
 			req.NoError(err)
-			assert.Equal(t, test.expectedStatement, generatedStatement)
+			assert.Equal(t, test.expectedStatements, generatedStatements)
 		})
 	}
 }
diff --git a/pkg/database/mysql/alter_test.go b/pkg/database/mysql/alter_test.go
index 4e027eec..c355af5b 100644
--- a/pkg/database/mysql/alter_test.go
+++ b/pkg/database/mysql/alter_test.go
@@ -17,14 +17,14 @@ func Test_AlterColumnStatment(t *testing.T) {
 	tests := []struct {
 		name               string
 		tableName          string
-		desiredColumns     []*schemasv1alpha4.MysqlSQLTableColumn
+		desiredColumns     []*schemasv1alpha4.MysqlTableColumn
 		existingColumn     *types.Column
 		expectedStatements []string
 	}{
 		{
 			name:      "no change",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "a",
 					Type: "integer",
@@ -44,7 +44,7 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "change data type",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "a",
 					Type: "integer",
@@ -64,7 +64,7 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "drop column",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "a",
 					Type: "integer",
@@ -80,11 +80,11 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "add not null constraint",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "a",
 					Type: "integer",
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 						NotNull: &trueValue,
 					},
 				},
@@ -102,11 +102,11 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "drop not null constraint",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "a",
 					Type: "integer",
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 						NotNull: &falseValue,
 					},
 				},
@@ -124,7 +124,7 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "no change to not null constraint",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "t",
 					Type: "text",
@@ -143,11 +143,11 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "type change, constraint no change",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "a",
 					Type: "integer",
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 						NotNull: &trueValue,
 					},
 				},
@@ -165,7 +165,7 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "default set",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name:    "a",
 					Type:    "integer",
@@ -181,7 +181,7 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "default unset",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "a",
 					Type: "integer",
@@ -197,7 +197,7 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "default empty string",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name:    "a",
 					Type:    "varchar (32)",
@@ -214,11 +214,11 @@ func Test_AlterColumnStatment(t *testing.T) {
 		// {
 		// 	name:      "no change to not nullable timestamp using short column type",
 		// 	tableName: "ts",
-		// 	desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
-		// 		&schemasv1alpha4.MysqlSQLTableColumn{
+		// 	desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
+		// 		&schemasv1alpha4.MysqlTableColumn{
 		// 			Name: "ts",
 		// 			Type: "timestamp",
-		// 			Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+		// 			Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 		// 				NotNull: &trueValue,
 		// 			},
 		// 		},
@@ -236,11 +236,11 @@ func Test_AlterColumnStatment(t *testing.T) {
 		// {
 		// 	name:      "no change to not nullable timestamp",
 		// 	tableName: "ts",
-		// 	desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
-		// 		&schemasv1alpha4.MysqlSQLTableColumn{
+		// 	desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
+		// 		&schemasv1alpha4.MysqlTableColumn{
 		// 			Name: "ts",
 		// 			Type: "timestamp with time zone",
-		// 			Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+		// 			Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 		// 				NotNull: &trueValue,
 		// 			},
 		// 		},
@@ -258,12 +258,12 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "add null and default",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name:    "a",
 					Type:    "varchar (255)",
 					Default: &defaultEleven,
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 						NotNull: &trueValue,
 					},
 				},
@@ -281,14 +281,14 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "add auto_increment attibute",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "c",
 					Type: "integer",
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 						NotNull: &trueValue,
 					},
-					Attributes: &schemasv1alpha4.SQLTableColumnAttributes{
+					Attributes: &schemasv1alpha4.MysqlTableColumnAttributes{
 						AutoIncrement: &trueValue,
 					},
 				},
@@ -307,11 +307,11 @@ func Test_AlterColumnStatment(t *testing.T) {
 		{
 			name:      "drop auto_increment attibute",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.MysqlTableColumn{
 				{
 					Name: "c",
 					Type: "integer",
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 						NotNull: &trueValue,
 					},
 				},
diff --git a/pkg/database/mysql/column_test.go b/pkg/database/mysql/column_test.go
index 61351f0e..fceb8f3e 100644
--- a/pkg/database/mysql/column_test.go
+++ b/pkg/database/mysql/column_test.go
@@ -14,15 +14,15 @@ func Test_mysqlColumnAsInsert(t *testing.T) {
 	default11 := "11"
 	tests := []struct {
 		name              string
-		column            *schemasv1alpha4.MysqlSQLTableColumn
+		column            *schemasv1alpha4.MysqlTableColumn
 		expectedStatement string
 	}{
 		{
 			name: "simple",
-			column: &schemasv1alpha4.MysqlSQLTableColumn{
+			column: &schemasv1alpha4.MysqlTableColumn{
 				Name: "c",
 				Type: "integer",
-				Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+				Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 					NotNull: &trueValue,
 				},
 				Default: &default11,
@@ -31,13 +31,13 @@ func Test_mysqlColumnAsInsert(t *testing.T) {
 		},
 		{
 			name: "auto_increment",
-			column: &schemasv1alpha4.MysqlSQLTableColumn{
+			column: &schemasv1alpha4.MysqlTableColumn{
 				Name: "c",
 				Type: "integer",
-				Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+				Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 					NotNull: &trueValue,
 				},
-				Attributes: &schemasv1alpha4.SQLTableColumnAttributes{
+				Attributes: &schemasv1alpha4.MysqlTableColumnAttributes{
 					AutoIncrement: &trueValue,
 				},
 			},
@@ -45,7 +45,7 @@ func Test_mysqlColumnAsInsert(t *testing.T) {
 		},
 		{
 			name: "charset and collation",
-			column: &schemasv1alpha4.MysqlSQLTableColumn{
+			column: &schemasv1alpha4.MysqlTableColumn{
 				Name:      "c",
 				Type:      "varchar(255)",
 				Charset:   "latin1",
@@ -55,10 +55,10 @@ func Test_mysqlColumnAsInsert(t *testing.T) {
 		},
 		{
 			name: "charset and collation not null default",
-			column: &schemasv1alpha4.MysqlSQLTableColumn{
+			column: &schemasv1alpha4.MysqlTableColumn{
 				Name: "c",
 				Type: "varchar(255)",
-				Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+				Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 					NotNull: &trueValue,
 				},
 				Default:   &default11,
@@ -84,13 +84,13 @@ func Test_InsertColumnStatement(t *testing.T) {
 	tests := []struct {
 		name              string
 		tableName         string
-		desiredColumn     *schemasv1alpha4.MysqlSQLTableColumn
+		desiredColumn     *schemasv1alpha4.MysqlTableColumn
 		expectedStatement string
 	}{
 		{
 			name:      "add column",
 			tableName: "t",
-			desiredColumn: &schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumn: &schemasv1alpha4.MysqlTableColumn{
 				Name: "a",
 				Type: "integer",
 			},
@@ -99,10 +99,10 @@ func Test_InsertColumnStatement(t *testing.T) {
 		{
 			name:      "add not null column",
 			tableName: "t",
-			desiredColumn: &schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumn: &schemasv1alpha4.MysqlTableColumn{
 				Name: "a",
 				Type: "integer",
-				Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+				Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 					NotNull: &trueValue,
 				},
 			},
@@ -111,10 +111,10 @@ func Test_InsertColumnStatement(t *testing.T) {
 		{
 			name:      "add null column",
 			tableName: "t",
-			desiredColumn: &schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumn: &schemasv1alpha4.MysqlTableColumn{
 				Name: "a",
 				Type: "integer",
-				Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+				Constraints: &schemasv1alpha4.MysqlTableColumnConstraints{
 					NotNull: &falseValue,
 				},
 			},
@@ -123,10 +123,10 @@ func Test_InsertColumnStatement(t *testing.T) {
 		{
 			name:      "add auto_increment column",
 			tableName: "t",
-			desiredColumn: &schemasv1alpha4.MysqlSQLTableColumn{
+			desiredColumn: &schemasv1alpha4.MysqlTableColumn{
 				Name: "a",
 				Type: "integer",
-				Attributes: &schemasv1alpha4.SQLTableColumnAttributes{
+				Attributes: &schemasv1alpha4.MysqlTableColumnAttributes{
 					AutoIncrement: &trueValue,
 				},
 			},
@@ -148,12 +148,12 @@ func Test_InsertColumnStatement(t *testing.T) {
 func Test_schemaColumnToMysqlColumn(t *testing.T) {
 	tests := []struct {
 		name           string
-		schemaColumn   *schemasv1alpha4.MysqlSQLTableColumn
+		schemaColumn   *schemasv1alpha4.MysqlTableColumn
 		expectedColumn *types.Column
 	}{
 		{
 			name: "varchar (10)",
-			schemaColumn: &schemasv1alpha4.MysqlSQLTableColumn{
+			schemaColumn: &schemasv1alpha4.MysqlTableColumn{
 				Name: "vc",
 				Type: "varchar (10)",
 			},
@@ -165,7 +165,7 @@ func Test_schemaColumnToMysqlColumn(t *testing.T) {
 		},
 		{
 			name: "bool",
-			schemaColumn: &schemasv1alpha4.MysqlSQLTableColumn{
+			schemaColumn: &schemasv1alpha4.MysqlTableColumn{
 				Name: "b",
 				Type: "bool",
 			},
@@ -177,10 +177,10 @@ func Test_schemaColumnToMysqlColumn(t *testing.T) {
 		},
 		{
 			name: "auto_increment",
-			schemaColumn: &schemasv1alpha4.MysqlSQLTableColumn{
+			schemaColumn: &schemasv1alpha4.MysqlTableColumn{
 				Name: "c",
 				Type: "integer (11)",
-				Attributes: &schemasv1alpha4.SQLTableColumnAttributes{
+				Attributes: &schemasv1alpha4.MysqlTableColumnAttributes{
 					AutoIncrement: &trueValue,
 				},
 			},
diff --git a/pkg/database/mysql/create_test.go b/pkg/database/mysql/create_test.go
index 549b6c7d..257fbda2 100644
--- a/pkg/database/mysql/create_test.go
+++ b/pkg/database/mysql/create_test.go
@@ -11,35 +11,37 @@ import (
 
 func Test_CreateTableStatement(t *testing.T) {
 	tests := []struct {
-		name              string
-		tableSchema       *schemasv1alpha4.MysqlSQLTableSchema
-		tableName         string
-		expectedStatement string
+		name               string
+		tableSchema        *schemasv1alpha4.MysqlTableSchema
+		tableName          string
+		expectedStatements []string
 	}{
 		{
 			name: "simple",
-			tableSchema: &schemasv1alpha4.MysqlSQLTableSchema{
+			tableSchema: &schemasv1alpha4.MysqlTableSchema{
 				PrimaryKey: []string{
 					"id",
 				},
-				Columns: []*schemasv1alpha4.MysqlSQLTableColumn{
+				Columns: []*schemasv1alpha4.MysqlTableColumn{
 					{
 						Name: "id",
 						Type: "integer",
 					},
 				},
 			},
-			tableName:         "simple",
-			expectedStatement: "create table `simple` (`id` int (11), primary key (`id`))",
+			tableName: "simple",
+			expectedStatements: []string{
+				"create table `simple` (`id` int (11), primary key (`id`))",
+			},
 		},
 		{
 			name: "varchar composite primary key",
-			tableSchema: &schemasv1alpha4.MysqlSQLTableSchema{
+			tableSchema: &schemasv1alpha4.MysqlTableSchema{
 				PrimaryKey: []string{
 					"col_a",
 					"col_b",
 				},
-				Columns: []*schemasv1alpha4.MysqlSQLTableColumn{
+				Columns: []*schemasv1alpha4.MysqlTableColumn{
 					{
 						Name: "col_a",
 						Type: "char (36)",
@@ -50,17 +52,19 @@ func Test_CreateTableStatement(t *testing.T) {
 					},
 				},
 			},
-			tableName:         "table_b",
-			expectedStatement: "create table `table_b` (`col_a` char (36), `col_b` varchar (255), primary key (`col_a`, `col_b`))",
+			tableName: "table_b",
+			expectedStatements: []string{
+				"create table `table_b` (`col_a` char (36), `col_b` varchar (255), primary key (`col_a`, `col_b`))",
+			},
 		},
 		{
 			name: "composite primary key",
-			tableSchema: &schemasv1alpha4.MysqlSQLTableSchema{
+			tableSchema: &schemasv1alpha4.MysqlTableSchema{
 				PrimaryKey: []string{
 					"one",
 					"two",
 				},
-				Columns: []*schemasv1alpha4.MysqlSQLTableColumn{
+				Columns: []*schemasv1alpha4.MysqlTableColumn{
 					{
 						Name: "one",
 						Type: "integer",
@@ -75,16 +79,18 @@ func Test_CreateTableStatement(t *testing.T) {
 					},
 				},
 			},
-			tableName:         "composite_primary_key",
-			expectedStatement: "create table `composite_primary_key` (`one` int (11), `two` int (11), `three` varchar (255), primary key (`one`, `two`))",
+			tableName: "composite_primary_key",
+			expectedStatements: []string{
+				"create table `composite_primary_key` (`one` int (11), `two` int (11), `three` varchar (255), primary key (`one`, `two`))",
+			},
 		},
 		{
 			name: "decimal (8, 2) column",
-			tableSchema: &schemasv1alpha4.MysqlSQLTableSchema{
+			tableSchema: &schemasv1alpha4.MysqlTableSchema{
 				PrimaryKey: []string{
 					"one",
 				},
-				Columns: []*schemasv1alpha4.MysqlSQLTableColumn{
+				Columns: []*schemasv1alpha4.MysqlTableColumn{
 					{
 						Name: "one",
 						Type: "integer",
@@ -95,16 +101,18 @@ func Test_CreateTableStatement(t *testing.T) {
 					},
 				},
 			},
-			tableName:         "decimal_8_2",
-			expectedStatement: "create table `decimal_8_2` (`one` int (11), `bee` decimal (8, 2), primary key (`one`))",
+			tableName: "decimal_8_2",
+			expectedStatements: []string{
+				"create table `decimal_8_2` (`one` int (11), `bee` decimal (8, 2), primary key (`one`))",
+			},
 		},
 		{
 			name: "table with default charset and collate",
-			tableSchema: &schemasv1alpha4.MysqlSQLTableSchema{
+			tableSchema: &schemasv1alpha4.MysqlTableSchema{
 				PrimaryKey: []string{
 					"id",
 				},
-				Columns: []*schemasv1alpha4.MysqlSQLTableColumn{
+				Columns: []*schemasv1alpha4.MysqlTableColumn{
 					{
 						Name: "id",
 						Type: "integer",
@@ -113,16 +121,18 @@ func Test_CreateTableStatement(t *testing.T) {
 				DefaultCharset: "latin1",
 				Collation:      "latin1_german1_ci",
 			},
-			tableName:         "test",
-			expectedStatement: "create table `test` (`id` int (11), primary key (`id`)) default character set latin1 collate latin1_german1_ci",
+			tableName: "test",
+			expectedStatements: []string{
+				"create table `test` (`id` int (11), primary key (`id`)) default character set latin1 collate latin1_german1_ci",
+			},
 		},
 		{
 			name: "table with default charset without collate",
-			tableSchema: &schemasv1alpha4.MysqlSQLTableSchema{
+			tableSchema: &schemasv1alpha4.MysqlTableSchema{
 				PrimaryKey: []string{
 					"id",
 				},
-				Columns: []*schemasv1alpha4.MysqlSQLTableColumn{
+				Columns: []*schemasv1alpha4.MysqlTableColumn{
 					{
 						Name: "id",
 						Type: "integer",
@@ -130,16 +140,18 @@ func Test_CreateTableStatement(t *testing.T) {
 				},
 				DefaultCharset: "latin1",
 			},
-			tableName:         "test",
-			expectedStatement: "create table `test` (`id` int (11), primary key (`id`)) default character set latin1",
+			tableName: "test",
+			expectedStatements: []string{
+				"create table `test` (`id` int (11), primary key (`id`)) default character set latin1",
+			},
 		},
 		{
 			name: "table with collate and no default character set",
-			tableSchema: &schemasv1alpha4.MysqlSQLTableSchema{
+			tableSchema: &schemasv1alpha4.MysqlTableSchema{
 				PrimaryKey: []string{
 					"id",
 				},
-				Columns: []*schemasv1alpha4.MysqlSQLTableColumn{
+				Columns: []*schemasv1alpha4.MysqlTableColumn{
 					{
 						Name: "id",
 						Type: "integer",
@@ -147,8 +159,10 @@ func Test_CreateTableStatement(t *testing.T) {
 				},
 				Collation: "latin1_german1_ci",
 			},
-			tableName:         "test",
-			expectedStatement: "create table `test` (`id` int (11), primary key (`id`)) collate latin1_german1_ci",
+			tableName: "test",
+			expectedStatements: []string{
+				"create table `test` (`id` int (11), primary key (`id`)) collate latin1_german1_ci",
+			},
 		},
 	}
 
@@ -156,10 +170,10 @@ func Test_CreateTableStatement(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			req := require.New(t)
 
-			createTableStatement, err := CreateTableStatement(test.tableName, test.tableSchema)
+			createTableStatements, err := CreateTableStatements(test.tableName, test.tableSchema)
 			req.NoError(err)
 
-			assert.Equal(t, test.expectedStatement, createTableStatement)
+			assert.Equal(t, test.expectedStatements, createTableStatements)
 		})
 	}
 }
diff --git a/pkg/database/mysql/foreignkey_test.go b/pkg/database/mysql/foreignkey_test.go
index a92100bb..8a0a73c3 100644
--- a/pkg/database/mysql/foreignkey_test.go
+++ b/pkg/database/mysql/foreignkey_test.go
@@ -12,17 +12,17 @@ func Test_AddForeignKeyStatement(t *testing.T) {
 	tests := []struct {
 		name              string
 		tableName         string
-		schemaForeignKey  *schemasv1alpha4.SQLTableForeignKey
+		schemaForeignKey  *schemasv1alpha4.MysqlTableForeignKey
 		expectedStatement string
 	}{
 		{
 			name:      "no name, one column, no on delete",
 			tableName: "t2",
-			schemaForeignKey: &schemasv1alpha4.SQLTableForeignKey{
+			schemaForeignKey: &schemasv1alpha4.MysqlTableForeignKey{
 				Columns: []string{
 					"c2",
 				},
-				References: schemasv1alpha4.SQLTableForeignKeyReferences{
+				References: schemasv1alpha4.MysqlTableForeignKeyReferences{
 					Table: "t1",
 					Columns: []string{
 						"c1",
@@ -34,12 +34,12 @@ func Test_AddForeignKeyStatement(t *testing.T) {
 		{
 			name:      "named, one column, no on delete",
 			tableName: "t2",
-			schemaForeignKey: &schemasv1alpha4.SQLTableForeignKey{
+			schemaForeignKey: &schemasv1alpha4.MysqlTableForeignKey{
 				Name: "hi_i_am_a_fkey",
 				Columns: []string{
 					"c2",
 				},
-				References: schemasv1alpha4.SQLTableForeignKeyReferences{
+				References: schemasv1alpha4.MysqlTableForeignKeyReferences{
 					Table: "t1",
 					Columns: []string{
 						"c1",
@@ -51,12 +51,12 @@ func Test_AddForeignKeyStatement(t *testing.T) {
 		{
 			name:      "no name, two columns, no on delete",
 			tableName: "t2",
-			schemaForeignKey: &schemasv1alpha4.SQLTableForeignKey{
+			schemaForeignKey: &schemasv1alpha4.MysqlTableForeignKey{
 				Columns: []string{
 					"c2",
 					"c22",
 				},
-				References: schemasv1alpha4.SQLTableForeignKeyReferences{
+				References: schemasv1alpha4.MysqlTableForeignKeyReferences{
 					Table: "t1",
 					Columns: []string{
 						"c1",
@@ -69,12 +69,12 @@ func Test_AddForeignKeyStatement(t *testing.T) {
 		{
 			name:      "no name, one column, on delete cascade",
 			tableName: "t2",
-			schemaForeignKey: &schemasv1alpha4.SQLTableForeignKey{
+			schemaForeignKey: &schemasv1alpha4.MysqlTableForeignKey{
 				OnDelete: "cascade",
 				Columns: []string{
 					"c2",
 				},
-				References: schemasv1alpha4.SQLTableForeignKeyReferences{
+				References: schemasv1alpha4.MysqlTableForeignKeyReferences{
 					Table: "t1",
 					Columns: []string{
 						"c1",
diff --git a/pkg/database/postgres/alter_test.go b/pkg/database/postgres/alter_test.go
index a9a8247a..956d8877 100644
--- a/pkg/database/postgres/alter_test.go
+++ b/pkg/database/postgres/alter_test.go
@@ -17,19 +17,19 @@ func Test_AlterColumnStatments(t *testing.T) {
 	tests := []struct {
 		name               string
 		tableName          string
-		desiredColumns     []*schemasv1alpha4.SQLTableColumn
+		desiredColumns     []*schemasv1alpha4.PostgresqlTableColumn
 		existingColumn     *types.Column
 		expectedStatements []string
 	}{
 		{
 			name:      "no change",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "a",
 					Type: "integer",
 				},
-				&schemasv1alpha4.SQLTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "b",
 					Type: "integer",
 				},
@@ -44,8 +44,8 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "no change varchar",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "a",
 					Type: "varchar(32)",
 				},
@@ -59,12 +59,12 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "change data type",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "a",
 					Type: "integer",
 				},
-				&schemasv1alpha4.SQLTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "b",
 					Type: "integer",
 				},
@@ -79,8 +79,8 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "drop column",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "a",
 					Type: "integer",
 				},
@@ -95,11 +95,11 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "add not null constraint",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
 				{
 					Name: "a",
 					Type: "integer",
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.PostgresqlTableColumnConstraints{
 						NotNull: &trueValue,
 					},
 				},
@@ -117,11 +117,11 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "drop not null constraint",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "a",
 					Type: "integer",
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.PostgresqlTableColumnConstraints{
 						NotNull: &falseValue,
 					},
 				},
@@ -139,8 +139,8 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "no change to not null constraint",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "t",
 					Type: "text",
 				},
@@ -158,11 +158,11 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "no change to not nullable timestamp using short column type",
 			tableName: "ts",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "ts",
 					Type: "timestamp",
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.PostgresqlTableColumnConstraints{
 						NotNull: &trueValue,
 					},
 				},
@@ -180,11 +180,11 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "no change to not nullable timestamp",
 			tableName: "ts",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "ts",
 					Type: "timestamp with time zone",
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.PostgresqlTableColumnConstraints{
 						NotNull: &trueValue,
 					},
 				},
@@ -202,8 +202,8 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "default set",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name:    "a",
 					Type:    "integer",
 					Default: &defaultEleven,
@@ -218,8 +218,8 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "default unset",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name: "a",
 					Type: "integer",
 				},
@@ -234,8 +234,8 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "default empty string",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
-				&schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
+				&schemasv1alpha4.PostgresqlTableColumn{
 					Name:    "a",
 					Type:    "varchar (32)",
 					Default: &defaultEmpty,
@@ -250,12 +250,12 @@ func Test_AlterColumnStatments(t *testing.T) {
 		{
 			name:      "add null and default",
 			tableName: "t",
-			desiredColumns: []*schemasv1alpha4.SQLTableColumn{
+			desiredColumns: []*schemasv1alpha4.PostgresqlTableColumn{
 				{
 					Name:    "a",
 					Type:    "varchar (32)",
 					Default: &defaultEleven,
-					Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+					Constraints: &schemasv1alpha4.PostgresqlTableColumnConstraints{
 						NotNull: &trueValue,
 					},
 				},
diff --git a/pkg/database/postgres/column_test.go b/pkg/database/postgres/column_test.go
index 6d4d793a..45ad9fc7 100644
--- a/pkg/database/postgres/column_test.go
+++ b/pkg/database/postgres/column_test.go
@@ -10,16 +10,16 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
-func Test_postgresColumnAsInsert(t *testing.T) {
+func Test_columnAsInsert(t *testing.T) {
 	default11 := "11"
 	tests := []struct {
 		name              string
-		column            *schemasv1alpha4.SQLTableColumn
+		column            *schemasv1alpha4.PostgresqlTableColumn
 		expectedStatement string
 	}{
 		{
 			name: "simple",
-			column: &schemasv1alpha4.SQLTableColumn{
+			column: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "c",
 				Type: "integer",
 			},
@@ -27,7 +27,7 @@ func Test_postgresColumnAsInsert(t *testing.T) {
 		},
 		{
 			name: "text",
-			column: &schemasv1alpha4.SQLTableColumn{
+			column: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "t",
 				Type: "text",
 			},
@@ -35,7 +35,7 @@ func Test_postgresColumnAsInsert(t *testing.T) {
 		},
 		{
 			name: "timestamp without time zone",
-			column: &schemasv1alpha4.SQLTableColumn{
+			column: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "t",
 				Type: "timestamp without time zone",
 			},
@@ -43,7 +43,7 @@ func Test_postgresColumnAsInsert(t *testing.T) {
 		},
 		{
 			name: "character varying (4)",
-			column: &schemasv1alpha4.SQLTableColumn{
+			column: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "c",
 				Type: "character varying (4)",
 			},
@@ -51,10 +51,10 @@ func Test_postgresColumnAsInsert(t *testing.T) {
 		},
 		{
 			name: "constraint not null",
-			column: &schemasv1alpha4.SQLTableColumn{
+			column: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "c",
 				Type: "integer",
-				Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+				Constraints: &schemasv1alpha4.PostgresqlTableColumnConstraints{
 					NotNull: &trueValue,
 				},
 			},
@@ -62,7 +62,7 @@ func Test_postgresColumnAsInsert(t *testing.T) {
 		},
 		{
 			name: "default",
-			column: &schemasv1alpha4.SQLTableColumn{
+			column: &schemasv1alpha4.PostgresqlTableColumn{
 				Name:    "c",
 				Type:    "integer",
 				Default: &default11,
@@ -71,7 +71,7 @@ func Test_postgresColumnAsInsert(t *testing.T) {
 		},
 		{
 			name: "text[]",
-			column: &schemasv1alpha4.SQLTableColumn{
+			column: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "c",
 				Type: "text[]",
 			},
@@ -83,7 +83,7 @@ func Test_postgresColumnAsInsert(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			req := require.New(t)
 
-			generatedStatement, err := postgresColumnAsInsert(test.column)
+			generatedStatement, err := columnAsInsert(test.column)
 			req.NoError(err)
 			assert.Equal(t, test.expectedStatement, generatedStatement)
 		})
@@ -94,13 +94,13 @@ func Test_InsertColumnStatement(t *testing.T) {
 	tests := []struct {
 		name              string
 		tableName         string
-		desiredColumn     *schemasv1alpha4.SQLTableColumn
+		desiredColumn     *schemasv1alpha4.PostgresqlTableColumn
 		expectedStatement string
 	}{
 		{
 			name:      "add column",
 			tableName: "t",
-			desiredColumn: &schemasv1alpha4.SQLTableColumn{
+			desiredColumn: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "a",
 				Type: "integer",
 			},
@@ -109,10 +109,10 @@ func Test_InsertColumnStatement(t *testing.T) {
 		{
 			name:      "add not null column",
 			tableName: "t",
-			desiredColumn: &schemasv1alpha4.SQLTableColumn{
+			desiredColumn: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "a",
 				Type: "integer",
-				Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+				Constraints: &schemasv1alpha4.PostgresqlTableColumnConstraints{
 					NotNull: &trueValue,
 				},
 			},
@@ -121,10 +121,10 @@ func Test_InsertColumnStatement(t *testing.T) {
 		{
 			name:      "add null column",
 			tableName: "t",
-			desiredColumn: &schemasv1alpha4.SQLTableColumn{
+			desiredColumn: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "a",
 				Type: "integer",
-				Constraints: &schemasv1alpha4.SQLTableColumnConstraints{
+				Constraints: &schemasv1alpha4.PostgresqlTableColumnConstraints{
 					NotNull: &falseValue,
 				},
 			},
@@ -146,12 +146,12 @@ func Test_InsertColumnStatement(t *testing.T) {
 func Test_schemaColumnToPostgresColumn(t *testing.T) {
 	tests := []struct {
 		name           string
-		schemaColumn   *schemasv1alpha4.SQLTableColumn
+		schemaColumn   *schemasv1alpha4.PostgresqlTableColumn
 		expectedColumn *types.Column
 	}{
 		{
 			name: "text",
-			schemaColumn: &schemasv1alpha4.SQLTableColumn{
+			schemaColumn: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "t",
 				Type: "text",
 			},
@@ -164,7 +164,7 @@ func Test_schemaColumnToPostgresColumn(t *testing.T) {
 		},
 		{
 			name: "character varying (10)",
-			schemaColumn: &schemasv1alpha4.SQLTableColumn{
+			schemaColumn: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "c",
 				Type: "character varying (10)",
 			},
@@ -176,7 +176,7 @@ func Test_schemaColumnToPostgresColumn(t *testing.T) {
 		},
 		{
 			name: "varchar (10)",
-			schemaColumn: &schemasv1alpha4.SQLTableColumn{
+			schemaColumn: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "vc",
 				Type: "varchar (10)",
 			},
@@ -188,7 +188,7 @@ func Test_schemaColumnToPostgresColumn(t *testing.T) {
 		},
 		{
 			name: "cidr",
-			schemaColumn: &schemasv1alpha4.SQLTableColumn{
+			schemaColumn: &schemasv1alpha4.PostgresqlTableColumn{
 				Name: "ip",
 				Type: "cidr",
 			},
diff --git a/pkg/database/postgres/create_test.go b/pkg/database/postgres/create_test.go
index 4b93dd9f..800fb4be 100644
--- a/pkg/database/postgres/create_test.go
+++ b/pkg/database/postgres/create_test.go
@@ -11,81 +11,116 @@ import (
 
 func Test_CreateTableStatement(t *testing.T) {
 	tests := []struct {
-		name              string
-		tableSchema       *schemasv1alpha4.SQLTableSchema
-		tableName         string
-		expectedStatement string
+		name               string
+		tableSchema        *schemasv1alpha4.PostgresqlTableSchema
+		tableName          string
+		expectedStatements []string
 	}{
 		{
 			name: "simple",
-			tableSchema: &schemasv1alpha4.SQLTableSchema{
+			tableSchema: &schemasv1alpha4.PostgresqlTableSchema{
 				PrimaryKey: []string{
 					"id",
 				},
-				Columns: []*schemasv1alpha4.SQLTableColumn{
-					&schemasv1alpha4.SQLTableColumn{
+				Columns: []*schemasv1alpha4.PostgresqlTableColumn{
+					{
 						Name: "id",
 						Type: "integer",
 					},
 				},
 			},
-			tableName:         "simple",
-			expectedStatement: `create table "simple" ("id" integer, primary key ("id"))`,
+			tableName: "simple",
+			expectedStatements: []string{
+				`create table "simple" ("id" integer, primary key ("id"))`,
+			},
 		},
 		{
 			name: "composite primary key",
-			tableSchema: &schemasv1alpha4.SQLTableSchema{
+			tableSchema: &schemasv1alpha4.PostgresqlTableSchema{
 				PrimaryKey: []string{
 					"one",
 					"two",
 				},
-				Columns: []*schemasv1alpha4.SQLTableColumn{
-					&schemasv1alpha4.SQLTableColumn{
+				Columns: []*schemasv1alpha4.PostgresqlTableColumn{
+					{
 						Name: "one",
 						Type: "integer",
 					},
-					&schemasv1alpha4.SQLTableColumn{
+					{
 						Name: "two",
 						Type: "integer",
 					},
-					&schemasv1alpha4.SQLTableColumn{
+					{
 						Name: "three",
 						Type: "varchar(255)",
 					},
 				},
 			},
-			tableName:         "composite_primary_key",
-			expectedStatement: `create table "composite_primary_key" ("one" integer, "two" integer, "three" character varying (255), primary key ("one", "two"))`,
+			tableName: "composite_primary_key",
+			expectedStatements: []string{
+				`create table "composite_primary_key" ("one" integer, "two" integer, "three" character varying (255), primary key ("one", "two"))`,
+			},
 		},
 		{
 			name: "composite unique index",
-			tableSchema: &schemasv1alpha4.SQLTableSchema{
+			tableSchema: &schemasv1alpha4.PostgresqlTableSchema{
 				PrimaryKey: []string{
 					"one",
 				},
-				Indexes: []*schemasv1alpha4.SQLTableIndex{
-					&schemasv1alpha4.SQLTableIndex{
+				Indexes: []*schemasv1alpha4.PostgresqlTableIndex{
+					{
 						Columns:  []string{"two", "three"},
 						IsUnique: true,
 					},
 				},
-				Columns: []*schemasv1alpha4.SQLTableColumn{
-					&schemasv1alpha4.SQLTableColumn{
+				Columns: []*schemasv1alpha4.PostgresqlTableColumn{
+					{
 						Name: "one",
 						Type: "integer",
 					},
-					&schemasv1alpha4.SQLTableColumn{
+					{
 						Name: "two",
 						Type: "integer",
 					},
-					&schemasv1alpha4.SQLTableColumn{
+					{
 						Name: "three",
 						Type: "varchar(255)",
 					},
 				},
 			},
-			tableName:         "composite_unique_index",
-			expectedStatement: `create table "composite_unique_index" ("one" integer, "two" integer, "three" character varying (255), primary key ("one"), constraint "idx_composite_unique_index_two_three" unique ("two", "three"))`,
+			tableName: "composite_unique_index",
+			expectedStatements: []string{
+				`create table "composite_unique_index" ("one" integer, "two" integer, "three" character varying (255), primary key ("one"), constraint "idx_composite_unique_index_two_three" unique ("two", "three"))`,
+			},
+		},
+		{
+			name: "simple with trigger",
+			tableSchema: &schemasv1alpha4.PostgresqlTableSchema{
+				PrimaryKey: []string{
+					"id",
+				},
+				Columns: []*schemasv1alpha4.PostgresqlTableColumn{
+					{
+						Name: "id",
+						Type: "integer",
+					},
+				},
+				Triggers: []*schemasv1alpha4.PostgresqlTableTrigger{
+					{
+						Name: "tgr",
+						Events: []string{
+							"after insert",
+						},
+						ForEachRow:       &trueValue,
+						ExecuteProcedure: "test()",
+					},
+				},
+			},
+			tableName: "simple",
+			expectedStatements: []string{
+				`create table "simple" ("id" integer, primary key ("id"))`,
+				`create trigger "tgr" after insert on "simple" for each row execute procedure test()`,
+			},
 		},
 	}
 
@@ -93,10 +128,10 @@ func Test_CreateTableStatement(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			req := require.New(t)
 
-			createTableStatement, err := CreateTableStatement(test.tableName, test.tableSchema)
+			createTableStatements, err := CreateTableStatements(test.tableName, test.tableSchema)
 			req.NoError(err)
 
-			assert.Equal(t, test.expectedStatement, createTableStatement)
+			assert.Equal(t, test.expectedStatements, createTableStatements)
 		})
 	}
 }
diff --git a/pkg/database/postgres/foreignkey_test.go b/pkg/database/postgres/foreignkey_test.go
index e5aee508..1c1827a9 100644
--- a/pkg/database/postgres/foreignkey_test.go
+++ b/pkg/database/postgres/foreignkey_test.go
@@ -12,17 +12,17 @@ func Test_AddForeignKeyStatement(t *testing.T) {
 	tests := []struct {
 		name              string
 		tableName         string
-		schemaForeignKey  *schemasv1alpha4.SQLTableForeignKey
+		schemaForeignKey  *schemasv1alpha4.PostgresqlTableForeignKey
 		expectedStatement string
 	}{
 		{
 			name:      "no name, one column, no on delete",
 			tableName: "t2",
-			schemaForeignKey: &schemasv1alpha4.SQLTableForeignKey{
+			schemaForeignKey: &schemasv1alpha4.PostgresqlTableForeignKey{
 				Columns: []string{
 					"c2",
 				},
-				References: schemasv1alpha4.SQLTableForeignKeyReferences{
+				References: schemasv1alpha4.PostgresqlTableForeignKeyReferences{
 					Table: "t1",
 					Columns: []string{
 						"c1",
@@ -34,12 +34,12 @@ func Test_AddForeignKeyStatement(t *testing.T) {
 		{
 			name:      "named, one column, no on delete",
 			tableName: "t2",
-			schemaForeignKey: &schemasv1alpha4.SQLTableForeignKey{
+			schemaForeignKey: &schemasv1alpha4.PostgresqlTableForeignKey{
 				Name: "hi_i_am_a_fkey",
 				Columns: []string{
 					"c2",
 				},
-				References: schemasv1alpha4.SQLTableForeignKeyReferences{
+				References: schemasv1alpha4.PostgresqlTableForeignKeyReferences{
 					Table: "t1",
 					Columns: []string{
 						"c1",
@@ -51,12 +51,12 @@ func Test_AddForeignKeyStatement(t *testing.T) {
 		{
 			name:      "no name, two columns, no on delete",
 			tableName: "t2",
-			schemaForeignKey: &schemasv1alpha4.SQLTableForeignKey{
+			schemaForeignKey: &schemasv1alpha4.PostgresqlTableForeignKey{
 				Columns: []string{
 					"c2",
 					"c22",
 				},
-				References: schemasv1alpha4.SQLTableForeignKeyReferences{
+				References: schemasv1alpha4.PostgresqlTableForeignKeyReferences{
 					Table: "t1",
 					Columns: []string{
 						"c1",
@@ -69,12 +69,12 @@ func Test_AddForeignKeyStatement(t *testing.T) {
 		{
 			name:      "no name, one column, on delete cascade",
 			tableName: "t2",
-			schemaForeignKey: &schemasv1alpha4.SQLTableForeignKey{
+			schemaForeignKey: &schemasv1alpha4.PostgresqlTableForeignKey{
 				OnDelete: "cascade",
 				Columns: []string{
 					"c2",
 				},
-				References: schemasv1alpha4.SQLTableForeignKeyReferences{
+				References: schemasv1alpha4.PostgresqlTableForeignKeyReferences{
 					Table: "t1",
 					Columns: []string{
 						"c1",
diff --git a/pkg/database/postgres/index_test.go b/pkg/database/postgres/index_test.go
index 2e223d95..5465f6ac 100644
--- a/pkg/database/postgres/index_test.go
+++ b/pkg/database/postgres/index_test.go
@@ -12,13 +12,13 @@ func Test_AddIndexStatement(t *testing.T) {
 	tests := []struct {
 		name              string
 		tableName         string
-		schemaIndex       *schemasv1alpha4.SQLTableIndex
+		schemaIndex       *schemasv1alpha4.PostgresqlTableIndex
 		expectedStatement string
 	}{
 		{
 			name:      "no name, one column, not specified unique",
 			tableName: "t2",
-			schemaIndex: &schemasv1alpha4.SQLTableIndex{
+			schemaIndex: &schemasv1alpha4.PostgresqlTableIndex{
 				Columns: []string{
 					"c1",
 				},
@@ -28,7 +28,7 @@ func Test_AddIndexStatement(t *testing.T) {
 		{
 			name:      "specified name, one column, not specified unique",
 			tableName: "t2",
-			schemaIndex: &schemasv1alpha4.SQLTableIndex{
+			schemaIndex: &schemasv1alpha4.PostgresqlTableIndex{
 				Columns: []string{
 					"c1",
 				},
@@ -39,7 +39,7 @@ func Test_AddIndexStatement(t *testing.T) {
 		{
 			name:      "no name, two columns, not specified unique",
 			tableName: "t2",
-			schemaIndex: &schemasv1alpha4.SQLTableIndex{
+			schemaIndex: &schemasv1alpha4.PostgresqlTableIndex{
 				Columns: []string{
 					"c1",
 					"c2",
@@ -50,7 +50,7 @@ func Test_AddIndexStatement(t *testing.T) {
 		{
 			name:      "np name, one column, unique",
 			tableName: "t2",
-			schemaIndex: &schemasv1alpha4.SQLTableIndex{
+			schemaIndex: &schemasv1alpha4.PostgresqlTableIndex{
 				Columns: []string{
 					"c1",
 				},
diff --git a/pkg/database/postgres/parameterized_test.go b/pkg/database/postgres/parameterized_test.go
index da5158e3..70f43824 100644
--- a/pkg/database/postgres/parameterized_test.go
+++ b/pkg/database/postgres/parameterized_test.go
@@ -88,11 +88,6 @@ func Test_maybeParseParameterizedColumnType(t *testing.T) {
 			requestedType:      "numeric  (5,3)",
 			expectedColumnType: "numeric (5, 3)",
 		},
-		{
-			name:               "citext",
-			requestedType:      "citext",
-			expectedColumnType: "citext",
-		},
 	}
 
 	for _, test := range tests {
diff --git a/pkg/database/postgres/trigger_test.go b/pkg/database/postgres/trigger_test.go
new file mode 100644
index 00000000..2d0f411b
--- /dev/null
+++ b/pkg/database/postgres/trigger_test.go
@@ -0,0 +1,147 @@
+package postgres
+
+import (
+	"testing"
+
+	schemasv1alpha4 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha4"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_triggerCreateStatement(t *testing.T) {
+	condition := "OLD.balance IS DISTINCT FROM NEW.balance"
+
+	tests := []struct {
+		name              string
+		trigger           *schemasv1alpha4.PostgresqlTableTrigger
+		tableName         string
+		expectedStatement string
+	}{
+		{
+			name: "after insert",
+			trigger: &schemasv1alpha4.PostgresqlTableTrigger{
+				Name: "tt",
+				Events: []string{
+					"after insert",
+				},
+				ForEachRow:       &trueValue,
+				ExecuteProcedure: "fn()",
+			},
+			tableName:         "a",
+			expectedStatement: `create trigger "tt" after insert on "a" for each row execute procedure fn()`,
+		},
+		{
+			name: "with when",
+			trigger: &schemasv1alpha4.PostgresqlTableTrigger{
+				Name: "tt",
+				Events: []string{
+					"before update",
+				},
+				ForEachRow:       &trueValue,
+				Condition:        &condition,
+				ExecuteProcedure: "fn()",
+			},
+			tableName:         "a",
+			expectedStatement: `create trigger "tt" before update on "a" for each row when (OLD.balance IS DISTINCT FROM NEW.balance) execute procedure fn()`,
+		},
+		{
+			name: "after insert or update",
+			trigger: &schemasv1alpha4.PostgresqlTableTrigger{
+				Name: "tt",
+				Events: []string{
+					"after insert",
+					"after update",
+				},
+				ForEachRow:       &trueValue,
+				ExecuteProcedure: "fn()",
+			},
+			tableName:         "a",
+			expectedStatement: `create trigger "tt" after insert or update on "a" for each row execute procedure fn()`,
+		},
+		{
+			name: "before insert constraint trigger",
+			trigger: &schemasv1alpha4.PostgresqlTableTrigger{
+				Name:              "tt",
+				ConstraintTrigger: &trueValue,
+				Events: []string{
+					"before insert",
+				},
+				ForEachStatement: &trueValue,
+				ExecuteProcedure: "fn()",
+			},
+			tableName:         "a",
+			expectedStatement: `create constraint trigger "tt" before insert on "a" for each statement execute procedure fn()`,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			req := require.New(t)
+
+			actual, err := triggerCreateStatement(test.trigger, test.tableName)
+			req.NoError(err)
+
+			assert.Equal(t, test.expectedStatement, actual)
+		})
+	}
+}
+
+func Test_triggerEventSyntax(t *testing.T) {
+	tests := []struct {
+		name              string
+		trigger           *schemasv1alpha4.PostgresqlTableTrigger
+		expectedStatement string
+	}{
+		{
+			name: "after insert",
+			trigger: &schemasv1alpha4.PostgresqlTableTrigger{
+				Events: []string{
+					"after insert",
+				},
+			},
+			expectedStatement: `after insert`,
+		},
+		{
+			name: "after insert and truncate",
+			trigger: &schemasv1alpha4.PostgresqlTableTrigger{
+				Name: "t",
+				Events: []string{
+					"after insert",
+					"after truncate",
+				},
+			},
+			expectedStatement: `after insert or truncate`,
+		},
+		{
+			name: "after insert and update of one column",
+			trigger: &schemasv1alpha4.PostgresqlTableTrigger{
+				Events: []string{
+					"after insert",
+					`after update of "c"`,
+				},
+			},
+			expectedStatement: `after insert or update of "c"`,
+		},
+		{
+			name: "instead of insert on",
+			trigger: &schemasv1alpha4.PostgresqlTableTrigger{
+				Events: []string{
+					`instead of insert`,
+				},
+			},
+			expectedStatement: `instead of insert`,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			req := require.New(t)
+
+			actual, err := triggerEvent(test.trigger)
+			req.NoError(err)
+
+			assert.Equal(t, test.expectedStatement, actual)
+		})
+	}
+}