Repository: supabase/cli
Pull request #1181 (2023-06-05 08:42:32)

feat: track migration statements in history table
## What kind of change does this PR introduce?

feature
closes https://github.com/supabase/cli/issues/1166

## What is the new behavior?

- adds a list of statements executed to migration history

TODO:
- [ ] backfill past migrations

## Additional context

![Screenshot 2023-06-06 at 2 30 12 PM](https://github.com/supabase/cli/assets/1639722/da383fb2-70bc-42c2-84ef-7323abe61bea)



Patch:
diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml
index 4ff52cdc..19f2d436 100644
--- a/.github/workflows/release-beta.yml
+++ b/.github/workflows/release-beta.yml
@@ -48,6 +48,8 @@ jobs:
           args: release --clean
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          BREWTAP_TOKEN: ${{ secrets.GH_PAT }}
+          SCOOP_TOKEN: ${{ secrets.GH_PAT }}
 
       - run: gh release edit v${{ needs.release.outputs.new-release-version }} --draft=false --prerelease
         env:
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 2c8be3c0..836c6fb3 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -27,6 +27,37 @@ changelog:
       order: 1
     - title: Others
       order: 999
+brews:
+  - name: supabase@beta
+    tap:
+      owner: supabase
+      name: homebrew-tap
+      token: "{{ .Env.BREWTAP_TOKEN }}"
+    commit_author:
+      name: Bobbie Soedirgo
+      email: bobbie@soedirgo.dev
+    url_template: "https://github.com/supabase/cli/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
+    homepage: https://supabase.com
+    description: Supabase CLI
+    license: MIT
+    install: |
+      bin.install "supabase"
+      (bash_completion/"supabase").write `#{bin}/supabase completion bash`
+      (fish_completion/"supabase.fish").write `#{bin}/supabase completion fish`
+      (zsh_completion/"_supabase").write `#{bin}/supabase completion zsh`
+scoops:
+  - name: supabase@beta
+    bucket:
+      owner: supabase
+      name: scoop-bucket
+      token: "{{ .Env.SCOOP_TOKEN }}"
+    commit_author:
+      name: Bobbie Soedirgo
+      email: bobbie@soedirgo.dev
+    url_template: "https://github.com/supabase/cli/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
+    homepage: https://supabase.com
+    description: Supabase CLI
+    license: MIT
 nfpms:
   - vendor: Supabase
     description: Supabase CLI
diff --git a/cmd/migration.go b/cmd/migration.go
index 4d68a019..2bacdc47 100644
--- a/cmd/migration.go
+++ b/cmd/migration.go
@@ -66,7 +66,7 @@ var (
 				return err
 			}
 			ctx, _ := signal.NotifyContext(cmd.Context(), os.Interrupt)
-			return repair.Run(ctx, dbConfig, args[0], targetStatus.Value)
+			return repair.Run(ctx, dbConfig, args[0], targetStatus.Value, fsys)
 		},
 	}
 
diff --git a/go.mod b/go.mod
index 72eb7ae5..868d6921 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/charmbracelet/bubbletea v0.24.1
 	github.com/charmbracelet/glamour v0.6.0
 	github.com/charmbracelet/lipgloss v0.7.1
-	github.com/deepmap/oapi-codegen v1.12.4
+	github.com/deepmap/oapi-codegen v1.13.0
 	github.com/docker/cli v24.0.2+incompatible
 	github.com/docker/docker v24.0.2+incompatible
 	github.com/docker/go-connections v0.4.0
@@ -42,7 +42,7 @@ require (
 	github.com/docker/docker-credential-helpers v0.7.0 // indirect
 	github.com/emirpasic/gods v1.18.1 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.2 // indirect
-	github.com/getkin/kin-openapi v0.107.0 // indirect
+	github.com/getkin/kin-openapi v0.117.0 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
 	github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
 	github.com/go-git/go-billy/v5 v5.4.1 // indirect
@@ -64,7 +64,7 @@ require (
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/kevinburke/ssh_config v1.2.0 // indirect
 	github.com/klauspost/cpuid/v2 v2.2.4 // indirect
-	github.com/labstack/echo/v4 v4.9.1 // indirect
+	github.com/labstack/echo/v4 v4.10.2 // indirect
 	github.com/labstack/gommon v0.4.0 // indirect
 	github.com/leodido/go-urn v1.2.4 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
@@ -75,6 +75,7 @@ require (
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
 	github.com/muesli/cancelreader v0.2.2 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.8 // indirect
+	github.com/perimeterx/marshmallow v1.1.4 // indirect
 	github.com/pjbgf/sha1cd v0.3.0 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/sahilm/fuzzy v0.1.0 // indirect
@@ -90,9 +91,9 @@ require (
 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 	github.com/xeipuuv/gojsonschema v1.2.0 // indirect
 	golang.org/x/arch v0.3.0 // indirect
-	golang.org/x/mod v0.8.0 // indirect
-	golang.org/x/sync v0.1.0 // indirect
-	golang.org/x/tools v0.6.0 // indirect
+	golang.org/x/mod v0.10.0 // indirect
+	golang.org/x/sync v0.2.0 // indirect
+	golang.org/x/tools v0.9.2 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
 	gotest.tools/v3 v3.0.3 // indirect
 )
diff --git a/go.sum b/go.sum
index e22b833e..c94d4918 100644
--- a/go.sum
+++ b/go.sum
@@ -112,8 +112,8 @@ github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0S
 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/deepmap/oapi-codegen v1.12.4 h1:pPmn6qI9MuOtCz82WY2Xaw46EQjgvxednXXrP7g5Q2s=
-github.com/deepmap/oapi-codegen v1.12.4/go.mod h1:3lgHGMu6myQ2vqbbTXH2H1o4eXFTGnFiDaOaKKl5yas=
+github.com/deepmap/oapi-codegen v1.13.0 h1:cnFHelhsRQbYvanCUAbRSn/ZpkUb1HPRlQcu8YqSORQ=
+github.com/deepmap/oapi-codegen v1.13.0/go.mod h1:Amy7tbubKY9qkZOXqymI3Z6xSbndmu+atMJheLdyg44=
 github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
 github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
 github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
@@ -143,8 +143,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4
 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
 github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
 github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
-github.com/getkin/kin-openapi v0.107.0 h1:bxhL6QArW7BXQj8NjXfIJQy680NsMKd25nwhvpCXchg=
-github.com/getkin/kin-openapi v0.107.0/go.mod h1:9Dhr+FasATJZjS4iOLvB0hkaxgYdulrNYm2e9epLWOo=
+github.com/getkin/kin-openapi v0.117.0 h1:QT2DyGujAL09F4NrKDHJGsUoIprlIcFVHWDVDcUFE8A=
+github.com/getkin/kin-openapi v0.117.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
 github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
@@ -175,6 +175,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
 github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
 github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
+github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
 github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U=
 github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
 github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
@@ -349,8 +351,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
-github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
-github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
+github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
+github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
 github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
 github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
 github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
@@ -427,6 +429,8 @@ github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3
 github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
 github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
+github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw=
+github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
 github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
 github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -498,6 +502,8 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8
 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
 github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
 github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
+github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
 github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
 github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
@@ -599,8 +605,9 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
+golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -660,8 +667,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
+golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -745,7 +753,7 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -802,8 +810,9 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.9.2 h1:UXbndbirwCAx6TULftIfie/ygDNCwxEie+IiNP1IcNc=
+golang.org/x/tools v0.9.2/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
 golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/internal/db/diff/migra.go b/internal/db/diff/migra.go
index 8fed56af..73b22586 100644
--- a/internal/db/diff/migra.go
+++ b/internal/db/diff/migra.go
@@ -79,13 +79,16 @@ func loadSchema(ctx context.Context, config pgconn.Config, options ...func(*pgx.
 }
 
 func LoadUserSchemas(ctx context.Context, conn *pgx.Conn, exclude ...string) ([]string, error) {
-	// Include auth,storage,extensions by default for RLS policies
 	if len(exclude) == 0 {
+		// RLS policies in auth and storage schemas can be included with -s flag
 		exclude = append([]string{
-			"_analytics",
+			"auth",
+			// "extensions",
 			"pgbouncer",
 			"realtime",
 			"_realtime",
+			"storage",
+			"_analytics",
 			// Exclude functions because Webhooks support is early alpha
 			"supabase_functions",
 			"supabase_migrations",
diff --git a/internal/db/reset/reset.go b/internal/db/reset/reset.go
index 1e65e6ca..41375cc1 100644
--- a/internal/db/reset/reset.go
+++ b/internal/db/reset/reset.go
@@ -17,6 +17,7 @@ import (
 	"github.com/spf13/afero"
 	"github.com/supabase/cli/internal/gen/keys"
 	"github.com/supabase/cli/internal/migration/apply"
+	"github.com/supabase/cli/internal/migration/repair"
 	"github.com/supabase/cli/internal/status"
 	"github.com/supabase/cli/internal/utils"
 )
@@ -112,7 +113,7 @@ func RecreateDatabase(ctx context.Context, options ...func(*pgx.ConnConfig)) err
 
 func SeedDatabase(ctx context.Context, conn *pgx.Conn, fsys afero.Fs) error {
 	fmt.Fprintln(os.Stderr, "Seeding data "+utils.Bold(utils.SeedDataPath)+"...")
-	seed, err := apply.NewMigrationFromFile(utils.SeedDataPath, fsys)
+	seed, err := repair.NewMigrationFromFile(utils.SeedDataPath, fsys)
 	if errors.Is(err, os.ErrNotExist) {
 		return nil
 	} else if err != nil {
@@ -202,7 +203,7 @@ func resetRemote(ctx context.Context, config pgconn.Config, fsys afero.Fs, optio
 	}
 	userSchemas = append(userSchemas, "supabase_migrations")
 	// Drop user defined objects
-	migration := apply.MigrationFile{}
+	migration := repair.MigrationFile{}
 	for _, schema := range userSchemas {
 		sql := fmt.Sprintf("DROP SCHEMA IF EXISTS %s CASCADE", schema)
 		migration.Lines = append(migration.Lines, sql)
diff --git a/internal/link/link.go b/internal/link/link.go
index 21f227bb..04ab9807 100644
--- a/internal/link/link.go
+++ b/internal/link/link.go
@@ -131,11 +131,7 @@ func linkDatabase(ctx context.Context, config pgconn.Config, options ...func(*pg
 	defer conn.Close(context.Background())
 	updatePostgresConfig(conn)
 	// If `schema_migrations` doesn't exist on the remote database, create it.
-	batch := pgconn.Batch{}
-	batch.ExecParams(repair.CREATE_VERSION_SCHEMA, nil, nil, nil, nil)
-	batch.ExecParams(repair.CREATE_VERSION_TABLE, nil, nil, nil, nil)
-	_, err = conn.PgConn().ExecBatch(ctx, &batch).ReadAll()
-	return err
+	return repair.CreateMigrationTable(ctx, conn)
 }
 
 func updatePostgresConfig(conn *pgx.Conn) {
diff --git a/internal/migration/apply/apply.go b/internal/migration/apply/apply.go
index a0a28bac..3d6821fd 100644
--- a/internal/migration/apply/apply.go
+++ b/internal/migration/apply/apply.go
@@ -7,14 +7,11 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/jackc/pgconn"
 	"github.com/jackc/pgx/v4"
 	"github.com/spf13/afero"
-	"github.com/spf13/viper"
 	"github.com/supabase/cli/internal/migration/list"
 	"github.com/supabase/cli/internal/migration/repair"
 	"github.com/supabase/cli/internal/utils"
-	"github.com/supabase/cli/internal/utils/parser"
 )
 
 func MigrateDatabase(ctx context.Context, conn *pgx.Conn, fsys afero.Fs) error {
@@ -42,7 +39,7 @@ func MigrateUp(ctx context.Context, conn *pgx.Conn, pending []string, fsys afero
 func applyMigration(ctx context.Context, conn *pgx.Conn, filename string, fsys afero.Fs) error {
 	fmt.Fprintln(os.Stderr, "Applying migration "+utils.Bold(filename)+"...")
 	path := filepath.Join(utils.MigrationsDir, filename)
-	migration, err := NewMigrationFromFile(path, fsys)
+	migration, err := repair.NewMigrationFromFile(path, fsys)
 	if err != nil {
 		return err
 	}
@@ -50,81 +47,9 @@ func applyMigration(ctx context.Context, conn *pgx.Conn, filename string, fsys a
 }
 
 func BatchExecDDL(ctx context.Context, conn *pgx.Conn, sql io.Reader) error {
-	migration, err := NewMigrationFromReader(sql)
+	migration, err := repair.NewMigrationFromReader(sql)
 	if err != nil {
 		return err
 	}
 	return migration.ExecBatch(ctx, conn)
 }
-
-type MigrationFile struct {
-	Lines   []string
-	version string
-}
-
-func NewMigrationFromFile(path string, fsys afero.Fs) (*MigrationFile, error) {
-	sql, err := fsys.Open(path)
-	if err != nil {
-		return nil, err
-	}
-	defer sql.Close()
-	// Unless explicitly specified, Use file length as max buffer size
-	if !viper.IsSet("SCANNER_BUFFER_SIZE") {
-		if fi, err := sql.Stat(); err == nil {
-			if size := int(fi.Size()); size > parser.MaxScannerCapacity {
-				parser.MaxScannerCapacity = size
-			}
-		}
-	}
-	file, err := NewMigrationFromReader(sql)
-	if err == nil {
-		// Parse version from file name
-		filename := filepath.Base(path)
-		matches := utils.MigrateFilePattern.FindStringSubmatch(filename)
-		if len(matches) > 1 {
-			file.version = matches[1]
-		}
-	}
-	return file, err
-}
-
-func NewMigrationFromReader(sql io.Reader) (*MigrationFile, error) {
-	lines, err := parser.SplitAndTrim(sql)
-	if err != nil {
-		return nil, err
-	}
-	return &MigrationFile{Lines: lines}, nil
-}
-
-func (m *MigrationFile) ExecBatch(ctx context.Context, conn *pgx.Conn) error {
-	// Batch migration commands, without using statement cache
-	batch := &pgconn.Batch{}
-	for _, line := range m.Lines {
-		batch.ExecParams(line, nil, nil, nil, nil)
-	}
-	// Insert into migration history
-	if len(m.version) > 0 {
-		repair.InsertVersionSQL(batch, m.version)
-	}
-	// ExecBatch is implicitly transactional
-	if result, err := conn.PgConn().ExecBatch(ctx, batch).ReadAll(); err != nil {
-		// Defaults to printing the last statement on error
-		stat := repair.INSERT_MIGRATION_VERSION
-		i := len(result)
-		if i < len(m.Lines) {
-			stat = m.Lines[i]
-		}
-		return fmt.Errorf("%w\nAt statement %d: %s", err, i, utils.Aqua(stat))
-	}
-	return nil
-}
-
-func (m *MigrationFile) ExecBatchWithCache(ctx context.Context, conn *pgx.Conn) error {
-	// Data statements don't mutate schemas, safe to use statement cache
-	batch := pgx.Batch{}
-	for _, line := range m.Lines {
-		batch.Queue(line)
-	}
-	// No need to track version here because there are no schema changes
-	return conn.SendBatch(ctx, &batch).Close()
-}
diff --git a/internal/migration/repair/repair.go b/internal/migration/repair/repair.go
index 397af5a2..405bac87 100644
--- a/internal/migration/repair/repair.go
+++ b/internal/migration/repair/repair.go
@@ -3,12 +3,17 @@ package repair
 import (
 	"context"
 	"fmt"
+	"io"
 	"os"
+	"path/filepath"
 
 	"github.com/jackc/pgconn"
 	"github.com/jackc/pgtype"
 	"github.com/jackc/pgx/v4"
+	"github.com/spf13/afero"
+	"github.com/spf13/viper"
 	"github.com/supabase/cli/internal/utils"
+	"github.com/supabase/cli/internal/utils/parser"
 )
 
 const (
@@ -19,24 +24,26 @@ const (
 const (
 	CREATE_VERSION_SCHEMA    = "CREATE SCHEMA IF NOT EXISTS supabase_migrations"
 	CREATE_VERSION_TABLE     = "CREATE TABLE IF NOT EXISTS supabase_migrations.schema_migrations (version text NOT NULL PRIMARY KEY)"
-	INSERT_MIGRATION_VERSION = "INSERT INTO supabase_migrations.schema_migrations(version) VALUES($1)"
+	ADD_STATEMENTS_COLUMN    = "ALTER TABLE supabase_migrations.schema_migrations ADD COLUMN IF NOT EXISTS statements text[]"
+	INSERT_MIGRATION_VERSION = "INSERT INTO supabase_migrations.schema_migrations(version, statements) VALUES($1, $2)"
 	DELETE_MIGRATION_VERSION = "DELETE FROM supabase_migrations.schema_migrations WHERE version = $1"
 )
 
-func Run(ctx context.Context, config pgconn.Config, version, status string, options ...func(*pgx.ConnConfig)) error {
+func Run(ctx context.Context, config pgconn.Config, version, status string, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
 	conn, err := utils.ConnectRemotePostgres(ctx, config, options...)
 	if err != nil {
 		return err
 	}
 	defer conn.Close(context.Background())
-	// Create history table if not exists
-	batch := pgconn.Batch{}
-	batch.ExecParams(CREATE_VERSION_SCHEMA, nil, nil, nil, nil)
-	batch.ExecParams(CREATE_VERSION_TABLE, nil, nil, nil, nil)
 	// Update migration history
+	batch := batchCreateTable()
 	switch status {
 	case Applied:
-		InsertVersionSQL(&batch, version)
+		f, err := NewMigrationFromVersion(version, fsys)
+		if err != nil {
+			return err
+		}
+		InsertVersionSQL(&batch, version, f.Lines)
 	case Reverted:
 		DeleteVersionSQL(&batch, version)
 	}
@@ -47,28 +54,126 @@ func Run(ctx context.Context, config pgconn.Config, version, status string, opti
 	return nil
 }
 
-func CreateMigrationTable(ctx context.Context, conn *pgx.Conn) error {
+func batchCreateTable() pgconn.Batch {
+	// Create history table if not exists
 	batch := pgconn.Batch{}
 	batch.ExecParams(CREATE_VERSION_SCHEMA, nil, nil, nil, nil)
 	batch.ExecParams(CREATE_VERSION_TABLE, nil, nil, nil, nil)
+	batch.ExecParams(ADD_STATEMENTS_COLUMN, nil, nil, nil, nil)
+	return batch
+}
+
+func CreateMigrationTable(ctx context.Context, conn *pgx.Conn) error {
+	batch := batchCreateTable()
 	_, err := conn.PgConn().ExecBatch(ctx, &batch).ReadAll()
 	return err
 }
 
-func InsertVersionSQL(batch *pgconn.Batch, version string) {
-	updateVersionSQL(batch, INSERT_MIGRATION_VERSION, version)
+func InsertVersionSQL(batch *pgconn.Batch, version string, stats []string) {
+	encoded := []byte{'{'}
+	for i, line := range stats {
+		if i > 0 {
+			encoded = append(encoded, ',')
+		}
+		encoded = append(encoded, pgtype.QuoteArrayElementIfNeeded(line)...)
+	}
+	encoded = append(encoded, '}')
+	batch.ExecParams(
+		INSERT_MIGRATION_VERSION,
+		[][]byte{[]byte(version), encoded},
+		[]uint32{pgtype.TextOID, pgtype.TextArrayOID},
+		[]int16{pgtype.TextFormatCode, pgtype.TextFormatCode},
+		nil,
+	)
 }
 
 func DeleteVersionSQL(batch *pgconn.Batch, version string) {
-	updateVersionSQL(batch, DELETE_MIGRATION_VERSION, version)
-}
-
-func updateVersionSQL(batch *pgconn.Batch, sql, version string) {
 	batch.ExecParams(
-		sql,
+		DELETE_MIGRATION_VERSION,
 		[][]byte{[]byte(version)},
 		[]uint32{pgtype.TextOID},
 		[]int16{pgtype.TextFormatCode},
 		nil,
 	)
 }
+
+type MigrationFile struct {
+	Lines   []string
+	version string
+}
+
+func NewMigrationFromVersion(version string, fsys afero.Fs) (*MigrationFile, error) {
+	path := filepath.Join(utils.MigrationsDir, version+"_*.sql")
+	matches, err := afero.Glob(fsys, path)
+	if err != nil || len(matches) == 0 {
+		return nil, err
+	}
+	return NewMigrationFromFile(matches[0], fsys)
+}
+
+func NewMigrationFromFile(path string, fsys afero.Fs) (*MigrationFile, error) {
+	sql, err := fsys.Open(path)
+	if err != nil {
+		return nil, err
+	}
+	defer sql.Close()
+	// Unless explicitly specified, Use file length as max buffer size
+	if !viper.IsSet("SCANNER_BUFFER_SIZE") {
+		if fi, err := sql.Stat(); err == nil {
+			if size := int(fi.Size()); size > parser.MaxScannerCapacity {
+				parser.MaxScannerCapacity = size
+			}
+		}
+	}
+	file, err := NewMigrationFromReader(sql)
+	if err == nil {
+		// Parse version from file name
+		filename := filepath.Base(path)
+		matches := utils.MigrateFilePattern.FindStringSubmatch(filename)
+		if len(matches) > 1 {
+			file.version = matches[1]
+		}
+	}
+	return file, err
+}
+
+func NewMigrationFromReader(sql io.Reader) (*MigrationFile, error) {
+	lines, err := parser.SplitAndTrim(sql)
+	if err != nil {
+		return nil, err
+	}
+	return &MigrationFile{Lines: lines}, nil
+}
+
+func (m *MigrationFile) ExecBatch(ctx context.Context, conn *pgx.Conn) error {
+	// Batch migration commands, without using statement cache
+	batch := &pgconn.Batch{}
+	for _, line := range m.Lines {
+		batch.ExecParams(line, nil, nil, nil, nil)
+	}
+	// Insert into migration history
+	if len(m.version) > 0 {
+		InsertVersionSQL(batch, m.version, m.Lines)
+	}
+	// ExecBatch is implicitly transactional
+	if result, err := conn.PgConn().ExecBatch(ctx, batch).ReadAll(); err != nil {
+		// Defaults to printing the last statement on error
+		stat := INSERT_MIGRATION_VERSION
+		i := len(result)
+		if i < len(m.Lines) {
+			stat = m.Lines[i]
+		}
+		return fmt.Errorf("%w\nAt statement %d: %s", err, i, utils.Aqua(stat))
+	}
+	return nil
+}
+
+func (m *MigrationFile) ExecBatchWithCache(ctx context.Context, conn *pgx.Conn) error {
+	// Data statements don't mutate schemas, safe to use statement cache
+	batch := pgx.Batch{}
+	for _, line := range m.Lines {
+		batch.Queue(line)
+	}
+	// No need to track version here because there are no schema changes
+	return conn.SendBatch(ctx, &batch).Close()
+}
diff --git a/internal/start/start.go b/internal/start/start.go
index b6b85eba..38dc6ee5 100644
--- a/internal/start/start.go
+++ b/internal/start/start.go
@@ -98,6 +98,7 @@ type kongConfig struct {
 	PgmetaId    string
 	DenoRelayId string
 	LogflareId  string
+	ApiPort     uint
 }
 
 var (
@@ -268,6 +269,7 @@ EOF
 	p.Send(utils.StatusMsg("Starting containers..."))
 	if !isContainerExcluded(utils.KongImage, excluded) {
 		var kongConfigBuf bytes.Buffer
+
 		if err := kongConfigTemplate.Execute(&kongConfigBuf, kongConfig{
 			GotrueId:    utils.GotrueId,
 			RestId:      utils.RestId,
@@ -276,6 +278,7 @@ EOF
 			PgmetaId:    utils.PgmetaId,
 			DenoRelayId: utils.DenoRelayId,
 			LogflareId:  utils.LogflareId,
+			ApiPort:     utils.Config.Api.Port,
 		}); err != nil {
 			return err
 		}
diff --git a/internal/start/templates/kong.yml b/internal/start/templates/kong.yml
index 0baa7140..f89b4b7d 100644
--- a/internal/start/templates/kong.yml
+++ b/internal/start/templates/kong.yml
@@ -85,6 +85,11 @@ services:
           - /storage/v1/
     plugins:
       - name: cors
+      - name: request-transformer
+        config:
+          add:
+            headers:
+              - "Forwarded: host=localhost:{{ .ApiPort }}/storage/v1;proto=http"
   - name: pg-meta
     _comment: "pg-meta: /pg/* -> http://pg-meta:8080/*"
     url: http://{{ .PgmetaId }}:8080/
diff --git a/internal/utils/misc.go b/internal/utils/misc.go
index ff54c6c1..c6ce75e7 100644
--- a/internal/utils/misc.go
+++ b/internal/utils/misc.go
@@ -23,7 +23,7 @@ var Version string
 const (
 	Pg13Image = "supabase/postgres:13.3.0"
 	Pg14Image = "supabase/postgres:14.1.0.89"
-	Pg15Image = "supabase/postgres:15.1.0.73"
+	Pg15Image = "supabase/postgres:15.1.0.90"
 	// Append to ServiceImages when adding new dependencies below
 	KongImage        = "library/kong:2.8.1"
 	InbucketImage    = "inbucket/inbucket:3.0.3"
@@ -31,7 +31,7 @@ const (
 	DifferImage      = "supabase/pgadmin-schema-diff:cli-0.0.5"
 	MigraImage       = "djrobstep/migra:3.0.1621480950"
 	PgmetaImage      = "supabase/postgres-meta:v0.66.0"
-	StudioImage      = "supabase/studio:20230512-ad596d8"
+	StudioImage      = "supabase/studio:20230605-c876cea"
 	DenoRelayImage   = "supabase/deno-relay:v1.6.0"
 	ImageProxyImage  = "darthsim/imgproxy:v3.8.0"
 	EdgeRuntimeImage = "supabase/edge-runtime:v1.4.2"
diff --git a/pkg/api/client.gen.go b/pkg/api/client.gen.go
index 75d6772c..8cf52c4b 100644
--- a/pkg/api/client.gen.go
+++ b/pkg/api/client.gen.go
@@ -1,6 +1,6 @@
 // Package api provides primitives to interact with the openapi HTTP API.
 //
-// Code generated by github.com/deepmap/oapi-codegen version v1.12.4 DO NOT EDIT.
+// Code generated by github.com/deepmap/oapi-codegen version v1.13.0 DO NOT EDIT.
 package api
 
 import (
@@ -1299,59 +1299,10 @@ func NewAuthorizeRequest(server string, params *AuthorizeParams) (*http.Request,
 		return nil, err
 	}
 
-	queryValues := queryURL.Query()
+	if params != nil {
+		queryValues := queryURL.Query()
 
-	if queryFrag, err := runtime.StyleParamWithLocation("form", true, "client_id", runtime.ParamLocationQuery, params.ClientId); err != nil {
-		return nil, err
-	} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-		return nil, err
-	} else {
-		for k, v := range parsed {
-			for _, v2 := range v {
-				queryValues.Add(k, v2)
-			}
-		}
-	}
-
-	if queryFrag, err := runtime.StyleParamWithLocation("form", true, "response_type", runtime.ParamLocationQuery, params.ResponseType); err != nil {
-		return nil, err
-	} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-		return nil, err
-	} else {
-		for k, v := range parsed {
-			for _, v2 := range v {
-				queryValues.Add(k, v2)
-			}
-		}
-	}
-
-	if queryFrag, err := runtime.StyleParamWithLocation("form", true, "redirect_uri", runtime.ParamLocationQuery, params.RedirectUri); err != nil {
-		return nil, err
-	} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-		return nil, err
-	} else {
-		for k, v := range parsed {
-			for _, v2 := range v {
-				queryValues.Add(k, v2)
-			}
-		}
-	}
-
-	if queryFrag, err := runtime.StyleParamWithLocation("form", true, "scope", runtime.ParamLocationQuery, params.Scope); err != nil {
-		return nil, err
-	} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-		return nil, err
-	} else {
-		for k, v := range parsed {
-			for _, v2 := range v {
-				queryValues.Add(k, v2)
-			}
-		}
-	}
-
-	if params.State != nil {
-
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "state", runtime.ParamLocationQuery, *params.State); err != nil {
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "client_id", runtime.ParamLocationQuery, params.ClientId); err != nil {
 			return nil, err
 		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
 			return nil, err
@@ -1363,11 +1314,7 @@ func NewAuthorizeRequest(server string, params *AuthorizeParams) (*http.Request,
 			}
 		}
 
-	}
-
-	if params.ResponseMode != nil {
-
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "response_mode", runtime.ParamLocationQuery, *params.ResponseMode); err != nil {
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "response_type", runtime.ParamLocationQuery, params.ResponseType); err != nil {
 			return nil, err
 		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
 			return nil, err
@@ -1379,11 +1326,7 @@ func NewAuthorizeRequest(server string, params *AuthorizeParams) (*http.Request,
 			}
 		}
 
-	}
-
-	if params.CodeChallenge != nil {
-
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code_challenge", runtime.ParamLocationQuery, *params.CodeChallenge); err != nil {
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "redirect_uri", runtime.ParamLocationQuery, params.RedirectUri); err != nil {
 			return nil, err
 		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
 			return nil, err
@@ -1395,11 +1338,7 @@ func NewAuthorizeRequest(server string, params *AuthorizeParams) (*http.Request,
 			}
 		}
 
-	}
-
-	if params.CodeChallengeMethod != nil {
-
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code_challenge_method", runtime.ParamLocationQuery, *params.CodeChallengeMethod); err != nil {
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "scope", runtime.ParamLocationQuery, params.Scope); err != nil {
 			return nil, err
 		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
 			return nil, err
@@ -1411,9 +1350,72 @@ func NewAuthorizeRequest(server string, params *AuthorizeParams) (*http.Request,
 			}
 		}
 
-	}
+		if params.State != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "state", runtime.ParamLocationQuery, *params.State); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
+				}
+			}
 
-	queryURL.RawQuery = queryValues.Encode()
+		}
+
+		if params.ResponseMode != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "response_mode", runtime.ParamLocationQuery, *params.ResponseMode); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
+				}
+			}
+
+		}
+
+		if params.CodeChallenge != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code_challenge", runtime.ParamLocationQuery, *params.CodeChallenge); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
+				}
+			}
+
+		}
+
+		if params.CodeChallengeMethod != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code_challenge_method", runtime.ParamLocationQuery, *params.CodeChallengeMethod); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
+				}
+			}
+
+		}
+
+		queryURL.RawQuery = queryValues.Encode()
+	}
 
 	req, err := http.NewRequest("GET", queryURL.String(), nil)
 	if err != nil {
@@ -1442,47 +1444,22 @@ func NewTokenRequest(server string, params *TokenParams) (*http.Request, error)
 		return nil, err
 	}
 
-	queryValues := queryURL.Query()
-
-	if queryFrag, err := runtime.StyleParamWithLocation("form", true, "grant_type", runtime.ParamLocationQuery, params.GrantType); err != nil {
-		return nil, err
-	} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-		return nil, err
-	} else {
-		for k, v := range parsed {
-			for _, v2 := range v {
-				queryValues.Add(k, v2)
-			}
-		}
-	}
-
-	if queryFrag, err := runtime.StyleParamWithLocation("form", true, "client_id", runtime.ParamLocationQuery, params.ClientId); err != nil {
-		return nil, err
-	} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-		return nil, err
-	} else {
-		for k, v := range parsed {
-			for _, v2 := range v {
-				queryValues.Add(k, v2)
-			}
-		}
-	}
+	if params != nil {
+		queryValues := queryURL.Query()
 
-	if queryFrag, err := runtime.StyleParamWithLocation("form", true, "client_secret", runtime.ParamLocationQuery, params.ClientSecret); err != nil {
-		return nil, err
-	} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-		return nil, err
-	} else {
-		for k, v := range parsed {
-			for _, v2 := range v {
-				queryValues.Add(k, v2)
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "grant_type", runtime.ParamLocationQuery, params.GrantType); err != nil {
+			return nil, err
+		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+			return nil, err
+		} else {
+			for k, v := range parsed {
+				for _, v2 := range v {
+					queryValues.Add(k, v2)
+				}
 			}
 		}
-	}
 
-	if params.Code != nil {
-
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code", runtime.ParamLocationQuery, *params.Code); err != nil {
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "client_id", runtime.ParamLocationQuery, params.ClientId); err != nil {
 			return nil, err
 		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
 			return nil, err
@@ -1494,11 +1471,7 @@ func NewTokenRequest(server string, params *TokenParams) (*http.Request, error)
 			}
 		}
 
-	}
-
-	if params.CodeVerifier != nil {
-
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code_verifier", runtime.ParamLocationQuery, *params.CodeVerifier); err != nil {
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "client_secret", runtime.ParamLocationQuery, params.ClientSecret); err != nil {
 			return nil, err
 		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
 			return nil, err
@@ -1510,23 +1483,39 @@ func NewTokenRequest(server string, params *TokenParams) (*http.Request, error)
 			}
 		}
 
-	}
-
-	if queryFrag, err := runtime.StyleParamWithLocation("form", true, "redirect_uri", runtime.ParamLocationQuery, params.RedirectUri); err != nil {
-		return nil, err
-	} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-		return nil, err
-	} else {
-		for k, v := range parsed {
-			for _, v2 := range v {
-				queryValues.Add(k, v2)
+		if params.Code != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code", runtime.ParamLocationQuery, *params.Code); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
+				}
 			}
+
 		}
-	}
 
-	if params.RefreshToken != nil {
+		if params.CodeVerifier != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "code_verifier", runtime.ParamLocationQuery, *params.CodeVerifier); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
+				}
+			}
+
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "refresh_token", runtime.ParamLocationQuery, *params.RefreshToken); err != nil {
+		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "redirect_uri", runtime.ParamLocationQuery, params.RedirectUri); err != nil {
 			return nil, err
 		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
 			return nil, err
@@ -1538,9 +1527,24 @@ func NewTokenRequest(server string, params *TokenParams) (*http.Request, error)
 			}
 		}
 
-	}
+		if params.RefreshToken != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "refresh_token", runtime.ParamLocationQuery, *params.RefreshToken); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
+				}
+			}
 
-	queryURL.RawQuery = queryValues.Encode()
+		}
+
+		queryURL.RawQuery = queryValues.Encode()
+	}
 
 	req, err := http.NewRequest("POST", queryURL.String(), nil)
 	if err != nil {
@@ -2351,106 +2355,108 @@ func NewCreateFunctionRequestWithBody(server string, ref string, params *CreateF
 		return nil, err
 	}
 
-	queryValues := queryURL.Query()
+	if params != nil {
+		queryValues := queryURL.Query()
 
-	if params.Slug != nil {
+		if params.Slug != nil {
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "slug", runtime.ParamLocationQuery, *params.Slug); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "slug", runtime.ParamLocationQuery, *params.Slug); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
 
-	}
-
-	if params.Name != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "name", runtime.ParamLocationQuery, *params.Name); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.Name != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "name", runtime.ParamLocationQuery, *params.Name); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
 
-	}
-
-	if params.VerifyJwt != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "verify_jwt", runtime.ParamLocationQuery, *params.VerifyJwt); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.VerifyJwt != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "verify_jwt", runtime.ParamLocationQuery, *params.VerifyJwt); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
 
-	}
-
-	if params.ImportMap != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "import_map", runtime.ParamLocationQuery, *params.ImportMap); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.ImportMap != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "import_map", runtime.ParamLocationQuery, *params.ImportMap); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
 
-	}
-
-	if params.EntrypointPath != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "entrypoint_path", runtime.ParamLocationQuery, *params.EntrypointPath); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.EntrypointPath != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "entrypoint_path", runtime.ParamLocationQuery, *params.EntrypointPath); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
-
-	}
 
-	if params.ImportMapPath != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "import_map_path", runtime.ParamLocationQuery, *params.ImportMapPath); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.ImportMapPath != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "import_map_path", runtime.ParamLocationQuery, *params.ImportMapPath); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
+
 		}
 
+		queryURL.RawQuery = queryValues.Encode()
 	}
 
-	queryURL.RawQuery = queryValues.Encode()
-
 	req, err := http.NewRequest("POST", queryURL.String(), body)
 	if err != nil {
 		return nil, err
@@ -2587,106 +2593,108 @@ func NewUpdateFunctionRequestWithBody(server string, ref string, functionSlug st
 		return nil, err
 	}
 
-	queryValues := queryURL.Query()
+	if params != nil {
+		queryValues := queryURL.Query()
 
-	if params.Slug != nil {
+		if params.Slug != nil {
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "slug", runtime.ParamLocationQuery, *params.Slug); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "slug", runtime.ParamLocationQuery, *params.Slug); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
-
-	}
 
-	if params.Name != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "name", runtime.ParamLocationQuery, *params.Name); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.Name != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "name", runtime.ParamLocationQuery, *params.Name); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
-
-	}
 
-	if params.VerifyJwt != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "verify_jwt", runtime.ParamLocationQuery, *params.VerifyJwt); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.VerifyJwt != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "verify_jwt", runtime.ParamLocationQuery, *params.VerifyJwt); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
-
-	}
 
-	if params.ImportMap != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "import_map", runtime.ParamLocationQuery, *params.ImportMap); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.ImportMap != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "import_map", runtime.ParamLocationQuery, *params.ImportMap); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
 
-	}
-
-	if params.EntrypointPath != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "entrypoint_path", runtime.ParamLocationQuery, *params.EntrypointPath); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.EntrypointPath != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "entrypoint_path", runtime.ParamLocationQuery, *params.EntrypointPath); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
-		}
 
-	}
-
-	if params.ImportMapPath != nil {
+		}
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "import_map_path", runtime.ParamLocationQuery, *params.ImportMapPath); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+		if params.ImportMapPath != nil {
+
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "import_map_path", runtime.ParamLocationQuery, *params.ImportMapPath); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
+
 		}
 
+		queryURL.RawQuery = queryValues.Encode()
 	}
 
-	queryURL.RawQuery = queryValues.Encode()
-
 	req, err := http.NewRequest("PATCH", queryURL.String(), body)
 	if err != nil {
 		return nil, err
@@ -3365,26 +3373,28 @@ func NewGetTypescriptTypesRequest(server string, ref string, params *GetTypescri
 		return nil, err
 	}
 
-	queryValues := queryURL.Query()
+	if params != nil {
+		queryValues := queryURL.Query()
 
-	if params.IncludedSchemas != nil {
+		if params.IncludedSchemas != nil {
 
-		if queryFrag, err := runtime.StyleParamWithLocation("form", true, "included_schemas", runtime.ParamLocationQuery, *params.IncludedSchemas); err != nil {
-			return nil, err
-		} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
-			return nil, err
-		} else {
-			for k, v := range parsed {
-				for _, v2 := range v {
-					queryValues.Add(k, v2)
+			if queryFrag, err := runtime.StyleParamWithLocation("form", true, "included_schemas", runtime.ParamLocationQuery, *params.IncludedSchemas); err != nil {
+				return nil, err
+			} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
+				return nil, err
+			} else {
+				for k, v := range parsed {
+					for _, v2 := range v {
+						queryValues.Add(k, v2)
+					}
 				}
 			}
+
 		}
 
+		queryURL.RawQuery = queryValues.Encode()
 	}
 
-	queryURL.RawQuery = queryValues.Encode()
-
 	req, err := http.NewRequest("GET", queryURL.String(), nil)
 	if err != nil {
 		return nil, err
diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go
index 8ab6105a..c34b0b40 100644
--- a/pkg/api/types.gen.go
+++ b/pkg/api/types.gen.go
@@ -1,6 +1,6 @@
 // Package api provides primitives to interact with the openapi HTTP API.
 //
-// Code generated by github.com/deepmap/oapi-codegen version v1.12.4 DO NOT EDIT.
+// Code generated by github.com/deepmap/oapi-codegen version v1.13.0 DO NOT EDIT.
 package api
 
 import (
@@ -849,7 +849,7 @@ func (t *AttributeValue_Default) MergeAttributeValueDefault0(v AttributeValueDef
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -875,7 +875,7 @@ func (t *AttributeValue_Default) MergeAttributeValueDefault1(v AttributeValueDef
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -901,7 +901,7 @@ func (t *AttributeValue_Default) MergeAttributeValueDefault2(v AttributeValueDef
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -927,7 +927,7 @@ func (t *AttributeValue_Default) MergeAttributeValueDefault3(v AttributeValueDef
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }


Test patch:
diff --git a/internal/db/diff/migra_test.go b/internal/db/diff/migra_test.go
index f41c4546..ccfbe86f 100644
--- a/internal/db/diff/migra_test.go
+++ b/internal/db/diff/migra_test.go
@@ -106,7 +106,7 @@ func TestRunMigra(t *testing.T) {
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
-		conn.Query(`SELECT schema_name FROM information_schema.schemata WHERE NOT schema_name LIKE ANY('{"\\_analytics",pgbouncer,realtime,"\\_realtime","supabase\\_functions","supabase\\_migrations","information\\_schema","pg\\_%",cron,graphql,"graphql\\_public",net,pgsodium,"pgsodium\\_masks",pgtle,repack,tiger,"tiger\\_data","timescaledb\\_%","\\_timescaledb\\_%",topology,vault}') ORDER BY schema_name`).
+		conn.Query(`SELECT schema_name FROM information_schema.schemata WHERE NOT schema_name LIKE ANY('{auth,pgbouncer,realtime,"\\_realtime",storage,"\\_analytics","supabase\\_functions","supabase\\_migrations","information\\_schema","pg\\_%",cron,graphql,"graphql\\_public",net,pgsodium,"pgsodium\\_masks",pgtle,repack,tiger,"tiger\\_data","timescaledb\\_%","\\_timescaledb\\_%",topology,vault}') ORDER BY schema_name`).
 			ReplyError(pgerrcode.DuplicateTable, `relation "test" already exists`)
 		// Run test
 		err := RunMigra(context.Background(), []string{}, "", dbConfig, fsys, conn.Intercept)
diff --git a/internal/db/push/push_test.go b/internal/db/push/push_test.go
index ed08b727..ee69617c 100644
--- a/internal/db/push/push_test.go
+++ b/internal/db/push/push_test.go
@@ -91,7 +91,8 @@ func TestMigrationPush(t *testing.T) {
 			Query(repair.CREATE_VERSION_SCHEMA).
 			Reply("CREATE SCHEMA").
 			Query(repair.CREATE_VERSION_TABLE).
-			ReplyError(pgerrcode.InsufficientPrivilege, "permission denied for relation supabase_migrations")
+			ReplyError(pgerrcode.InsufficientPrivilege, "permission denied for relation supabase_migrations").
+			Query(repair.ADD_STATEMENTS_COLUMN)
 		// Run test
 		err := Run(context.Background(), false, dbConfig, fsys, conn.Intercept)
 		// Check error
@@ -112,7 +113,9 @@ func TestMigrationPush(t *testing.T) {
 			Reply("CREATE SCHEMA").
 			Query(repair.CREATE_VERSION_TABLE).
 			Reply("CREATE TABLE").
-			Query(repair.INSERT_MIGRATION_VERSION, "0").
+			Query(repair.ADD_STATEMENTS_COLUMN).
+			Reply("ALTER TABLE").
+			Query(repair.INSERT_MIGRATION_VERSION, "0", "{}").
 			ReplyError(pgerrcode.NotNullViolation, `null value in column "version" of relation "schema_migrations"`)
 		// Run test
 		err := Run(context.Background(), false, dbConfig, fsys, conn.Intercept)
diff --git a/internal/link/link_test.go b/internal/link/link_test.go
index d6ea0b56..d36fc94a 100644
--- a/internal/link/link_test.go
+++ b/internal/link/link_test.go
@@ -125,7 +125,9 @@ func TestLinkCommand(t *testing.T) {
 		conn.Query(repair.CREATE_VERSION_SCHEMA).
 			Reply("CREATE SCHEMA").
 			Query(repair.CREATE_VERSION_TABLE).
-			Reply("CREATE TABLE")
+			Reply("CREATE TABLE").
+			Query(repair.ADD_STATEMENTS_COLUMN).
+			Reply("ALTER TABLE")
 		// Flush pending mocks after test execution
 		defer gock.OffAll()
 		gock.New(utils.DefaultApiHost).
@@ -300,7 +302,9 @@ func TestLinkDatabase(t *testing.T) {
 		conn.Query(repair.CREATE_VERSION_SCHEMA).
 			Reply("CREATE SCHEMA").
 			Query(repair.CREATE_VERSION_TABLE).
-			Reply("CREATE TABLE")
+			Reply("CREATE TABLE").
+			Query(repair.ADD_STATEMENTS_COLUMN).
+			Reply("ALTER TABLE")
 		// Run test
 		err := linkDatabase(context.Background(), dbConfig, conn.Intercept)
 		// Check error
@@ -320,7 +324,9 @@ func TestLinkDatabase(t *testing.T) {
 		conn.Query(repair.CREATE_VERSION_SCHEMA).
 			Reply("CREATE SCHEMA").
 			Query(repair.CREATE_VERSION_TABLE).
-			Reply("CREATE TABLE")
+			Reply("CREATE TABLE").
+			Query(repair.ADD_STATEMENTS_COLUMN).
+			Reply("ALTER TABLE")
 		// Run test
 		err := linkDatabase(context.Background(), dbConfig, conn.Intercept)
 		// Check error
@@ -340,7 +346,8 @@ func TestLinkDatabase(t *testing.T) {
 		conn.Query(repair.CREATE_VERSION_SCHEMA).
 			Reply("CREATE SCHEMA").
 			Query(repair.CREATE_VERSION_TABLE).
-			ReplyError(pgerrcode.InsufficientPrivilege, "permission denied for relation supabase_migrations")
+			ReplyError(pgerrcode.InsufficientPrivilege, "permission denied for relation supabase_migrations").
+			Query(repair.ADD_STATEMENTS_COLUMN)
 		// Run test
 		err := linkDatabase(context.Background(), dbConfig, conn.Intercept)
 		// Check error
diff --git a/internal/migration/apply/apply_test.go b/internal/migration/apply/apply_test.go
index c29ab4a7..ed9ea2ea 100644
--- a/internal/migration/apply/apply_test.go
+++ b/internal/migration/apply/apply_test.go
@@ -1,23 +1,20 @@
 package apply
 
 import (
-	"bufio"
 	"context"
+	"fmt"
 	"os"
 	"path/filepath"
-	"strings"
 	"testing"
 
 	"github.com/jackc/pgconn"
 	"github.com/jackc/pgerrcode"
 	"github.com/spf13/afero"
-	"github.com/spf13/viper"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/supabase/cli/internal/migration/repair"
 	"github.com/supabase/cli/internal/testing/pgtest"
 	"github.com/supabase/cli/internal/utils"
-	"github.com/supabase/cli/internal/utils/parser"
 )
 
 func TestMigrateDatabase(t *testing.T) {
@@ -34,9 +31,11 @@ func TestMigrateDatabase(t *testing.T) {
 			Reply("CREATE SCHEMA").
 			Query(repair.CREATE_VERSION_TABLE).
 			Reply("CREATE TABLE").
+			Query(repair.ADD_STATEMENTS_COLUMN).
+			Reply("ALTER TABLE").
 			Query(sql).
 			Reply("CREATE SCHEMA").
-			Query(repair.INSERT_MIGRATION_VERSION, "0").
+			Query(repair.INSERT_MIGRATION_VERSION, "0", fmt.Sprintf("{%s}", sql)).
 			Reply("INSERT 1")
 		// Connect to mock
 		ctx := context.Background()
@@ -74,7 +73,8 @@ func TestMigrateUp(t *testing.T) {
 		conn.Query(repair.CREATE_VERSION_SCHEMA).
 			Reply("CREATE SCHEMA").
 			Query(repair.CREATE_VERSION_TABLE).
-			ReplyError(pgerrcode.InsufficientPrivilege, "permission denied for relation supabase_migrations")
+			ReplyError(pgerrcode.InsufficientPrivilege, "permission denied for relation supabase_migrations").
+			Query(repair.ADD_STATEMENTS_COLUMN)
 		// Connect to mock
 		ctx := context.Background()
 		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
@@ -95,7 +95,9 @@ func TestMigrateUp(t *testing.T) {
 		conn.Query(repair.CREATE_VERSION_SCHEMA).
 			Reply("CREATE SCHEMA").
 			Query(repair.CREATE_VERSION_TABLE).
-			Reply("CREATE TABLE")
+			Reply("CREATE TABLE").
+			Query(repair.ADD_STATEMENTS_COLUMN).
+			Reply("ALTER TABLE")
 		// Connect to mock
 		ctx := context.Background()
 		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
@@ -107,56 +109,3 @@ func TestMigrateUp(t *testing.T) {
 		assert.ErrorIs(t, err, os.ErrNotExist)
 	})
 }
-
-func TestMigrationFile(t *testing.T) {
-	t.Run("new from file sets max token", func(t *testing.T) {
-		viper.Reset()
-		// Setup in-memory fs
-		fsys := afero.NewMemMapFs()
-		// Setup initial migration
-		name := "20220727064247_create_table.sql"
-		path := filepath.Join(utils.MigrationsDir, name)
-		query := "BEGIN; " + strings.Repeat("a", parser.MaxScannerCapacity)
-		require.NoError(t, afero.WriteFile(fsys, path, []byte(query), 0644))
-		// Run test
-		migration, err := NewMigrationFromFile(path, fsys)
-		// Check error
-		assert.NoError(t, err)
-		assert.Len(t, migration.Lines, 2)
-		assert.Equal(t, "20220727064247", migration.version)
-	})
-
-	t.Run("new from reader errors on max token", func(t *testing.T) {
-		viper.Reset()
-		sql := "\tBEGIN; " + strings.Repeat("a", parser.MaxScannerCapacity)
-		// Run test
-		migration, err := NewMigrationFromReader(strings.NewReader(sql))
-		// Check error
-		assert.ErrorIs(t, err, bufio.ErrTooLong)
-		assert.ErrorContains(t, err, "After statement 1: \tBEGIN;")
-		assert.Nil(t, migration)
-	})
-
-	t.Run("throws error on insert failure", func(t *testing.T) {
-		migration := MigrationFile{
-			Lines:   []string{"create schema public"},
-			version: "0",
-		}
-		// Setup mock postgres
-		conn := pgtest.NewConn()
-		defer conn.Close(t)
-		conn.Query(migration.Lines[0]).
-			ReplyError(pgerrcode.DuplicateSchema, `schema "public" already exists`).
-			Query(repair.INSERT_MIGRATION_VERSION, "0")
-		// Connect to mock
-		ctx := context.Background()
-		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
-		require.NoError(t, err)
-		defer mock.Close(ctx)
-		// Run test
-		err = migration.ExecBatch(context.Background(), mock)
-		// Check error
-		assert.ErrorContains(t, err, "ERROR: schema \"public\" already exists (SQLSTATE 42P06)")
-		assert.ErrorContains(t, err, "At statement 0: create schema public")
-	})
-}
diff --git a/internal/migration/repair/repair_test.go b/internal/migration/repair/repair_test.go
index 5c8849c3..55c453e4 100644
--- a/internal/migration/repair/repair_test.go
+++ b/internal/migration/repair/repair_test.go
@@ -1,13 +1,22 @@
 package repair
 
 import (
+	"bufio"
 	"context"
+	"fmt"
+	"path/filepath"
+	"strings"
 	"testing"
 
 	"github.com/jackc/pgconn"
 	"github.com/jackc/pgerrcode"
+	"github.com/spf13/afero"
+	"github.com/spf13/viper"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	"github.com/supabase/cli/internal/testing/pgtest"
+	"github.com/supabase/cli/internal/utils"
+	"github.com/supabase/cli/internal/utils/parser"
 )
 
 var dbConfig = pgconn.Config{
@@ -20,6 +29,10 @@ var dbConfig = pgconn.Config{
 
 func TestRepairCommand(t *testing.T) {
 	t.Run("applies new version", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
+		path := filepath.Join(utils.MigrationsDir, "0_test.sql")
+		require.NoError(t, afero.WriteFile(fsys, path, []byte(""), 0644))
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
@@ -27,15 +40,19 @@ func TestRepairCommand(t *testing.T) {
 			Reply("CREATE SCHEMA").
 			Query(CREATE_VERSION_TABLE).
 			Reply("CREATE TABLE").
-			Query(INSERT_MIGRATION_VERSION, "0").
+			Query(ADD_STATEMENTS_COLUMN).
+			Reply("ALTER TABLE").
+			Query(INSERT_MIGRATION_VERSION, "0", "{}").
 			Reply("INSERT 0 1")
 		// Run test
-		err := Run(context.Background(), dbConfig, "0", Applied, conn.Intercept)
+		err := Run(context.Background(), dbConfig, "0", Applied, fsys, conn.Intercept)
 		// Check error
 		assert.NoError(t, err)
 	})
 
 	t.Run("reverts old version", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
@@ -43,22 +60,30 @@ func TestRepairCommand(t *testing.T) {
 			Reply("CREATE SCHEMA").
 			Query(CREATE_VERSION_TABLE).
 			Reply("CREATE TABLE").
+			Query(ADD_STATEMENTS_COLUMN).
+			Reply("ALTER TABLE").
 			Query(DELETE_MIGRATION_VERSION, "0").
 			Reply("DELETE 1")
 		// Run test
-		err := Run(context.Background(), dbConfig, "0", Reverted, conn.Intercept)
+		err := Run(context.Background(), dbConfig, "0", Reverted, fsys, conn.Intercept)
 		// Check error
 		assert.NoError(t, err)
 	})
 
 	t.Run("throws error on connect failure", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
 		// Run test
-		err := Run(context.Background(), pgconn.Config{}, "0", Applied)
+		err := Run(context.Background(), pgconn.Config{}, "0", Applied, fsys)
 		// Check error
 		assert.ErrorContains(t, err, "invalid port (outside range)")
 	})
 
 	t.Run("throws error on insert failure", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
+		path := filepath.Join(utils.MigrationsDir, "0_test.sql")
+		require.NoError(t, afero.WriteFile(fsys, path, []byte(""), 0644))
 		// Setup mock postgres
 		conn := pgtest.NewConn()
 		defer conn.Close(t)
@@ -66,11 +91,66 @@ func TestRepairCommand(t *testing.T) {
 			Reply("CREATE SCHEMA").
 			Query(CREATE_VERSION_TABLE).
 			Reply("CREATE TABLE").
-			Query(INSERT_MIGRATION_VERSION, "0").
+			Query(ADD_STATEMENTS_COLUMN).
+			Reply("ALTER TABLE").
+			Query(INSERT_MIGRATION_VERSION, "0", "{}").
 			ReplyError(pgerrcode.DuplicateObject, `relation "supabase_migrations.schema_migrations" does not exist`)
 		// Run test
-		err := Run(context.Background(), dbConfig, "0", Applied, conn.Intercept)
+		err := Run(context.Background(), dbConfig, "0", Applied, fsys, conn.Intercept)
 		// Check error
 		assert.ErrorContains(t, err, `ERROR: relation "supabase_migrations.schema_migrations" does not exist (SQLSTATE 42710)`)
 	})
 }
+
+func TestMigrationFile(t *testing.T) {
+	t.Run("new from file sets max token", func(t *testing.T) {
+		viper.Reset()
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
+		// Setup initial migration
+		name := "20220727064247_create_table.sql"
+		path := filepath.Join(utils.MigrationsDir, name)
+		query := "BEGIN; " + strings.Repeat("a", parser.MaxScannerCapacity)
+		require.NoError(t, afero.WriteFile(fsys, path, []byte(query), 0644))
+		// Run test
+		migration, err := NewMigrationFromFile(path, fsys)
+		// Check error
+		assert.NoError(t, err)
+		assert.Len(t, migration.Lines, 2)
+		assert.Equal(t, "20220727064247", migration.version)
+	})
+
+	t.Run("new from reader errors on max token", func(t *testing.T) {
+		viper.Reset()
+		sql := "\tBEGIN; " + strings.Repeat("a", parser.MaxScannerCapacity)
+		// Run test
+		migration, err := NewMigrationFromReader(strings.NewReader(sql))
+		// Check error
+		assert.ErrorIs(t, err, bufio.ErrTooLong)
+		assert.ErrorContains(t, err, "After statement 1: \tBEGIN;")
+		assert.Nil(t, migration)
+	})
+
+	t.Run("throws error on insert failure", func(t *testing.T) {
+		migration := MigrationFile{
+			Lines:   []string{"create schema public"},
+			version: "0",
+		}
+		// Setup mock postgres
+		conn := pgtest.NewConn()
+		defer conn.Close(t)
+		conn.Query(migration.Lines[0]).
+			ReplyError(pgerrcode.DuplicateSchema, `schema "public" already exists`).
+			Query(INSERT_MIGRATION_VERSION, "0", fmt.Sprintf("{%s}", migration.Lines[0]))
+		// Connect to mock
+		ctx := context.Background()
+		mock, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{Port: 5432}, conn.Intercept)
+		require.NoError(t, err)
+		defer mock.Close(ctx)
+		// Run test
+		err = migration.ExecBatch(context.Background(), mock)
+		// Check error
+		assert.ErrorContains(t, err, "ERROR: schema \"public\" already exists (SQLSTATE 42P06)")
+		assert.ErrorContains(t, err, "At statement 0: create schema public")
+	})
+}