├── .github
├── ops
│ └── mysql
│ │ └── Dockerfile
└── workflows
│ ├── cd-docker-push-cockroach_oss.yaml
│ ├── cd-docker-push-mysql_oss.yaml
│ ├── ci-dialect_oss.yaml
│ ├── ci-go_oss.yaml
│ └── ci-revisions_oss.yaml
├── .golangci.yml
├── LICENSE
├── README.md
├── cmd
└── atlas
│ ├── go.mod
│ ├── go.sum
│ ├── internal
│ ├── cloudapi
│ │ ├── client.go
│ │ ├── client_oss.go
│ │ └── client_test.go
│ ├── cmdapi
│ │ ├── cmdapi.go
│ │ ├── cmdapi_oss.go
│ │ ├── cmdapi_test.go
│ │ ├── migrate.go
│ │ ├── migrate_oss.go
│ │ ├── migrate_test.go
│ │ ├── project.go
│ │ ├── project_test.go
│ │ ├── schema.go
│ │ ├── schema_test.go
│ │ ├── testdata
│ │ │ ├── baseline1
│ │ │ │ ├── 1_baseline.sql
│ │ │ │ └── atlas.sum
│ │ │ ├── baseline2
│ │ │ │ ├── 1_baseline.sql
│ │ │ │ ├── 20220318104614_initial.sql
│ │ │ │ ├── 20220318104615_second.sql
│ │ │ │ └── atlas.sum
│ │ │ ├── import
│ │ │ │ ├── dbmate
│ │ │ │ │ ├── 1_initial.sql
│ │ │ │ │ └── 2_second_migration.sql
│ │ │ │ ├── dbmate_gold
│ │ │ │ │ ├── 1_initial.sql
│ │ │ │ │ └── 2_second_migration.sql
│ │ │ │ ├── flyway
│ │ │ │ │ ├── B2__baseline.sql
│ │ │ │ │ ├── R__views.sql
│ │ │ │ │ ├── U1__initial.sql
│ │ │ │ │ ├── V1__initial.sql
│ │ │ │ │ ├── V2__second_migration.sql
│ │ │ │ │ └── V3__third_migration.sql
│ │ │ │ ├── flyway_gold
│ │ │ │ │ ├── 2_baseline.sql
│ │ │ │ │ ├── 3R_views.sql
│ │ │ │ │ └── 3_third_migration.sql
│ │ │ │ ├── golang-migrate
│ │ │ │ │ ├── 1_initial.down.sql
│ │ │ │ │ ├── 1_initial.up.sql
│ │ │ │ │ ├── 2_second_migration.down.sql
│ │ │ │ │ └── 2_second_migration.up.sql
│ │ │ │ ├── golang-migrate_gold
│ │ │ │ │ ├── 1_initial.sql
│ │ │ │ │ └── 2_second_migration.sql
│ │ │ │ ├── goose
│ │ │ │ │ ├── 1_initial.sql
│ │ │ │ │ └── 2_second_migration.sql
│ │ │ │ ├── goose_gold
│ │ │ │ │ ├── 1_initial.sql
│ │ │ │ │ └── 2_second_migration.sql
│ │ │ │ ├── liquibase
│ │ │ │ │ ├── 1_initial.sql
│ │ │ │ │ └── 2_second_migration.sql
│ │ │ │ └── liquibase_gold
│ │ │ │ │ ├── 1_initial.sql
│ │ │ │ │ └── 2_second_migration.sql
│ │ │ ├── mysql
│ │ │ │ ├── 20220318104614_initial.sql
│ │ │ │ ├── 20220420213403_second.sql
│ │ │ │ └── atlas.sum
│ │ │ ├── sqlite
│ │ │ │ ├── 20220318104614_initial.sql
│ │ │ │ ├── 20220318104615_second.sql
│ │ │ │ └── atlas.sum
│ │ │ ├── sqlite2
│ │ │ │ ├── 20220318104614_initial.sql
│ │ │ │ ├── 20220318104615_second.sql
│ │ │ │ └── atlas.sum
│ │ │ ├── sqlitetx
│ │ │ │ ├── 20220925092817_initial.sql
│ │ │ │ ├── 20220925094021_second.sql
│ │ │ │ ├── 20220925094437_third.sql
│ │ │ │ └── atlas.sum
│ │ │ ├── sqlitetx2
│ │ │ │ ├── 20220925092817_initial.sql
│ │ │ │ ├── 20220925094021_second.sql
│ │ │ │ ├── 20220925094437_third.sql
│ │ │ │ └── atlas.sum
│ │ │ ├── sqlitetx3
│ │ │ │ ├── 20220925092817_initial.sql
│ │ │ │ ├── 20220925094021_second.sql
│ │ │ │ └── atlas.sum
│ │ │ ├── sqlitetx4
│ │ │ │ ├── 20220925092817_initial.sql
│ │ │ │ ├── 20220925094021_second.sql
│ │ │ │ └── atlas.sum
│ │ │ └── templatedir
│ │ │ │ ├── 1.sql
│ │ │ │ ├── 2.sql
│ │ │ │ ├── atlas.sum
│ │ │ │ └── shared
│ │ │ │ └── users.sql
│ │ ├── vercheck
│ │ │ ├── notification.tmpl
│ │ │ ├── req_oss.go
│ │ │ ├── vercheck.go
│ │ │ └── vercheck_test.go
│ │ ├── version_oss.go
│ │ └── version_oss_test.go
│ ├── cmdext
│ │ ├── cmdext.go
│ │ ├── cmdext_oss.go
│ │ ├── cmdext_test.go
│ │ ├── reader.go
│ │ └── reader_test.go
│ ├── cmdlog
│ │ ├── cmdlog.go
│ │ ├── cmdlog_oss.go
│ │ └── cmdlog_test.go
│ ├── cmdstate
│ │ ├── cmdstate.go
│ │ └── cmdstate_test.go
│ ├── docker
│ │ ├── docker.go
│ │ └── docker_test.go
│ ├── migrate
│ │ ├── ent
│ │ │ ├── client.go
│ │ │ ├── convert.go
│ │ │ ├── ent.go
│ │ │ ├── entc.go
│ │ │ ├── enttest
│ │ │ │ └── enttest.go
│ │ │ ├── generate.go
│ │ │ ├── hook
│ │ │ │ └── hook.go
│ │ │ ├── internal
│ │ │ │ └── schemaconfig.go
│ │ │ ├── migrate
│ │ │ │ ├── migrate.go
│ │ │ │ └── schema.go
│ │ │ ├── mutation.go
│ │ │ ├── predicate
│ │ │ │ └── predicate.go
│ │ │ ├── revision.go
│ │ │ ├── revision
│ │ │ │ ├── revision.go
│ │ │ │ └── where.go
│ │ │ ├── revision_create.go
│ │ │ ├── revision_delete.go
│ │ │ ├── revision_query.go
│ │ │ ├── revision_update.go
│ │ │ ├── runtime.go
│ │ │ ├── runtime
│ │ │ │ └── runtime.go
│ │ │ ├── schema
│ │ │ │ └── revision.go
│ │ │ ├── template
│ │ │ │ └── convert.tmpl
│ │ │ └── tx.go
│ │ ├── migrate.go
│ │ ├── migrate_oss.go
│ │ ├── migrate_test.go
│ │ └── testdata
│ │ │ ├── broken
│ │ │ ├── 1.sql
│ │ │ ├── 2.sql
│ │ │ ├── 3.sql
│ │ │ └── atlas.sum
│ │ │ └── fixed
│ │ │ ├── 1.sql
│ │ │ ├── 2.sql
│ │ │ ├── 3.sql
│ │ │ └── atlas.sum
│ ├── migratelint
│ │ ├── lint.go
│ │ ├── lint_oss.go
│ │ └── lint_test.go
│ └── sqlparse
│ │ ├── myparse
│ │ └── myparse_oss.go
│ │ ├── parseutil
│ │ └── parseutil.go
│ │ ├── pgparse
│ │ └── pgparse_oss.go
│ │ ├── sqliteparse
│ │ ├── Lexer.g4
│ │ ├── Parser.g4
│ │ ├── README.md
│ │ ├── lexer.go
│ │ ├── parser.go
│ │ ├── parser_base_listener.go
│ │ ├── parser_base_visitor.go
│ │ ├── parser_listener.go
│ │ ├── parser_visitor.go
│ │ └── sqliteparse_oss.go
│ │ └── sqlparse.go
│ ├── main.go
│ └── main_oss.go
├── go.mod
├── go.sum
├── internal
├── ci
│ ├── ci_dialect.tmpl
│ ├── ci_go.tmpl
│ ├── ci_revisions.tmpl
│ ├── cockroach
│ │ ├── Dockerfile.tmpl
│ │ └── main.go
│ ├── jobs_oss.go
│ └── main.go
└── integration
│ ├── README.md
│ ├── cockroach_test.go
│ ├── docker-compose.yaml
│ ├── go.mod
│ ├── go.sum
│ ├── hclsqlspec
│ └── hclsqlspec_test.go
│ ├── integration_test.go
│ ├── mysql_test.go
│ ├── postgres_test.go
│ ├── script_test.go
│ ├── sqlite_test.go
│ ├── testdata
│ ├── migrations
│ │ ├── mysql
│ │ │ ├── 1_initial.sql
│ │ │ └── atlas.sum
│ │ ├── mysqlock
│ │ │ ├── 1.sql
│ │ │ ├── 2.sql
│ │ │ ├── 3.sql
│ │ │ └── atlas.sum
│ │ └── postgres
│ │ │ ├── 1_initial.sql
│ │ │ └── atlas.sum
│ ├── mysql
│ │ ├── autoincrement.txtar
│ │ ├── check-maria.txtar
│ │ ├── check.txtar
│ │ ├── cli-inspect-file.txtar
│ │ ├── cli-migrate-apply-datasrc.txtar
│ │ ├── cli-migrate-apply.txtar
│ │ ├── cli-migrate-diff-format.txtar
│ │ ├── cli-migrate-diff-mode-normalized.txtar
│ │ ├── cli-migrate-diff.txtar
│ │ ├── cli-project-schemas.txtar
│ │ ├── cli-project-url-escape.txtar
│ │ ├── cli-schema-apply-datasrc.txtar
│ │ ├── column-add-drop.txtar
│ │ ├── column-bit.txtar
│ │ ├── column-bool.txtar
│ │ ├── column-charset.txtar
│ │ ├── column-default-expr.txtar
│ │ ├── column-generated-inspect.txtar
│ │ ├── column-generated.txtar
│ │ ├── column-json.txtar
│ │ ├── column-time-precision-maria.txtar
│ │ ├── column-time-precision-mysql.txtar
│ │ ├── foreign-key-add.txtar
│ │ ├── foreign-key-modify-action.txtar
│ │ ├── foreign-key.txtar
│ │ ├── index-add-drop.txtar
│ │ ├── index-desc.txtar
│ │ ├── index-expr.txtar
│ │ ├── index-prefix.txtar
│ │ ├── index-type.txtar
│ │ ├── index-unique.txtar
│ │ ├── primary-key-parts.txtar
│ │ ├── primary-key.txtar
│ │ └── table-engine.txtar
│ ├── postgres
│ │ ├── cli-inspect-file.txtar
│ │ ├── cli-inspect.txtar
│ │ ├── cli-migrate-apply-datasrc.txtar
│ │ ├── cli-migrate-apply.txtar
│ │ ├── cli-migrate-diff-unsupported.txtar
│ │ ├── cli-migrate-diff.txtar
│ │ ├── cli-migrate-status.txtar
│ │ ├── column-array.txtar
│ │ ├── column-bit.txtar
│ │ ├── column-comment.txtar
│ │ ├── column-default.txtar
│ │ ├── column-domain.txtar
│ │ ├── column-enum-array.txtar
│ │ ├── column-enum.txtar
│ │ ├── column-float.txtar
│ │ ├── column-generated-inspect.txtar
│ │ ├── column-identity.txtar
│ │ ├── column-interval.txtar
│ │ ├── column-numeric.txtar
│ │ ├── column-range.txtar
│ │ ├── column-serial.txtar
│ │ ├── column-textsearch.txtar
│ │ ├── column-time-precision.txtar
│ │ ├── foreign-key-action.txtar
│ │ ├── foreign-key.txtar
│ │ ├── index-desc.txtar
│ │ ├── index-expr.txtar
│ │ ├── index-include.txtar
│ │ ├── index-issue-557.txtar
│ │ ├── index-nulls-distinct.txtar
│ │ ├── index-operator-class.txtar
│ │ ├── index-partial.txtar
│ │ ├── index-type-brin.txtar
│ │ ├── index-type.txtar
│ │ ├── index-unique-constraint.txtar
│ │ ├── primary-key.txtar
│ │ ├── table-checks.txtar
│ │ └── table-partition.txtar
│ └── sqlite
│ │ ├── autoincrement.txtar
│ │ ├── cli-apply-multifile.txtar
│ │ ├── cli-apply-project-multifile.txtar
│ │ ├── cli-apply-vars.txtar
│ │ ├── cli-inspect.txtar
│ │ ├── cli-migrate-apply.txtar
│ │ ├── cli-migrate-diff-datasrc-hcl-paths.txtar
│ │ ├── cli-migrate-diff-datasrc-hcl.txtar
│ │ ├── cli-migrate-diff-minimal-env.txtar
│ │ ├── cli-migrate-diff-multifile.txtar
│ │ ├── cli-migrate-diff-sql.txtar
│ │ ├── cli-migrate-diff.txtar
│ │ ├── cli-migrate-lint-add-notnull.txtar
│ │ ├── cli-migrate-lint-destructive.txtar
│ │ ├── cli-migrate-lint-ignore.txtar
│ │ ├── cli-migrate-lint-minimal-env.txtar
│ │ ├── cli-migrate-lint-project.txtar
│ │ ├── cli-migrate-project-multifile.txtar
│ │ ├── cli-migrate-project.txtar
│ │ ├── cli-migrate-set.txtar
│ │ ├── cli-project-vars.txtar
│ │ ├── cli-schema-project-file.txtar
│ │ ├── column-default.txtar
│ │ ├── column-generated.txtar
│ │ ├── column-user-defined.txtar
│ │ ├── index-desc.txtar
│ │ ├── index-expr.txtar
│ │ ├── index-partial.txtar
│ │ └── table-options.txtar
│ ├── tidb_test.go
│ └── tools.go
├── schemahcl
├── context.go
├── context_test.go
├── extension.go
├── extension_test.go
├── schemahcl.go
├── schemahcl_test.go
├── spec.go
├── spec_test.go
├── stdlib.go
├── stdlib_test.go
├── testdata
│ ├── a.hcl
│ ├── b.hcl
│ ├── nested
│ │ └── c.hcl
│ └── variables.hcl
├── types.go
└── types_test.go
└── sql
├── internal
├── spectest
│ └── spectest.go
├── specutil
│ ├── convert.go
│ ├── convert_test.go
│ └── spec.go
├── sqltest
│ └── sqltest.go
└── sqlx
│ ├── dev.go
│ ├── dev_test.go
│ ├── diff.go
│ ├── plan.go
│ ├── plan_test.go
│ ├── sqlx.go
│ ├── sqlx_oss.go
│ └── sqlx_test.go
├── migrate
├── dir.go
├── dir_test.go
├── lex.go
├── lex_test.go
├── migrate.go
├── migrate_oss.go
├── migrate_test.go
└── testdata
│ ├── golang-migrate
│ └── 1_base.up.sql
│ ├── lex
│ ├── 1.sql
│ ├── 1.sql.golden
│ ├── 10_delimiter_comment.sql
│ ├── 10_delimiter_comment.sql.golden
│ ├── 11_delimiter_mysql_command.sql
│ ├── 11_delimiter_mysql_command.sql.golden
│ ├── 12_delimiter_mysql_command.sql
│ ├── 12_delimiter_mysql_command.sql.golden
│ ├── 13_delimiter_mysql_command.sql
│ ├── 13_delimiter_mysql_command.sql.golden
│ ├── 14_delimiter_mysql_command.sql
│ ├── 14_delimiter_mysql_command.sql.golden
│ ├── 15_dollar_quote.sql
│ ├── 15_dollar_quote.sql.golden
│ ├── 16_begin_atomic.sql
│ ├── 16_begin_atomic.sql.golden
│ ├── 17_paren.sql
│ ├── 17_paren.sql.golden
│ ├── 18_pg_expr.sql
│ ├── 18_pg_expr.sql.golden
│ ├── 19_ms_gocmd.sql
│ ├── 19_ms_gocmd.sql.golden
│ ├── 20_ms_go-delim.sql
│ ├── 20_ms_go-delim.sql.golden
│ ├── 2_mysql.sql
│ ├── 2_mysql.sql.golden
│ ├── 3_delimiter.sql
│ ├── 3_delimiter.sql.golden
│ ├── 4_delimiter.sql
│ ├── 4_delimiter.sql.golden
│ ├── 5_delimiter.sql
│ ├── 5_delimiter.sql.golden
│ ├── 6_skip_comment.sql
│ ├── 6_skip_comment.sql.golden
│ ├── 7_delimiter_2n.sql
│ ├── 7_delimiter_2n.sql.golden
│ ├── 8_delimiter_3n.sql
│ ├── 8_delimiter_3n.sql.golden
│ ├── 9_delimiter_3n.sql
│ └── 9_delimiter_3n.sql.golden
│ ├── lexbegintry
│ ├── 1.sql
│ └── 1.sql.golden
│ ├── lexescaped
│ ├── 1.my.sql
│ ├── 1.my.sql.golden
│ ├── 2.pg.sql
│ └── 2.pg.sql.golden
│ ├── lexgroup
│ ├── 1_trigger.sql
│ ├── 1_trigger.sql.golden
│ ├── 2_function.sql
│ ├── 2_function.sql.golden
│ ├── 3_delimiter.sql
│ └── 3_delimiter.sql.golden
│ ├── migrate
│ ├── 1_initial.down.sql
│ ├── 1_initial.up.sql
│ ├── atlas.sum
│ └── sub
│ │ ├── 1.a_sub.up.sql
│ │ ├── 2.10.x-20_description.sql
│ │ ├── 3_partly.sql
│ │ └── atlas.sum
│ ├── partial-checkpoint
│ ├── 1_first.sql
│ ├── 2_second.sql
│ ├── 3_checkpoint.sql
│ ├── 4_fourth.sql
│ ├── 5_checkpoint.sql
│ ├── 6_sixth.sql
│ └── atlas.sum
│ └── sqlserver
│ ├── 1_return_table.sql
│ ├── 1_return_table.sql.golden
│ ├── 2_function.sql
│ └── 2_function.sql.golden
├── mysql
├── convert.go
├── diff_oss.go
├── diff_oss_test.go
├── driver_oss.go
├── driver_oss_test.go
├── inspect_oss.go
├── inspect_oss_test.go
├── internal
│ └── mysqlversion
│ │ ├── is
│ │ ├── .README.md
│ │ ├── charset2collate
│ │ ├── charset2collate.maria
│ │ ├── collate2charset
│ │ └── collate2charset.maria
│ │ ├── mysqlversion.go
│ │ └── mysqlversion_test.go
├── migrate_oss.go
├── migrate_oss_test.go
├── mysqlcheck
│ ├── mysqlcheck.go
│ ├── mysqlcheck_oss.go
│ └── mysqlcheck_test.go
├── sqlspec_oss.go
├── sqlspec_oss_test.go
└── tidb.go
├── postgres
├── convert.go
├── crdb_oss.go
├── diff_oss.go
├── diff_oss_test.go
├── driver_oss.go
├── driver_oss_test.go
├── inspect_oss.go
├── inspect_oss_test.go
├── internal
│ └── postgresop
│ │ └── postgresop.go
├── migrate_oss.go
├── migrate_oss_test.go
├── postgrescheck
│ ├── postgrescheck.go
│ ├── postgrescheck_oss.go
│ └── postgrescheck_test.go
├── sqlspec_oss.go
└── sqlspec_oss_test.go
├── schema
├── changekind_string.go
├── dsl.go
├── dsl_test.go
├── exclude_oss.go
├── inspect.go
├── migrate.go
├── migrate_test.go
└── schema.go
├── sqlcheck
├── condrop
│ ├── condrop.go
│ └── condrop_test.go
├── datadepend
│ ├── datadepend.go
│ └── datadepend_test.go
├── destructive
│ ├── destructive.go
│ ├── destructive_oss.go
│ └── destructive_test.go
├── incompatible
│ ├── incompatible.go
│ └── incompatible_test.go
└── sqlcheck.go
├── sqlclient
├── client.go
└── client_test.go
├── sqlite
├── convert.go
├── diff.go
├── diff_test.go
├── driver.go
├── driver_oss.go
├── driver_test.go
├── inspect.go
├── inspect_test.go
├── migrate.go
├── migrate_test.go
├── sqlitecheck
│ ├── sqlitecheck.go
│ ├── sqlitecheck_oss.go
│ └── sqlitecheck_test.go
├── sqlspec.go
└── sqlspec_test.go
├── sqlspec
├── sqlspec.go
└── sqlspec_test.go
└── sqltool
├── doc.go
├── hidden.go
├── hidden_windows.go
├── testdata
├── dbmate
│ ├── 1_initial.sql
│ └── 2_second_migration.sql
├── flyway
│ ├── B2__baseline.sql
│ ├── R__views.sql
│ ├── U1__initial.sql
│ ├── V1__initial.sql
│ ├── V2__second_migration.sql
│ ├── V3__third_migration.sql
│ └── v3
│ │ └── V3_1__fourth_migration.sql
├── golang-migrate
│ ├── 1_initial.down.sql
│ ├── 1_initial.up.sql
│ ├── 2_second_migration.down.sql
│ └── 2_second_migration.up.sql
├── goose
│ ├── 1_initial.sql
│ └── 2_second_migration.sql
└── liquibase
│ ├── 1_initial.sql
│ └── 2_second_migration.sql
├── tool.go
└── tool_test.go
/.github/ops/mysql/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG DIALECT=mysql:8.0
2 |
3 | FROM $DIALECT as builder
4 |
5 | ARG SERVER=mysqld
6 | ENV MYSQL_ROOT_PASSWORD=pass
7 |
8 | # Remove the last line of the entry point script, leaving the initialization code but omitting actually starting the db.
9 | RUN sed -i 's/exec "$@"/echo "not running $@"/' /usr/local/bin/docker-entrypoint.sh
10 | RUN /usr/local/bin/docker-entrypoint.sh ${SERVER}
11 |
12 | FROM $DIALECT
13 |
14 | COPY --from=builder /var/lib/mysql /var/lib/mysql
15 |
--------------------------------------------------------------------------------
/.github/workflows/cd-docker-push-cockroach_oss.yaml:
--------------------------------------------------------------------------------
1 | name: CD - Build Docker - Cockroach - Community Edition
2 | on:
3 | pull_request:
4 | push:
5 | branches:
6 | - master
7 |
8 | env:
9 | CRDB_VERSIONS: v21.2.11 v22.1.0
10 |
11 | jobs:
12 | build-services:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - uses: actions/setup-go@v5
17 | with:
18 | go-version-file: cmd/atlas/go.mod
19 | - name: Log in to registry
20 | run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
21 | - name: "build cockroach image"
22 | run: |
23 | VER="${{ env.CRDB_VERSIONS }}"
24 | for i in $VER
25 | do
26 | :
27 | if ! docker manifest inspect ghcr.io/ariga/cockroachdb-single-node:$i; then
28 | go run internal/ci/cockroach/main.go $i > internal/ci/cockroach/Dockerfile
29 | docker build -t ghcr.io/ariga/cockroachdb-single-node:$i internal/ci/cockroach/
30 | docker push ghcr.io/ariga/cockroachdb-single-node:$i
31 | else
32 | echo image already exists
33 | fi
34 | done
--------------------------------------------------------------------------------
/.github/workflows/ci-revisions_oss.yaml:
--------------------------------------------------------------------------------
1 | # # # # # # # # # # # # # # # #
2 | # CODE GENERATED - DO NOT EDIT
3 | # # # # # # # # # # # # # # # #
4 | name: CI - Revisions - Community Edition
5 | on:
6 | pull_request:
7 | paths:
8 | - 'cmd/atlas/internal/migrate/ent/**'
9 | push:
10 | branches:
11 | - master
12 | paths:
13 | - 'cmd/atlas/internal/migrate/ent/**'
14 | concurrency:
15 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
16 | cancel-in-progress: true
17 | jobs:
18 | revisions:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - uses: actions/checkout@v4
22 | with:
23 | fetch-depth: 0
24 | - uses: actions/setup-go@v5
25 | with:
26 | go-version-file: cmd/atlas/go.mod
27 | - name: Checkout origin/master
28 | run: git checkout origin/master
29 | - name: Create revisions from master
30 | run: go run . migrate apply --dir file://internal/cmdapi/testdata/sqlite --url sqlite://db?_fk=1
31 | working-directory: cmd/atlas
32 | - name: Checkout previous HEAD
33 | run: git checkout -
34 | - name: Migrate revisions table to HEAD
35 | run: go run . migrate apply --dir file://internal/cmdapi/testdata/sqlite --url sqlite://db?_fk=1
36 | working-directory: cmd/atlas
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | run:
2 | timeout: 3m
3 |
4 | issues:
5 | include:
6 | - EXC0012
7 | exclude:
8 | - G601
9 | - G404
10 | - redefines-builtin-id
11 | exclude-rules:
12 | - path: _test\.go
13 | linters:
14 | - gosec
15 | - path: sql/migrate/dir.go
16 | linters:
17 | - gosec
18 | - path: sql/migrate/lex.go
19 | linters:
20 | - revive
21 | - path: sql/internal/sqlx/diff.go
22 | linters:
23 | - revive
24 |
25 | linters-settings:
26 | goheader:
27 | template: |-
28 | Copyright 2021-present The Atlas Authors. All rights reserved.
29 | This source code is licensed under the Apache 2.0 license found
30 | in the LICENSE file in the root directory of this source tree.
31 |
32 | linters:
33 | disable-all: true
34 | enable:
35 | - gosec
36 | - revive
37 | - goheader
38 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cloudapi/client_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package cloudapi
8 |
9 | import (
10 | "net/url"
11 | )
12 |
13 | func testingURL(endpoint string) bool {
14 | u, err := url.Parse(endpoint)
15 | if err != nil {
16 | return false
17 | }
18 | host := u.Hostname()
19 | return host == "localhost" || host == "127.0.0.1"
20 | }
21 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/baseline1/1_baseline.sql:
--------------------------------------------------------------------------------
1 | -- create "baseline" table
2 | CREATE TABLE baseline (`c` int NOT NULL);
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/baseline1/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:GqOjMVGk2H0qYhhtJ1SPCyyHEBbWP/LD2ueWQTY4e6A=
2 | 1_baseline.sql h1:rZgkRmNcN2UEKgxru1nHCpBRVn/fjFavyQ4xxPxhrD4=
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/baseline2/1_baseline.sql:
--------------------------------------------------------------------------------
1 | -- create "baseline" table
2 | CREATE TABLE baseline (`c` int NOT NULL);
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/baseline2/20220318104614_initial.sql:
--------------------------------------------------------------------------------
1 | -- create "tbl" table
2 | CREATE TABLE tbl (`col` int NOT NULL);
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/baseline2/20220318104615_second.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `tbl` ADD `col_2` bigint;
2 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/baseline2/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:sxNQqhuqhm1fLpr3WN9N/M/niaS81Y7k5RrSaKpmBZE=
2 | 1_baseline.sql h1:rZgkRmNcN2UEKgxru1nHCpBRVn/fjFavyQ4xxPxhrD4=
3 | 20220318104614_initial.sql h1:/B1/+IxzgrRc4tCm1tpcpMhocHgqkdWF+iffxuguYaQ=
4 | 20220318104615_second.sql h1:nUc1cUvm8BzjTZdbavM1IRlNpfhtyY3YyZJ8v23K9j4=
5 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/dbmate/1_initial.sql:
--------------------------------------------------------------------------------
1 | -- migrate:up
2 | CREATE TABLE post
3 | (
4 | id int NOT NULL,
5 | title text,
6 | body text,
7 | PRIMARY KEY (id)
8 | );
9 |
10 | /*
11 | Multiline comment ...
12 | */
13 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
14 |
15 | -- Normal comment
16 | -- With a second line
17 | INSERT INTO post (title) VALUES (
18 | 'This is
19 | my multiline
20 |
21 | value');
22 |
23 | -- migrate:down
24 |
25 |
26 | DROP TABLE post;
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/dbmate/2_second_migration.sql:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -- migrate:up
5 |
6 |
7 |
8 |
9 | CREATE TABLE tbl_2 (col INT);
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/dbmate_gold/1_initial.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE post
2 | (
3 | id int NOT NULL,
4 | title text,
5 | body text,
6 | PRIMARY KEY (id)
7 | );
8 | /*
9 | Multiline comment ...
10 | */
11 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
12 | -- Normal comment
13 | -- With a second line
14 | INSERT INTO post (title) VALUES (
15 | 'This is
16 | my multiline
17 |
18 | value');
19 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/dbmate_gold/2_second_migration.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE tbl_2 (col INT);
2 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/flyway/B2__baseline.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE post
2 | (
3 | id int NOT NULL,
4 | title text,
5 | body text,
6 | created_at TIMESTAMP NOT NULL
7 | PRIMARY KEY (id)
8 | );
9 |
10 | INSERT INTO post (title, created_at) VALUES (
11 | 'This is
12 | my multiline
13 |
14 | value', NOW());
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/flyway/R__views.sql:
--------------------------------------------------------------------------------
1 | CREATE VIEW `my_view` AS SELECT * FROM `post`;
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/flyway/U1__initial.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE tbl;
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/flyway/V1__initial.sql:
--------------------------------------------------------------------------------
1 | -- comment
2 | CREATE TABLE post
3 | (
4 | id int NOT NULL,
5 | title text,
6 | body text,
7 | PRIMARY KEY (id)
8 | );
9 |
10 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
11 |
12 | INSERT INTO post (title, created_at) VALUES (
13 | 'This is
14 | my multiline
15 |
16 | value', NOW());
17 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/flyway/V2__second_migration.sql:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -- migrate:up
5 |
6 |
7 |
8 |
9 | CREATE TABLE tbl_2 (col INT);
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/flyway/V3__third_migration.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE tbl_2 ADD col_1 INTEGER NOT NULL;
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/flyway_gold/2_baseline.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE post
2 | (
3 | id int NOT NULL,
4 | title text,
5 | body text,
6 | created_at TIMESTAMP NOT NULL
7 | PRIMARY KEY (id)
8 | );
9 | INSERT INTO post (title, created_at) VALUES (
10 | 'This is
11 | my multiline
12 |
13 | value', NOW());
14 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/flyway_gold/3R_views.sql:
--------------------------------------------------------------------------------
1 | CREATE VIEW `my_view` AS SELECT * FROM `post`;
2 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/flyway_gold/3_third_migration.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE tbl_2 ADD col_1 INTEGER NOT NULL;
2 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/golang-migrate/1_initial.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE tbl;
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/golang-migrate/1_initial.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE tbl
2 | (
3 | col INT
4 | );
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/golang-migrate/2_second_migration.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE tbl_2;
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/golang-migrate/2_second_migration.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE tbl_2 (col INT);
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/golang-migrate_gold/1_initial.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE tbl
2 | (
3 | col INT
4 | );
5 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/golang-migrate_gold/2_second_migration.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE tbl_2 (col INT);
2 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/goose/1_initial.sql:
--------------------------------------------------------------------------------
1 | -- +goose Up
2 | CREATE TABLE post
3 | (
4 | id int NOT NULL,
5 | title text,
6 | body text,
7 | PRIMARY KEY (id)
8 | );
9 |
10 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
11 |
12 | INSERT INTO post (title) VALUES (
13 | 'This is
14 | my multiline
15 |
16 | value');
17 |
18 | -- +goose Down
19 | DROP TABLE post;
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/goose/2_second_migration.sql:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -- +goose Up
5 |
6 |
7 | ALTER TABLE post ADD updated_at TIMESTAMP NOT NULL;
8 |
9 | -- +goose StatementBegin
10 | -- Comment for the function declaration.
11 | CREATE
12 | OR REPLACE FUNCTION histories_partition_creation( DATE, DATE )
13 | returns void AS $$
14 | DECLARE
15 | create_query text;
16 | BEGIN
17 | FOR create_query IN
18 | SELECT 'CREATE TABLE IF NOT EXISTS histories_'
19 | || TO_CHAR(d, 'YYYY_MM')
20 | || ' ( CHECK( created_at >= timestamp '''
21 | || TO_CHAR(d, 'YYYY-MM-DD 00:00:00')
22 | || ''' AND created_at < timestamp '''
23 | || TO_CHAR(d + INTERVAL '1 month', 'YYYY-MM-DD 00:00:00')
24 | || ''' ) ) inherits ( histories );'
25 | FROM generate_series($1, $2, '1 month') AS d LOOP
26 | EXECUTE create_query;
27 | END LOOP; -- LOOP END
28 | END; -- FUNCTION END
29 | $$
30 | language plpgsql;
31 | -- +goose StatementEnd
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/goose_gold/1_initial.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE post
2 | (
3 | id int NOT NULL,
4 | title text,
5 | body text,
6 | PRIMARY KEY (id)
7 | );
8 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
9 | INSERT INTO post (title) VALUES (
10 | 'This is
11 | my multiline
12 |
13 | value');
14 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/goose_gold/2_second_migration.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE post ADD updated_at TIMESTAMP NOT NULL;
2 | -- Comment for the function declaration.
3 | CREATE
4 | OR REPLACE FUNCTION histories_partition_creation( DATE, DATE )
5 | returns void AS $$
6 | DECLARE
7 | create_query text;
8 | BEGIN
9 | FOR create_query IN
10 | SELECT 'CREATE TABLE IF NOT EXISTS histories_'
11 | || TO_CHAR(d, 'YYYY_MM')
12 | || ' ( CHECK( created_at >= timestamp '''
13 | || TO_CHAR(d, 'YYYY-MM-DD 00:00:00')
14 | || ''' AND created_at < timestamp '''
15 | || TO_CHAR(d + INTERVAL '1 month', 'YYYY-MM-DD 00:00:00')
16 | || ''' ) ) inherits ( histories );'
17 | FROM generate_series($1, $2, '1 month') AS d LOOP
18 | EXECUTE create_query;
19 | END LOOP; -- LOOP END
20 | END; -- FUNCTION END
21 | $$
22 | language plpgsql;
23 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/liquibase/1_initial.sql:
--------------------------------------------------------------------------------
1 | --liquibase formatted sql
2 |
3 | --changeset atlas:1-1
4 | CREATE TABLE post
5 | (
6 | id int NOT NULL,
7 | title text,
8 | body text,
9 | PRIMARY KEY (id)
10 | );
11 | --rollback: DROP TABLE post;
12 |
13 | --changeset atlas:1-2
14 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
15 | --rollback: ALTER TABLE post DROP created_at;
16 |
17 | --changeset atlas:1-3
18 | INSERT INTO post (title) VALUES (
19 | 'This is
20 | my multiline
21 |
22 | value');
23 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/liquibase/2_second_migration.sql:
--------------------------------------------------------------------------------
1 | --liquibase formatted sql
2 |
3 | --changeset atlas:2-1
4 | CREATE TABLE tbl_2 (col INT);
5 | --rollback DROP TABLE tbl_2;
6 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/liquibase_gold/1_initial.sql:
--------------------------------------------------------------------------------
1 | --changeset atlas:1-1
2 | CREATE TABLE post
3 | (
4 | id int NOT NULL,
5 | title text,
6 | body text,
7 | PRIMARY KEY (id)
8 | );
9 | --changeset atlas:1-2
10 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
11 | --changeset atlas:1-3
12 | INSERT INTO post (title) VALUES (
13 | 'This is
14 | my multiline
15 |
16 | value');
17 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/import/liquibase_gold/2_second_migration.sql:
--------------------------------------------------------------------------------
1 | --changeset atlas:2-1
2 | CREATE TABLE tbl_2 (col INT);
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/mysql/20220318104614_initial.sql:
--------------------------------------------------------------------------------
1 | -- add new schema named "atlantis"
2 | CREATE DATABASE `atlantis`;
3 | -- create "tbl" table
4 | CREATE TABLE `atlantis`.`tbl` (`col` int NOT NULL) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
5 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/mysql/20220420213403_second.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `atlantis`.`tbl` ADD `col_2` TEXT;
2 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/mysql/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:EGX5/CEEerpLWqYQNHB1veTXon8t05wEGJiX2fOtFXg=
2 | 20220318104614_initial.sql h1:EoDHPlX7fTGn5qiCdR5xhwFh+DrOi3cQ7Y49BsIy97k=
3 | 20220420213403_second.sql h1:cAioQjDgJkOIiMAyEwqaurPs0EHpTeu0CnWlJzNj5SE=
4 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlite/20220318104614_initial.sql:
--------------------------------------------------------------------------------
1 | -- create "tbl" table
2 | CREATE TABLE tbl (`col` int NOT NULL);
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlite/20220318104615_second.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `tbl` ADD `col_2` bigint;
2 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlite/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:GMi7mvWSIHv0I/Wrc2NCGVt9Z5hWZbPa6wL986t7Z2o=
2 | 20220318104614_initial.sql h1:FifWjY2X0g2YVnb18Qm+QBPvoldDOOob7bS0LrFuCXc=
3 | 20220318104615_second.sql h1:wbPDlODOQeixCiopAhlT7W4xOO9TgJxzjYjxf4TA2f4=
4 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlite2/20220318104614_initial.sql:
--------------------------------------------------------------------------------
1 | -- create "tbl" table
2 | CREATE TABLE tbl (`col` int NOT NULL);
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlite2/20220318104615_second.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `tbl` ADD `col_2` bigint;
2 | asdasd ALTER TABLE `tbl` ADD `col_3` bigint; -- will fail
3 | ALTER TABLE `tbl` ADD `col_4` bigint;
4 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlite2/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:lXdG49p5Vr5b9eARNKq3Gkgd+flbQXDM+XDyB6b2nzw=
2 | 20220318104614_initial.sql h1:FifWjY2X0g2YVnb18Qm+QBPvoldDOOob7bS0LrFuCXc=
3 | 20220318104615_second.sql h1:UA1TOODS2yU138E2HBlChe/O8vSmTRxkHs4OJOUK3K8=
4 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx/20220925092817_initial.sql:
--------------------------------------------------------------------------------
1 | -- create "users" table
2 | CREATE TABLE `users` (`id` integer NOT NULL, `name` text NULL, PRIMARY KEY (`id`));
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx/20220925094021_second.sql:
--------------------------------------------------------------------------------
1 | -- create "friendships" table
2 | CREATE TABLE `friendships` (`user_id` integer NOT NULL, `friend_id` integer NOT NULL, PRIMARY KEY (`user_id`, `friend_id`), CONSTRAINT `user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, CONSTRAINT `friend_id_fk` FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`) ON DELETE CASCADE);
3 |
4 | INSERT INTO `users` (`id`) VALUES (1), (2);
5 | INSERT INTO `friendships` (`user_id`, `friend_id`) VALUES (1,2), (2,1);
6 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx/20220925094437_third.sql:
--------------------------------------------------------------------------------
1 | -- disable the enforcement of foreign-keys constraints
2 | PRAGMA foreign_keys = off;
3 | -- create "new_users" table
4 | CREATE TABLE `new_users` (`id` integer NOT NULL, PRIMARY KEY (`id`));
5 | -- copy rows from old table "users" to new temporary table "new_users"
6 | INSERT INTO `new_users` (`id`) SELECT `id` FROM `users`;
7 | -- drop "users" table after copying rows
8 | DROP TABLE `users`;
9 | -- rename temporary table "new_users" to "users"
10 | ALTER TABLE `new_users` RENAME TO `users`;
11 | -- enable back the enforcement of foreign-keys constraints
12 | PRAGMA foreign_keys = on;
13 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:09lkmQGTxdoqPwK0ZXtU4+KHipufkVp1Jlje3t6Opy4=
2 | 20220925092817_initial.sql h1:ZGeLdeqNUMXqJm+hPkhBrhzbtUzSBH8yVTsnSnJo/qU=
3 | 20220925094021_second.sql h1:vcoquz3yk+TlTPiQgW5hHpS/abIvySCM/bzgwYTDoqY=
4 | 20220925094437_third.sql h1:2pbBiUBKsEC5+ppfPPTDr+iwJSgZ2rM4qmHI44/vmnc=
5 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx2/20220925092817_initial.sql:
--------------------------------------------------------------------------------
1 | -- create "users" table
2 | CREATE TABLE `users` (`id` integer NOT NULL, `name` text NULL, PRIMARY KEY (`id`));
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx2/20220925094021_second.sql:
--------------------------------------------------------------------------------
1 | -- create "friendships" table
2 | CREATE TABLE `friendships` (`user_id` integer NOT NULL, `friend_id` integer NOT NULL, PRIMARY KEY (`user_id`, `friend_id`), CONSTRAINT `user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, CONSTRAINT `friend_id_fk` FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`) ON DELETE CASCADE);
3 |
4 | INSERT INTO `users` (`id`) VALUES (1), (2);
5 | INSERT INTO `friendships` (`user_id`, `friend_id`) VALUES (1,2), (2,1);
6 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx2/20220925094437_third.sql:
--------------------------------------------------------------------------------
1 | -- disable the enforcement of foreign-keys constraints
2 | PRAGMA foreign_keys = off;
3 | -- create "new_users" table
4 | CREATE TABLE `new_users` (`id` integer NOT NULL, PRIMARY KEY (`id`));
5 | -- copy rows from old table "users" to new temporary table "new_users"
6 | INSERT INTO `new_users` (`id`) SELECT `id` FROM `users`;
7 | -- drop "users" table after copying rows
8 | DROP TABLE `users`;
9 | -- rename temporary table "new_users" to "users"
10 | ALTER TABLE `new_users` RENAME TO `users`;
11 | -- insert faulty data
12 | INSERT INTO `friendships` (`user_id`, `friend_id`) VALUES (3,2);
13 | -- enable back the enforcement of foreign-keys constraints
14 | PRAGMA foreign_keys = on;
15 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx2/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:eH+7c2mVWbrhky00/3SKYklyHLyz+QzDk1UZJ9+ZJsg=
2 | 20220925092817_initial.sql h1:ZGeLdeqNUMXqJm+hPkhBrhzbtUzSBH8yVTsnSnJo/qU=
3 | 20220925094021_second.sql h1:vcoquz3yk+TlTPiQgW5hHpS/abIvySCM/bzgwYTDoqY=
4 | 20220925094437_third.sql h1:58glD96PVBa0fSu8x/3Gbwbf7N6WjAcVl4jh/XcNXoM=
5 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx3/20220925092817_initial.sql:
--------------------------------------------------------------------------------
1 | -- create "users" table
2 | CREATE TABLE `users` (`id` integer NOT NULL, `name` text NULL, PRIMARY KEY (`id`));
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx3/20220925094021_second.sql:
--------------------------------------------------------------------------------
1 | -- atlas:txmode none
2 |
3 | -- Create a table.
4 | CREATE TABLE t1 (a INTEGER PRIMARY KEY);
5 |
6 | -- Cause migrations to fail.
7 | INSERT INTO t1 VALUES (1), (1);
8 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx3/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:tTdOsRIKj8kX3o4eUQpw6znQsGVorkUrxi2o3C/ELL4=
2 | 20220925092817_initial.sql h1:ZGeLdeqNUMXqJm+hPkhBrhzbtUzSBH8yVTsnSnJo/qU=
3 | 20220925094021_second.sql h1:RTw52JCxOkWfSnY1N/kRZeLkmAFmvY2BXfZKDzhV3QM=
4 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx4/20220925092817_initial.sql:
--------------------------------------------------------------------------------
1 | -- create "users" table
2 | CREATE TABLE `users` (`id` integer NOT NULL, `name` text NULL, PRIMARY KEY (`id`));
3 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx4/20220925094021_second.sql:
--------------------------------------------------------------------------------
1 | -- atlas:txmode unknown
2 |
3 | -- Create a table.
4 | CREATE TABLE t1 (a INTEGER PRIMARY KEY);
5 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/sqlitetx4/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:RO76A3Kj66lD13e+iIb5lafWPtz4S3ypswaBm5kPRrI=
2 | 20220925092817_initial.sql h1:ZGeLdeqNUMXqJm+hPkhBrhzbtUzSBH8yVTsnSnJo/qU=
3 | 20220925094021_second.sql h1:MH4JwNo3hLxH0rauBusXr3IvJJFm9EC2TPe0DhXbgkE=
4 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/templatedir/1.sql:
--------------------------------------------------------------------------------
1 | {{- if eq .Env "dev" }}
2 | create table dev1 (c text);
3 | {{- else }}
4 | create table prod1 (c text);
5 | {{- end }}
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/templatedir/2.sql:
--------------------------------------------------------------------------------
1 | {{- if eq .Env "dev" }}
2 | create table dev2 (c text);
3 | {{ template "shared/users" "dev2" }}
4 | {{- else }}
5 | create table prod2 (c text);
6 | {{ template "shared/users" "prod2" }}
7 | {{- end }}
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/templatedir/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:qhwlEKNEXRVSUiyBXmbiSiS26un12DoxHCR3WDzrDdA=
2 | 1.sql h1:b/5P45x6+CVoyVbBJ/BVc5Z2cI46XfoW92QH3T1kqxY=
3 | 2.sql h1:El2EOcXWK2PfPV6yJg4hBVtc4aHheV/MFEPjho9SEmQ=
4 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/testdata/templatedir/shared/users.sql:
--------------------------------------------------------------------------------
1 | {{- define "shared/users" }}
2 | create table users_{{ $ }} (c text);
3 | {{- end}}
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/vercheck/notification.tmpl:
--------------------------------------------------------------------------------
1 | {{- with .Advisory -}}
2 | SECURITY ADVISORY
3 | {{ .Text }}
4 | {{- end }}
5 | {{- with .Latest -}}
6 | A new version of Atlas is available ({{ .Version }}){{ with .Link }}: {{ . }}
7 | {{ end }}
8 | {{- with .Summary }}
9 | {{ . }}
10 | {{- end }}
11 | {{- end }}
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/vercheck/req_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package vercheck
8 |
9 | import (
10 | "context"
11 | "net/http"
12 |
13 | "ariga.io/atlas/cmd/atlas/internal/cloudapi"
14 | )
15 |
16 | func addHeaders(_ context.Context, req *http.Request) {
17 | req.Header.Set("User-Agent", cloudapi.UserAgent())
18 | }
19 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdapi/version_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent && !official
6 |
7 | package cmdapi
8 |
9 | const (
10 | versionFmt = "atlas unofficial "
11 | versionInfo = "To download an official version, visit: https://atlasgo.io/getting-started#installation\n"
12 | )
13 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdlog/cmdlog_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package cmdlog
8 |
9 | import (
10 | "context"
11 |
12 | "ariga.io/atlas/sql/migrate"
13 | )
14 |
15 | // SchemaApply contains a summary of a 'schema apply' execution on a database.
16 | type SchemaApply struct {
17 | ctx context.Context `json:"-"`
18 | Env
19 | Changes Changes `json:"Changes,omitempty"`
20 | // General error that occurred during execution.
21 | // e.g., when committing or rolling back a transaction.
22 | Error string `json:"Error,omitempty"`
23 | }
24 |
25 | // NewSchemaApply returns a SchemaApply.
26 | func NewSchemaApply(ctx context.Context, env Env, applied, pending []*migrate.Change, err *StmtError) *SchemaApply {
27 | return &SchemaApply{
28 | ctx: ctx,
29 | Env: env,
30 | Changes: Changes{
31 | Applied: applied,
32 | Pending: pending,
33 | Error: err,
34 | },
35 | }
36 | }
37 |
38 | // NewSchemaPlan returns a SchemaApply only with pending changes.
39 | func NewSchemaPlan(ctx context.Context, env Env, pending []*migrate.Change, err *StmtError) *SchemaApply {
40 | return NewSchemaApply(ctx, env, nil, pending, err)
41 | }
42 |
43 | func (*MigrateApply) MaskedText(s *migrate.Stmt) string {
44 | return s.Text // Unsupported feature.
45 | }
46 |
47 | // MaskedErrorText returns the masked versioned of the error, if caused by a statement.
48 | func (*MigrateApply) MaskedErrorText(e migrate.LogError) string {
49 | return e.Error.Error() // Unsupported feature.
50 | }
51 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/cmdstate/cmdstate_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | package cmdstate_test
6 |
7 | import (
8 | "os"
9 | "path/filepath"
10 | "testing"
11 |
12 | "ariga.io/atlas/cmd/atlas/internal/cmdstate"
13 |
14 | "github.com/mitchellh/go-homedir"
15 | "github.com/stretchr/testify/require"
16 | )
17 |
18 | func TestFile(t *testing.T) {
19 | homedir.DisableCache = true
20 | t.Cleanup(func() { homedir.DisableCache = false })
21 |
22 | type T struct{ V string }
23 | f := cmdstate.File[T]{Name: "test", Dir: t.TempDir()}
24 | v, err := f.Read()
25 | require.NoError(t, err)
26 | require.Equal(t, T{}, v)
27 | require.NoError(t, f.Write(T{V: "v"}))
28 | v, err = f.Read()
29 | require.NoError(t, err)
30 | require.Equal(t, T{V: "v"}, v)
31 |
32 | home := t.TempDir()
33 | t.Setenv("HOME", home)
34 | f = cmdstate.File[T]{Name: "t"}
35 | _, err = f.Read()
36 | require.NoError(t, err)
37 | dirs, err := os.ReadDir(home)
38 | require.NoError(t, err)
39 | require.Empty(t, dirs)
40 |
41 | require.NoError(t, f.Write(T{V: "v"}))
42 | dirs, err = os.ReadDir(home)
43 | require.NoError(t, err)
44 | require.Len(t, dirs, 1)
45 | require.Equal(t, ".atlas", dirs[0].Name())
46 | dirs, err = os.ReadDir(filepath.Join(home, ".atlas"))
47 | require.NoError(t, err)
48 | require.Len(t, dirs, 1)
49 | require.Equal(t, "t.json", dirs[0].Name())
50 | v, err = f.Read()
51 | require.NoError(t, err)
52 | require.Equal(t, T{V: "v"}, v)
53 | }
54 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/convert.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | // Code generated by entc, DO NOT EDIT.
6 |
7 | package ent
8 |
9 | import "ariga.io/atlas/sql/migrate"
10 |
11 | // SetRevision takes the values for each field from the given migrate.Revision.
12 | func (rc *RevisionCreate) SetRevision(rev *migrate.Revision) *RevisionCreate {
13 | rc.SetID(rev.Version)
14 | rc.SetDescription(rev.Description)
15 | rc.SetType(rev.Type)
16 | rc.SetApplied(rev.Applied)
17 | rc.SetTotal(rev.Total)
18 | rc.SetExecutedAt(rev.ExecutedAt)
19 | rc.SetExecutionTime(rev.ExecutionTime)
20 | rc.SetError(rev.Error)
21 | rc.SetErrorStmt(rev.ErrorStmt)
22 | rc.SetHash(rev.Hash)
23 | rc.SetPartialHashes(rev.PartialHashes)
24 | rc.SetOperatorVersion(rev.OperatorVersion)
25 | return rc
26 | }
27 |
28 | // AtlasRevision returns an migrate.Revision from the current Revision.
29 | func (_m *Revision) AtlasRevision() *migrate.Revision {
30 | return &migrate.Revision{
31 | Version: _m.ID,
32 | Description: _m.Description,
33 | Type: _m.Type,
34 | Applied: _m.Applied,
35 | Total: _m.Total,
36 | ExecutedAt: _m.ExecutedAt,
37 | ExecutionTime: _m.ExecutionTime,
38 | Error: _m.Error,
39 | ErrorStmt: _m.ErrorStmt,
40 | Hash: _m.Hash,
41 | PartialHashes: _m.PartialHashes,
42 | OperatorVersion: _m.OperatorVersion,
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/entc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build ignore
6 |
7 | package main
8 |
9 | import (
10 | "log"
11 |
12 | "entgo.io/ent/entc"
13 | "entgo.io/ent/entc/gen"
14 | )
15 |
16 | func main() {
17 | err := entc.Generate("./schema", &gen.Config{
18 | Header: `// Copyright 2021-present The Atlas Authors. All rights reserved.
19 | // This source code is licensed under the Apache 2.0 license found
20 | // in the LICENSE file in the root directory of this source tree.
21 |
22 | // Code generated by entc, DO NOT EDIT.
23 | `,
24 | Features: []gen.Feature{
25 | gen.FeatureUpsert,
26 | gen.FeatureExecQuery,
27 | gen.FeatureSchemaConfig,
28 | },
29 | }, entc.TemplateDir("template"))
30 | if err != nil {
31 | log.Fatalf("running ent codegen: %v", err)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/generate.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | package ent
6 |
7 | //go:generate go run -mod=mod entc.go
8 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/internal/schemaconfig.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | // Code generated by entc, DO NOT EDIT.
6 |
7 | package internal
8 |
9 | import "context"
10 |
11 | // SchemaConfig represents alternative schema names for all tables
12 | // that can be passed at runtime.
13 | type SchemaConfig struct {
14 | Revision string // Revision table.
15 | }
16 |
17 | type schemaCtxKey struct{}
18 |
19 | // SchemaConfigFromContext returns a SchemaConfig stored inside a context, or empty if there isn't one.
20 | func SchemaConfigFromContext(ctx context.Context) SchemaConfig {
21 | config, _ := ctx.Value(schemaCtxKey{}).(SchemaConfig)
22 | return config
23 | }
24 |
25 | // NewSchemaConfigContext returns a new context with the given SchemaConfig attached.
26 | func NewSchemaConfigContext(parent context.Context, config SchemaConfig) context.Context {
27 | return context.WithValue(parent, schemaCtxKey{}, config)
28 | }
29 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/migrate/schema.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | // Code generated by entc, DO NOT EDIT.
6 |
7 | package migrate
8 |
9 | import (
10 | "entgo.io/ent/dialect/entsql"
11 | "entgo.io/ent/dialect/sql/schema"
12 | "entgo.io/ent/schema/field"
13 | )
14 |
15 | var (
16 | // AtlasSchemaRevisionsColumns holds the columns for the "atlas_schema_revisions" table.
17 | AtlasSchemaRevisionsColumns = []*schema.Column{
18 | {Name: "version", Type: field.TypeString},
19 | {Name: "description", Type: field.TypeString},
20 | {Name: "type", Type: field.TypeUint, Default: 2},
21 | {Name: "applied", Type: field.TypeInt, Default: 0},
22 | {Name: "total", Type: field.TypeInt, Default: 0},
23 | {Name: "executed_at", Type: field.TypeTime},
24 | {Name: "execution_time", Type: field.TypeInt64},
25 | {Name: "error", Type: field.TypeString, Nullable: true, Size: 2147483647},
26 | {Name: "error_stmt", Type: field.TypeString, Nullable: true, Size: 2147483647},
27 | {Name: "hash", Type: field.TypeString},
28 | {Name: "partial_hashes", Type: field.TypeJSON, Nullable: true},
29 | {Name: "operator_version", Type: field.TypeString},
30 | }
31 | // AtlasSchemaRevisionsTable holds the schema information for the "atlas_schema_revisions" table.
32 | AtlasSchemaRevisionsTable = &schema.Table{
33 | Name: "atlas_schema_revisions",
34 | Columns: AtlasSchemaRevisionsColumns,
35 | PrimaryKey: []*schema.Column{AtlasSchemaRevisionsColumns[0]},
36 | }
37 | // Tables holds all the tables in the schema.
38 | Tables = []*schema.Table{
39 | AtlasSchemaRevisionsTable,
40 | }
41 | )
42 |
43 | func init() {
44 | AtlasSchemaRevisionsTable.Annotation = &entsql.Annotation{
45 | Table: "atlas_schema_revisions",
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/predicate/predicate.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | // Code generated by entc, DO NOT EDIT.
6 |
7 | package predicate
8 |
9 | import (
10 | "entgo.io/ent/dialect/sql"
11 | )
12 |
13 | // Revision is the predicate function for revision builders.
14 | type Revision func(*sql.Selector)
15 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/runtime.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | // Code generated by entc, DO NOT EDIT.
6 |
7 | package ent
8 |
9 | import (
10 | "ariga.io/atlas/cmd/atlas/internal/migrate/ent/revision"
11 | "ariga.io/atlas/cmd/atlas/internal/migrate/ent/schema"
12 | "ariga.io/atlas/sql/migrate"
13 | )
14 |
15 | // The init function reads all schema descriptors with runtime code
16 | // (default values, validators, hooks and policies) and stitches it
17 | // to their package variables.
18 | func init() {
19 | revisionFields := schema.Revision{}.Fields()
20 | _ = revisionFields
21 | // revisionDescType is the schema descriptor for type field.
22 | revisionDescType := revisionFields[2].Descriptor()
23 | // revision.DefaultType holds the default value on creation for the type field.
24 | revision.DefaultType = migrate.RevisionType(revisionDescType.Default.(uint))
25 | // revisionDescApplied is the schema descriptor for applied field.
26 | revisionDescApplied := revisionFields[3].Descriptor()
27 | // revision.DefaultApplied holds the default value on creation for the applied field.
28 | revision.DefaultApplied = revisionDescApplied.Default.(int)
29 | // revision.AppliedValidator is a validator for the "applied" field. It is called by the builders before save.
30 | revision.AppliedValidator = revisionDescApplied.Validators[0].(func(int) error)
31 | // revisionDescTotal is the schema descriptor for total field.
32 | revisionDescTotal := revisionFields[4].Descriptor()
33 | // revision.DefaultTotal holds the default value on creation for the total field.
34 | revision.DefaultTotal = revisionDescTotal.Default.(int)
35 | // revision.TotalValidator is a validator for the "total" field. It is called by the builders before save.
36 | revision.TotalValidator = revisionDescTotal.Validators[0].(func(int) error)
37 | }
38 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/runtime/runtime.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | // Code generated by entc, DO NOT EDIT.
6 |
7 | package runtime
8 |
9 | // The schema-stitching logic is generated in ariga.io/atlas/cmd/atlas/internal/migrate/ent/runtime.go
10 |
11 | const (
12 | Version = "v0.14.5-0.20250523082027-21ecfa0872d4" // Version of ent codegen.
13 | Sum = "h1:d7UZAvQCnOp1PyiHAWkPCXBEPW3tVjraiK/RZlsW0XY=" // Sum of ent codegen.
14 | )
15 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/schema/revision.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | package schema
6 |
7 | import (
8 | "time"
9 |
10 | "ariga.io/atlas/sql/migrate"
11 |
12 | "entgo.io/ent"
13 | "entgo.io/ent/dialect/entsql"
14 | "entgo.io/ent/schema"
15 | "entgo.io/ent/schema/field"
16 | )
17 |
18 | // DefaultRevisionSchema is the default schema for storing revisions table.
19 | const DefaultRevisionSchema = "atlas_schema_revisions"
20 |
21 | // Revision holds the schema definition for the Revision entity.
22 | type Revision struct {
23 | ent.Schema
24 | }
25 |
26 | // Fields of the Revision.
27 | func (Revision) Fields() []ent.Field {
28 | return []ent.Field{
29 | field.String("id").
30 | StorageKey("version").
31 | Immutable(),
32 | field.String("description").
33 | Immutable(),
34 | field.Uint("type").
35 | GoType(migrate.RevisionType(0)).
36 | Default(uint(migrate.RevisionTypeExecute)),
37 | field.Int("applied").
38 | NonNegative().
39 | Default(0),
40 | field.Int("total").
41 | NonNegative().
42 | Default(0),
43 | field.Time("executed_at").
44 | Immutable(),
45 | field.Int64("execution_time").
46 | GoType(time.Duration(0)),
47 | field.Text("error").
48 | Optional(),
49 | field.Text("error_stmt").
50 | Optional(),
51 | field.String("hash"),
52 | field.Strings("partial_hashes").
53 | Optional(),
54 | field.String("operator_version"),
55 | }
56 | }
57 |
58 | // Annotations of the Revision.
59 | func (Revision) Annotations() []schema.Annotation {
60 | return []schema.Annotation{
61 | entsql.Annotation{Table: DefaultRevisionSchema},
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/ent/template/convert.tmpl:
--------------------------------------------------------------------------------
1 | {{/* gotype: entgo.io/ent/entc/gen.Graph */}}
2 |
3 | {{ define "convert" }}
4 |
5 | {{ $pkg := base $.Config.Package }}
6 | {{ template "header" $ }}
7 |
8 | import "ariga.io/atlas/sql/migrate"
9 |
10 | {{ range $n := $.Nodes }}
11 | {{ if eq $n.Name "Revision" }}
12 | {{ $builder := $n.CreateName }}
13 | {{ $receiver := receiver $builder }}
14 |
15 | // SetRevision takes the values for each field from the given migrate.Revision.
16 | func ({{ $receiver }} *{{ $builder }}) SetRevision(rev *migrate.Revision) *{{ $builder }} {
17 | {{ $receiver }}.SetID(rev.Version)
18 | {{- range $f := $n.Fields }}
19 | {{ $receiver }}.Set{{ $f.StructField }}(rev.{{ $f.StructField }})
20 | {{- end }}
21 | return {{ $receiver }}
22 | }
23 |
24 | // AtlasRevision returns an migrate.Revision from the current Revision.
25 | func({{ $n.Receiver }} *Revision) AtlasRevision() *migrate.Revision {
26 | return &migrate.Revision{
27 | Version: {{ $n.Receiver }}.ID,
28 | {{- range $f := $n.Fields }}
29 | {{ $f.StructField }}: {{ $n.Receiver }}.{{ $f.StructField }},
30 | {{- end }}
31 | }
32 | }
33 | {{ end }}
34 | {{ end }}
35 |
36 | {{ end }}
37 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/migrate_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package migrate
8 |
9 | import (
10 | "context"
11 | "fmt"
12 | "net/url"
13 |
14 | "ariga.io/atlas/sql/migrate"
15 | )
16 |
17 | func openAtlasDir(context.Context, *url.URL) (migrate.Dir, error) {
18 | return nil, fmt.Errorf("atlas remote directory is not supported by this release. See: https://atlasgo.io/getting-started")
19 | }
20 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/testdata/broken/1.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `users` (`id` int NOT NULL PRIMARY KEY);
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/testdata/broken/2.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `users` ADD COLUMN `happy` boolean NOT NULL DEFAULT true;
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/testdata/broken/3.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `pets` (`id` int NOT NULL PRIMARY KEY);
2 | THIS LINE ADDS A SYNTAX ERROR;
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/testdata/broken/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:0YTkvowN+aAuYuJY5ZANPAq6QAZ0wAXunU9sUXsuZcI=
2 | 1.sql h1:twN+zPVp8JzWEUcPPfNIT6/62Wa08dfxxZhT4gZxBzg=
3 | 2.sql h1:KHLlrSPwSjbp4+KrpQHwYZf8zlSIiAR7MS3H2yd1yeE=
4 | 3.sql h1:iTKab5MEzWsTdVVDkCUWmateRs9XRNpal/cxqlCYsmQ=
5 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/testdata/fixed/1.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `users` (`id` int NOT NULL PRIMARY KEY);
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/testdata/fixed/2.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `users` ADD COLUMN `happy` boolean NOT NULL DEFAULT true;
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/testdata/fixed/3.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `pets` (`id` int NOT NULL PRIMARY KEY);
2 | ALTER TABLE `pets` ADD COLUMN `happy` boolean NULL;
--------------------------------------------------------------------------------
/cmd/atlas/internal/migrate/testdata/fixed/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:oNV0f9HzMMCf2pzF+sA6CmsSHGjdkWYmcTjoc/lWxLs=
2 | 1.sql h1:twN+zPVp8JzWEUcPPfNIT6/62Wa08dfxxZhT4gZxBzg=
3 | 2.sql h1:KHLlrSPwSjbp4+KrpQHwYZf8zlSIiAR7MS3H2yd1yeE=
4 | 3.sql h1:osHrPgu8uNgd6j09XCiyBQWWEh9aAmwjRgzdZZgm68M=
5 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/sqlparse/myparse/myparse_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package myparse
8 |
9 | import (
10 | "errors"
11 |
12 | "ariga.io/atlas/sql/migrate"
13 | "ariga.io/atlas/sql/schema"
14 | )
15 |
16 | // Parser for fixing linting changes.
17 | type FileParser struct{}
18 |
19 | // FixChange fixes the changes according to the given statement.
20 | func (*FileParser) FixChange(migrate.Driver, string, schema.Changes) (schema.Changes, error) {
21 | return nil, errors.New("unimplemented")
22 | }
23 |
24 | // ColumnFilledBefore checks if the column was filled with values before the given position in the file.
25 | func (*FileParser) ColumnFilledBefore([]*migrate.Stmt, *schema.Table, *schema.Column, int) (bool, error) {
26 | return false, errors.New("unimplemented")
27 | }
28 |
29 | // CreateViewAfter checks if a view was created after the position with the given name to a table.
30 | func (*FileParser) CreateViewAfter([]*migrate.Stmt, string, string, int) (bool, error) {
31 | return false, errors.New("unimplemented")
32 | }
33 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/sqlparse/pgparse/pgparse_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package pgparse
8 |
9 | import (
10 | "errors"
11 |
12 | "ariga.io/atlas/sql/migrate"
13 | "ariga.io/atlas/sql/schema"
14 | )
15 |
16 | type Parser struct{}
17 |
18 | func (*Parser) ColumnFilledBefore([]*migrate.Stmt, *schema.Table, *schema.Column, int) (bool, error) {
19 | return false, errors.New("unimplemented")
20 | }
21 |
22 | func (*Parser) CreateViewAfter([]*migrate.Stmt, string, string, int) (bool, error) {
23 | return false, errors.New("unimplemented")
24 | }
25 |
26 | func (*Parser) FixChange(_ migrate.Driver, _ string, changes schema.Changes) (schema.Changes, error) {
27 | return changes, nil // Unimplemented.
28 | }
29 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/sqlparse/sqliteparse/README.md:
--------------------------------------------------------------------------------
1 | ### SQLite parser based on ANTLR4
2 |
3 | #### Resources
4 |
5 | 1. SQLite syntax: https://www.sqlite.org/syntaxdiagrams.html
6 | 2. Grammar file: https://github.com/antlr/grammars-v4/tree/master/sql/sqlite
7 |
8 | #### Run codegen
9 |
10 | 1. Install `antlr4`: https://github.com/antlr/antlr4/blob/master/doc/getting-started.md#unix
11 | 2. Run:
12 | ```bash
13 | antlr4 -Dlanguage=Go -package sqliteparse -visitor Lexer.g4 Parser.g4 \
14 | && mv _lexer.go lexer.go \
15 | && mv _parser.go parser.go \
16 | && rm *.interp *.tokens
17 | ```
--------------------------------------------------------------------------------
/cmd/atlas/internal/sqlparse/sqliteparse/sqliteparse_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package sqliteparse
8 |
9 | import (
10 | "errors"
11 |
12 | "ariga.io/atlas/sql/migrate"
13 | "ariga.io/atlas/sql/schema"
14 | )
15 |
16 | type FileParser struct{}
17 |
18 | func (*FileParser) ColumnFilledBefore([]*migrate.Stmt, *schema.Table, *schema.Column, int) (bool, error) {
19 | return false, errors.New("unimplemented")
20 | }
21 |
22 | func (*FileParser) CreateViewAfter([]*migrate.Stmt, string, string, int) (bool, error) {
23 | return false, errors.New("unimplemented")
24 | }
25 |
26 | func (*FileParser) FixChange(_ migrate.Driver, _ string, changes schema.Changes) (schema.Changes, error) {
27 | return changes, nil // Unimplemented.
28 | }
29 |
--------------------------------------------------------------------------------
/cmd/atlas/internal/sqlparse/sqlparse.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | package sqlparse
6 |
7 | import (
8 | "sync"
9 |
10 | "ariga.io/atlas/cmd/atlas/internal/sqlparse/myparse"
11 | "ariga.io/atlas/cmd/atlas/internal/sqlparse/pgparse"
12 | "ariga.io/atlas/cmd/atlas/internal/sqlparse/sqliteparse"
13 | "ariga.io/atlas/sql/migrate"
14 | "ariga.io/atlas/sql/mysql"
15 | "ariga.io/atlas/sql/postgres"
16 | "ariga.io/atlas/sql/schema"
17 | "ariga.io/atlas/sql/sqlite"
18 | )
19 |
20 | // A Parser represents an SQL file parser used to fix, search and enrich schema.Changes.
21 | type Parser interface {
22 | // FixChange fixes the changes according to the given statement.
23 | FixChange(d migrate.Driver, stmt string, changes schema.Changes) (schema.Changes, error)
24 |
25 | // ColumnFilledBefore checks if the column was filled with values before the given position
26 | // in the file. For example:
27 | //
28 | // UPDATE
SET =
29 | // UPDATE SET = WHERE IS NULL
30 | //
31 | ColumnFilledBefore([]*migrate.Stmt, *schema.Table, *schema.Column, int) (bool, error)
32 |
33 | // CreateViewAfter checks if a view was created after the position with the given name
34 | // to a table. For example:
35 | //
36 | // ALTER TABLE `users` RENAME TO `Users`
37 | // CREATE VIEW `users` AS SELECT * FROM `Users`
38 | //
39 | CreateViewAfter(stmts []*migrate.Stmt, old, new string, pos int) (bool, error)
40 | }
41 |
42 | // drivers specific fixers.
43 | var drivers sync.Map
44 |
45 | // Register a fixer with the given name.
46 | func Register(name string, f Parser) {
47 | drivers.Store(name, f)
48 | }
49 |
50 | // ParserFor returns a ChangesFixer for the given driver.
51 | func ParserFor(name string) Parser {
52 | f, ok := drivers.Load(name)
53 | if ok {
54 | return f.(Parser)
55 | }
56 | return nil
57 | }
58 |
59 | func init() {
60 | Register(mysql.DriverName, &myparse.FileParser{})
61 | Register(postgres.DriverName, &pgparse.Parser{})
62 | Register(sqlite.DriverName, &sqliteparse.FileParser{})
63 | }
64 |
--------------------------------------------------------------------------------
/cmd/atlas/main_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package main
8 |
9 | import (
10 | "context"
11 | )
12 |
13 | func extendContext(ctx context.Context) (context.Context, error) {
14 | return ctx, nil
15 | }
16 |
17 | func vercheckEndpoint(context.Context) string {
18 | return vercheckURL
19 | }
20 |
21 | // initialize is a no-op for the OSS version.
22 | func initialize(ctx context.Context) (context.Context, func(error)) {
23 | return ctx, func(error) {}
24 | }
25 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module ariga.io/atlas
2 |
3 | go 1.24
4 |
5 | toolchain go1.24.3
6 |
7 | require (
8 | github.com/DATA-DOG/go-sqlmock v1.5.0
9 | github.com/bmatcuk/doublestar v1.3.4
10 | github.com/go-openapi/inflect v0.19.0
11 | github.com/hashicorp/hcl/v2 v2.13.0
12 | github.com/stretchr/testify v1.8.2
13 | github.com/zclconf/go-cty v1.14.4
14 | github.com/zclconf/go-cty-yaml v1.1.0
15 | golang.org/x/mod v0.24.0
16 | gopkg.in/yaml.v3 v3.0.1
17 | )
18 |
19 | require (
20 | github.com/agext/levenshtein v1.2.1 // indirect
21 | github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
22 | github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
23 | github.com/davecgh/go-spew v1.1.1 // indirect
24 | github.com/google/go-cmp v0.6.0 // indirect
25 | github.com/kr/text v0.2.0 // indirect
26 | github.com/kylelemons/godebug v1.1.0 // indirect
27 | github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
28 | github.com/pmezard/go-difflib v1.0.0 // indirect
29 | golang.org/x/text v0.21.0 // indirect
30 | )
31 |
--------------------------------------------------------------------------------
/internal/ci/ci_revisions.tmpl:
--------------------------------------------------------------------------------
1 | # # # # # # # # # # # # # # # #
2 | # CODE GENERATED - DO NOT EDIT
3 | # # # # # # # # # # # # # # # #
4 | name: CI - Revisions{{ with $.Flavor }} - {{ . }} Edition{{ end }}
5 | on:
6 | pull_request:
7 | paths:
8 | - 'cmd/atlas/internal/migrate/ent/**'
9 | push:
10 | branches:
11 | - master
12 | paths:
13 | - 'cmd/atlas/internal/migrate/ent/**'
14 | {{ .Concurrency }}
15 | jobs:
16 | revisions:
17 | runs-on: {{ $.Runner }}
18 | steps:
19 | - uses: actions/checkout@v4
20 | with:
21 | fetch-depth: 0
22 | - uses: actions/setup-go@v5
23 | with:
24 | go-version-file: cmd/atlas/go.mod
25 | {{- with .SharedSteps }}
26 | {{- range . }}
27 | - name: {{ .Name }}
28 | uses: {{ .Action }}
29 | {{- with .With }}
30 | with:
31 | {{- range . }}
32 | {{ . }}{{ end }}
33 | {{- end }}
34 | {{- end }}
35 | {{- end }}
36 | - name: Checkout origin/master
37 | run: git checkout origin/master
38 | - name: Create revisions from master
39 | run: go run {{ with $.Tags }}-tags={{ . }} {{ end }}. migrate apply --dir file://internal/cmdapi/testdata/sqlite --url sqlite://db?_fk=1
40 | working-directory: cmd/atlas
41 | - name: Checkout previous HEAD
42 | run: git checkout -
43 | - name: Migrate revisions table to HEAD
44 | run: go run {{ with $.Tags }}-tags={{ . }} {{ end }}. migrate apply --dir file://internal/cmdapi/testdata/sqlite --url sqlite://db?_fk=1
45 | working-directory: cmd/atlas
--------------------------------------------------------------------------------
/internal/ci/cockroach/Dockerfile.tmpl:
--------------------------------------------------------------------------------
1 | FROM cockroachdb/cockroach:{{ .Version}}
2 |
3 | EXPOSE 8080
4 | EXPOSE 26257
5 |
6 | ENTRYPOINT ["/cockroach/cockroach", "start-single-node", "--insecure"]
--------------------------------------------------------------------------------
/internal/ci/cockroach/main.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | package main
6 |
7 | import (
8 | _ "embed"
9 | "fmt"
10 | "os"
11 | "text/template"
12 | )
13 |
14 | type params struct {
15 | Version string
16 | }
17 |
18 | //go:embed Dockerfile.tmpl
19 | var dockerTmpl string
20 |
21 | func main() {
22 | if len(os.Args) < 2 {
23 | fmt.Println("please supply version as argument e.g. 'v22.1.0'")
24 | os.Exit(1)
25 | }
26 |
27 | p := params{
28 | Version: os.Args[1],
29 | }
30 | t, err := template.New("docker").Parse(dockerTmpl)
31 | if err != nil {
32 | panic(err)
33 | }
34 | err = t.Execute(os.Stdout, p)
35 | if err != nil {
36 | panic(err)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/internal/ci/jobs_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package main
8 |
9 | //go:generate go run . -flavor Community -suffix oss
10 |
11 | func init() {
12 | data.GoVersions = goVersions{"1.22"}
13 | data.GlobalEnv = []struct{ K, V string }{
14 | {K: "ATLAS_NO_UPGRADE_SUGGESTIONS", V: "1"},
15 | }
16 | data.Jobs = append(jobs,
17 | Job{
18 | Version: "tidb5",
19 | Image: "pingcap/tidb:v5.4.0",
20 | Regex: "TiDB",
21 | Ports: []string{"4309:4000"},
22 | },
23 | Job{
24 | Version: "tidb6",
25 | Image: "pingcap/tidb:v6.0.0",
26 | Regex: "TiDB",
27 | Ports: []string{"4310:4000"},
28 | },
29 | Job{
30 | Version: "cockroach",
31 | Image: "ghcr.io/ariga/cockroachdb-single-node:v21.2.11",
32 | Regex: "Cockroach",
33 | Ports: []string{"26257:26257"},
34 | },
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/internal/integration/README.md:
--------------------------------------------------------------------------------
1 | ### This directory contains all integration tests for Atlas.
2 |
3 | The provided `docker-compose.yaml` file contains images for each database the integration tests are run on. You can
4 | start them by calling:
5 |
6 | ```shell
7 | docker-compose --project-name atlas-integration up -d
8 | ```
9 |
10 | The whole integration suite is then run by executing within this directory:
11 |
12 | ```shell
13 | go test ./...
14 | ```
15 |
16 | #### Selectively running tests
17 |
18 | Running all integration tests (and keeping all database containers up all the time) consumes time and resources (and
19 | power). You can execute only some of the tests by using the `-run` and `-dialect` flags:
20 |
21 | The below examples don't require for you to have all docker containers running, instead only the ones used in the tests
22 | have to be up.
23 |
24 | Consider the following test in `mysql_test.go`:
25 |
26 | ```go
27 | func TestMySQL_Executor(t *testing.T) {
28 | myRun(t, func(t *myTest) {
29 | testExecutor(t)
30 | })
31 | }
32 | ```
33 |
34 | If you'd wanted to run that test only for mysql56, simply pass its full name into the `-run` flag:
35 |
36 | ```shell
37 | # Run TestMySQL_Executor for all mysql versions
38 | go test -run='MySQL_Executor' ./...
39 |
40 | # Run TestMySQL_Executor for mysql 5.6 only
41 | go test -run='MySQL_Executor/mysql56' ./...
42 | ```
43 |
44 | If you'd like to run the above for Postgres 10, change the name respectively:
45 |
46 | ```shell
47 | # Run TestPostgres_Executor for all postgres versions
48 | go test -run='Postgres_Executor' ./...
49 |
50 | # Run TestPostgres_Executor for postgres 10 only
51 | go test -run='Postgres_Executor/postgres10' ./...
52 | ```
53 |
54 | If you want to run all tests for one specific dialect, like only TiDB 5, you can use the `-dialect` flag:
55 |
56 | ```shell
57 | go test -run='TiDB' -dialect='tidb5' ./...
58 | ```
--------------------------------------------------------------------------------
/internal/integration/testdata/migrations/mysql/1_initial.sql:
--------------------------------------------------------------------------------
1 | CREATE SCHEMA IF NOT EXISTS `bc_test`;
2 | CREATE TABLE `bc_test`.`bc_tbl` (`col` INTEGER NULL);
--------------------------------------------------------------------------------
/internal/integration/testdata/migrations/mysql/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:FT0VjrL64KJmuOe1Dq4dpbG/50Kwn0lZqfopa6BhJM8=
2 | 1_initial.sql h1:bWUYLjb0oiGQHf45Q08aKFKxVZ3pZBArJnSmuGBw9X4=
3 |
--------------------------------------------------------------------------------
/internal/integration/testdata/migrations/mysqlock/1.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `t1` (`id` int);
2 | CREATE TABLE `t2` (`id` int);
3 | select sleep(0.1);
4 | CREATE TABLE `t3` (`id` int);
5 | CREATE TABLE `t4` (`id` int);
6 | CREATE TABLE `t5` (`id` int);
7 | select sleep(0.1);
8 | CREATE TABLE `t6` (`id` int);
9 |
--------------------------------------------------------------------------------
/internal/integration/testdata/migrations/mysqlock/2.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `t1` ADD COLUMN `c1` varchar(255) DEFAULT 'name';
2 | ALTER TABLE `t2` ADD COLUMN `c1` varchar(255) DEFAULT 'name';
3 | select sleep(0.1);
4 | ALTER TABLE `t3` ADD COLUMN `c1` varchar(255) DEFAULT 'name';
5 | ALTER TABLE `t4` ADD COLUMN `c1` varchar(255) DEFAULT 'name';
6 | select sleep(0.1);
7 | ALTER TABLE `t5` ADD COLUMN `c1` varchar(255) DEFAULT 'name';
8 | ALTER TABLE `t6` ADD COLUMN `c1` varchar(255) DEFAULT 'name';
9 | ALTER TABLE `t1` ADD COLUMN `c2` varchar(255) DEFAULT 'name';
10 | ALTER TABLE `t2` ADD COLUMN `c2` varchar(255) DEFAULT 'name';
11 | select sleep(0.1);
12 | ALTER TABLE `t3` ADD COLUMN `c2` varchar(255) DEFAULT 'name';
13 | ALTER TABLE `t4` ADD COLUMN `c2` varchar(255) DEFAULT 'name';
14 | select sleep(0.1);
15 | ALTER TABLE `t5` ADD COLUMN `c2` varchar(255) DEFAULT 'name';
16 | ALTER TABLE `t6` ADD COLUMN `c2` varchar(255) DEFAULT 'name';
17 |
--------------------------------------------------------------------------------
/internal/integration/testdata/migrations/mysqlock/3.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `t7` (`id` int);
2 | select sleep(0.1);
3 | CREATE TABLE `t8` (`id` int);
4 | CREATE TABLE `t9` (`id` int);
5 |
--------------------------------------------------------------------------------
/internal/integration/testdata/migrations/mysqlock/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:XiFkhbkD+gUR/ry9+AVfyLW4X/tYaVUHFul5q0Kvtpo=
2 | 1.sql h1:+HoZslM3E59DllQlUXd5TFnPw+9de9IBNQEYdn77f7c=
3 | 2.sql h1:OliSiXPsLoVoWixWDC/yBJUtjrxnMMm+hjCf2Sz66Rk=
4 | 3.sql h1:Gb5M9ibe0COwTBrb08v/4VuWXxJ55+D2lSLXHLVa/Po=
5 |
--------------------------------------------------------------------------------
/internal/integration/testdata/migrations/postgres/1_initial.sql:
--------------------------------------------------------------------------------
1 | CREATE SCHEMA IF NOT EXISTS "bc_test";
2 | CREATE TABLE "bc_test"."bc_tbl" ("col" INTEGER NULL);
--------------------------------------------------------------------------------
/internal/integration/testdata/migrations/postgres/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:80V3wCzovMg2ot2hR0arbEjEfMfKWDeQNrXZJbFPF10=
2 | 1_initial.sql h1:53poyM34ShPWCVU41ldi4d9LUrzqPiQfBdEq//yH4Jo=
3 |
--------------------------------------------------------------------------------
/internal/integration/testdata/mysql/autoincrement.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | # Setup a custom AUTO_INCREMENT initial value.
5 | apply 2.hcl
6 | cmpshow users 2.sql
7 |
8 | # Increase the AUTO_INCREMENT value.
9 | apply 3.hcl
10 | cmpshow users 3.sql
11 |
12 | -- 1.hcl --
13 | schema "$db" {}
14 |
15 | table "users" {
16 | schema = schema.$db
17 | column "id" {
18 | null = false
19 | type = bigint
20 | auto_increment = true
21 | }
22 | primary_key {
23 | columns = [column.id]
24 | }
25 | }
26 |
27 | -- 1.sql --
28 | CREATE TABLE `users` (
29 | `id` bigint(20) NOT NULL AUTO_INCREMENT,
30 | PRIMARY KEY (`id`)
31 | )
32 |
33 | -- mysql8/1.sql --
34 | CREATE TABLE `users` (
35 | `id` bigint NOT NULL AUTO_INCREMENT,
36 | PRIMARY KEY (`id`)
37 | )
38 |
39 | -- 2.hcl --
40 | schema "$db" {}
41 |
42 | table "users" {
43 | schema = schema.$db
44 | column "id" {
45 | null = false
46 | type = bigint
47 | auto_increment = true
48 | }
49 | primary_key {
50 | columns = [column.id]
51 | }
52 | auto_increment = 1000
53 | }
54 |
55 | -- 2.sql --
56 | CREATE TABLE `users` (
57 | `id` bigint(20) NOT NULL AUTO_INCREMENT,
58 | PRIMARY KEY (`id`)
59 | ) AUTO_INCREMENT=1000
60 |
61 | -- mysql8/2.sql --
62 | CREATE TABLE `users` (
63 | `id` bigint NOT NULL AUTO_INCREMENT,
64 | PRIMARY KEY (`id`)
65 | ) AUTO_INCREMENT=1000
66 |
67 | -- 3.hcl --
68 | schema "$db" {}
69 |
70 | table "users" {
71 | schema = schema.$db
72 | column "id" {
73 | null = false
74 | type = bigint
75 | auto_increment = true
76 | }
77 | primary_key {
78 | columns = [column.id]
79 | }
80 | auto_increment = 2000
81 | }
82 |
83 | -- 3.sql --
84 | CREATE TABLE `users` (
85 | `id` bigint(20) NOT NULL AUTO_INCREMENT,
86 | PRIMARY KEY (`id`)
87 | ) AUTO_INCREMENT=2000
88 |
89 | -- mysql8/3.sql --
90 | CREATE TABLE `users` (
91 | `id` bigint NOT NULL AUTO_INCREMENT,
92 | PRIMARY KEY (`id`)
93 | ) AUTO_INCREMENT=2000
--------------------------------------------------------------------------------
/internal/integration/testdata/mysql/cli-inspect-file.txtar:
--------------------------------------------------------------------------------
1 | only mysql8
2 |
3 | # inspect without dev-db will failed
4 | ! atlas schema inspect -u file://a.sql
5 | stderr 'Error: --dev-url cannot be empty'
6 |
7 | # inspect file to HCL
8 | atlas schema inspect -u file://a.sql --dev-url URL > inspected.hcl
9 | cmp inspected.hcl script_cli_inspect.hcl
10 |
11 | # inspect file to SQL
12 | atlas schema inspect -u file://a.sql --dev-url URL --format '{{ sql . }}' > inspected.sql
13 | cmp inspected.sql script_cli_inspect.sql
14 |
15 | -- a.sql --
16 | create table users (
17 | id int NOT NULL,
18 | PRIMARY KEY (id)
19 | )
20 |
21 | -- script_cli_inspect.hcl --
22 | table "users" {
23 | schema = schema.script_cli_inspect_file
24 | column "id" {
25 | null = false
26 | type = int
27 | }
28 | primary_key {
29 | columns = [column.id]
30 | }
31 | }
32 | schema "script_cli_inspect_file" {
33 | charset = "utf8mb4"
34 | collate = "utf8mb4_0900_ai_ci"
35 | }
36 | -- script_cli_inspect.sql --
37 | -- Create "users" table
38 | CREATE TABLE `users` (`id` int NOT NULL, PRIMARY KEY (`id`)) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
39 |
--------------------------------------------------------------------------------
/internal/integration/testdata/mysql/cli-migrate-apply-datasrc.txtar:
--------------------------------------------------------------------------------
1 | only mysql8
2 |
3 | atlas migrate hash
4 | atlas migrate apply --url URL --env dev --var "url=URL" --var "pattern=script_cli_migrate_apply_datasrc"
5 | stdout 'Migrating to version 1 \(1 migrations in total\):'
6 |
7 | -- atlas.hcl --
8 | variable "url" {
9 | type = string
10 | }
11 |
12 | variable "pattern" {
13 | type = string
14 | }
15 |
16 | data "sql" "tenants" {
17 | url = var.url
18 | query = < out.txt
2 | exec cat out.txt
3 | stdout 'CREATE TABLE `script_cli_project_schemas`'
4 |
5 | -- 1.hcl --
6 | schema "script_cli_project_schemas" {
7 | }
8 | table "users" {
9 | schema = schema.script_cli_project_schemas
10 | column "id" {
11 | type = bigint
12 | null = false
13 | }
14 | }
15 | -- atlas.hcl --
16 | env "local" {
17 | url = "URL"
18 | src = "./1.hcl"
19 | schemas = ["script_cli_project_schemas"]
20 | }
21 | -- expected.sql --
22 | CREATE TABLE `users` (
23 | `id` bigint NOT NULL
24 | )
25 | -- 0.hcl --
26 | schema "$db" {
27 | charset = "$charset"
28 | collate = "$collate"
29 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/mysql/cli-project-url-escape.txtar:
--------------------------------------------------------------------------------
1 | only mysql8
2 |
3 | execsql 'CREATE USER IF NOT EXISTS "a8m"@"%" IDENTIFIED BY "&pass?"'
4 | execsql 'GRANT ALL PRIVILEGES ON *.* TO "a8m"@"%" WITH GRANT OPTION'
5 |
6 | atlas schema inspect --env local > got.txt
7 | cmp got.txt want.txt
8 |
9 | ! atlas schema inspect --env failed
10 | stderr 'invalid port ":&pass" after host'
11 |
12 | execsql 'DROP USER "a8m"@"%"'
13 |
14 | -- atlas.hcl --
15 | variable "pass" {
16 | type = string
17 | default = "&pass?"
18 | }
19 |
20 | locals {
21 | escaped_pass = urlescape(var.pass)
22 | }
23 |
24 | env "local" {
25 | url = "mysql://a8m:${local.escaped_pass}@localhost:3308/script_cli_project_url_escape"
26 | }
27 |
28 | env "failed" {
29 | url = "mysql://a8m:${var.pass}@localhost:3308/script_cli_project_url_escape"
30 | }
31 |
32 | -- want.txt --
33 | schema "script_cli_project_url_escape" {
34 | charset = "utf8mb4"
35 | collate = "utf8mb4_0900_ai_ci"
36 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/mysql/cli-schema-apply-datasrc.txtar:
--------------------------------------------------------------------------------
1 | only mysql8
2 |
3 | atlas schema apply --auto-approve --url URL --env dev --var "url=URL" --var "pattern=script_cli_schema_apply_datasrc"
4 | stdout '\{"Applied":\["CREATE TABLE `users` \(\\n `id` int NOT NULL\\n\);*"\],"Tenant":"script_cli_schema_apply_datasrc"\}'
5 |
6 | -- schema.hcl --
7 | variable "tenant" {
8 | type = string
9 | }
10 |
11 | schema "test" {
12 | name = var.tenant
13 | }
14 |
15 | table "users" {
16 | schema = schema.test
17 | column "id" {
18 | type = int
19 | }
20 | }
21 |
22 | -- atlas.hcl --
23 | variable "url" {
24 | type = string
25 | }
26 |
27 | variable "pattern" {
28 | type = string
29 | }
30 |
31 | data "sql" "tenants" {
32 | url = var.url
33 | query = < inspected.hcl
7 | cmp inspected.hcl script_cli_inspect.hcl
8 |
9 | # inspect file to SQL
10 | atlas schema inspect -u file://a.sql --dev-url URL --format '{{ sql . }}' > inspected.sql
11 | cmp inspected.sql script_cli_inspect.sql
12 |
13 | -- a.sql --
14 | create table users (
15 | id int NOT NULL,
16 | PRIMARY KEY (id)
17 | )
18 |
19 | -- script_cli_inspect.hcl --
20 | table "users" {
21 | schema = schema.script_cli_inspect_file
22 | column "id" {
23 | null = false
24 | type = integer
25 | }
26 | primary_key {
27 | columns = [column.id]
28 | }
29 | }
30 | schema "script_cli_inspect_file" {
31 | }
32 | -- script_cli_inspect.sql --
33 | -- Create "users" table
34 | CREATE TABLE "users" ("id" integer NOT NULL, PRIMARY KEY ("id"));
35 |
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/cli-inspect.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 |
3 | # test url flag
4 | atlas schema inspect -u URL > inspected.hcl
5 | cmp inspected.hcl script_cli_inspect.hcl
6 |
7 | # test exclude flag on table.
8 | atlas schema inspect -u URL --exclude "users" > inspected.hcl
9 | cmp inspected.hcl notable.hcl
10 |
11 | # test exclude flag on column.
12 | atlas schema inspect -u URL --exclude "*.[ab]*" > inspected.hcl
13 | cmp inspected.hcl id.hcl
14 |
15 | # test exclude flag on column.
16 | atlas schema inspect -u URL --exclude "*.*" > inspected.hcl
17 | cmp inspected.hcl nocolumn.hcl
18 |
19 |
20 | -- 1.hcl --
21 | table "users" {
22 | schema = schema.$db
23 | column "id" {
24 | null = false
25 | type = int
26 | }
27 | column "a" {
28 | null = false
29 | type = int
30 | }
31 | column "b" {
32 | null = false
33 | type = int
34 | }
35 | column "ab" {
36 | null = false
37 | type = int
38 | }
39 | column "ac" {
40 | null = false
41 | type = int4
42 | }
43 | }
44 | schema "$db" {
45 | }
46 |
47 | -- script_cli_inspect.hcl --
48 | table "users" {
49 | schema = schema.script_cli_inspect
50 | column "id" {
51 | null = false
52 | type = integer
53 | }
54 | column "a" {
55 | null = false
56 | type = integer
57 | }
58 | column "b" {
59 | null = false
60 | type = integer
61 | }
62 | column "ab" {
63 | null = false
64 | type = integer
65 | }
66 | column "ac" {
67 | null = false
68 | type = integer
69 | }
70 | }
71 | schema "script_cli_inspect" {
72 | }
73 | -- empty.hcl --
74 | -- notable.hcl --
75 | schema "script_cli_inspect" {
76 | }
77 | -- id.hcl --
78 | table "users" {
79 | schema = schema.script_cli_inspect
80 | column "id" {
81 | null = false
82 | type = integer
83 | }
84 | }
85 | schema "script_cli_inspect" {
86 | }
87 | -- nocolumn.hcl --
88 | table "users" {
89 | schema = schema.script_cli_inspect
90 | }
91 | schema "script_cli_inspect" {
92 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/cli-migrate-apply-datasrc.txtar:
--------------------------------------------------------------------------------
1 | only postgres14
2 |
3 | atlas migrate hash
4 | atlas migrate apply --url URL --env dev --var "url=URL" --var "pattern=script_cli_migrate_apply_datasrc"
5 | stdout 'Migrating to version 1 \(1 migrations in total\):'
6 |
7 | -- atlas.hcl --
8 | variable "url" {
9 | type = string
10 | }
11 |
12 | variable "pattern" {
13 | type = string
14 | }
15 |
16 | data "sql" "tenants" {
17 | url = var.url
18 | query = < 0)'
2 |
3 | apply 1.hcl
4 | cmpshow users 1.sql
5 | cmphcl 1.inspect.hcl
6 |
7 | -- 1.hcl --
8 | schema "script_column_domain" {}
9 |
10 | table "users" {
11 | schema = schema.script_column_domain
12 | column "c1" {
13 | type = sql("script_column_domain.positive_int")
14 | }
15 | }
16 |
17 | -- 1.sql --
18 | Table "script_column_domain.users"
19 | Column | Type | Collation | Nullable | Default
20 | --------+-----------------------------------+-----------+----------+---------
21 | c1 | script_column_domain.positive_int | | not null |
22 |
23 | -- 1.inspect.hcl --
24 | table "users" {
25 | schema = schema.script_column_domain
26 | column "c1" {
27 | null = false
28 | type = sql("positive_int")
29 | }
30 | }
31 | schema "script_column_domain" {
32 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/column-float.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | apply 2.hcl
5 | cmpshow users 2.sql
6 |
7 | -- 1.hcl --
8 | schema "$db" {}
9 |
10 | table "users" {
11 | schema = schema.$db
12 | column "c1" {
13 | type = real
14 | }
15 | column "c2" {
16 | type = double_precision
17 | }
18 | column "c3" {
19 | // Equals to real when precision is between 1 and 24.
20 | type = float(10)
21 | }
22 | column "c4" {
23 | // Equals to double_precision when precision is between 1 and 24.
24 | type = float(30)
25 | }
26 | }
27 |
28 | -- 1.sql --
29 | Table "script_column_float.users"
30 | Column | Type | Collation | Nullable | Default
31 | --------+------------------+-----------+----------+---------
32 | c1 | real | | not null |
33 | c2 | double precision | | not null |
34 | c3 | real | | not null |
35 | c4 | double precision | | not null |
36 |
37 |
38 | -- 2.hcl --
39 | schema "$db" {}
40 |
41 | table "users" {
42 | schema = schema.$db
43 | column "c1" {
44 | type = double_precision
45 | }
46 | column "c2" {
47 | type = real
48 | }
49 | column "c3" {
50 | type = float(30)
51 | }
52 | column "c4" {
53 | type = float(10)
54 | }
55 | }
56 |
57 | -- 2.sql --
58 | Table "script_column_float.users"
59 | Column | Type | Collation | Nullable | Default
60 | --------+------------------+-----------+----------+---------
61 | c1 | double precision | | not null |
62 | c2 | real | | not null |
63 | c3 | double precision | | not null |
64 | c4 | real | | not null |
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/column-generated-inspect.txtar:
--------------------------------------------------------------------------------
1 | # Skip PostgreSQL 10, 11 as they do not support generated columns.
2 | ! only postgres10|postgres11
3 |
4 | apply 1.hcl
5 | cmphcl 1.inspect.hcl
6 |
7 | -- 1.hcl --
8 | schema "$db" {}
9 |
10 | table "users" {
11 | schema = schema.$db
12 | column "a" {
13 | type = int
14 | }
15 | column "b" {
16 | type = int
17 | as = "1"
18 | }
19 | column "c" {
20 | type = int
21 | as {
22 | expr = "2"
23 | type = STORED
24 | }
25 | }
26 | }
27 |
28 | -- 1.inspect.hcl --
29 | table "users" {
30 | schema = schema.$db
31 | column "a" {
32 | null = false
33 | type = integer
34 | }
35 | column "b" {
36 | null = false
37 | type = integer
38 | as {
39 | expr = "1"
40 | type = STORED
41 | }
42 | }
43 | column "c" {
44 | null = false
45 | type = integer
46 | as {
47 | expr = "2"
48 | type = STORED
49 | }
50 | }
51 | }
52 | schema "$db" {
53 | }
54 |
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/column-identity.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | # Change identity generation.
5 | apply 2.hcl
6 | cmpshow users 2.sql
7 |
8 | -- 1.hcl --
9 | schema "$db" {}
10 |
11 | table "users" {
12 | schema = schema.$db
13 | column "name" {
14 | null = false
15 | type = int
16 | identity {
17 | generated = ALWAYS
18 | start = 10
19 | increment = 10
20 | }
21 | }
22 | }
23 |
24 | -- 1.sql --
25 | Table "script_column_identity.users"
26 | Column | Type | Collation | Nullable | Default
27 | --------+---------+-----------+----------+------------------------------
28 | name | integer | | not null | generated always as identity
29 |
30 |
31 | -- 2.hcl --
32 | schema "$db" {}
33 |
34 | table "users" {
35 | schema = schema.$db
36 | column "name" {
37 | null = false
38 | type = int
39 | identity {
40 | generated = BY_DEFAULT
41 | start = 10
42 | increment = 10
43 | }
44 | }
45 | }
46 |
47 | -- 2.sql --
48 | Table "script_column_identity.users"
49 | Column | Type | Collation | Nullable | Default
50 | --------+---------+-----------+----------+----------------------------------
51 | name | integer | | not null | generated by default as identity
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/column-interval.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow logs 1.sql
3 | cmphcl 1.inspect.hcl
4 |
5 | -- 1.hcl --
6 | table "logs" {
7 | schema = schema.script_column_interval
8 | column "a" {
9 | null = false
10 | type = interval
11 | default = "3 hours"
12 | }
13 | column "b" {
14 | null = false
15 | type = interval(1)
16 | }
17 | column "c" {
18 | null = false
19 | type = second
20 | }
21 | column "d" {
22 | null = false
23 | type = second(1)
24 | }
25 | column "e" {
26 | null = true
27 | type = day_to_second(4)
28 | }
29 | }
30 |
31 | schema "script_column_interval" {}
32 |
33 | -- 1.sql --
34 | Table "script_column_interval.logs"
35 | Column | Type | Collation | Nullable | Default
36 | --------+---------------------------+-----------+----------+----------------------
37 | a | interval | | not null | '03:00:00'::interval
38 | b | interval(1) | | not null |
39 | c | interval second | | not null |
40 | d | interval second(1) | | not null |
41 | e | interval day to second(4) | | |
42 |
43 |
44 | -- 1.inspect.hcl --
45 | table "logs" {
46 | schema = schema.script_column_interval
47 | column "a" {
48 | null = false
49 | type = interval
50 | default = sql("'03:00:00'::interval")
51 | }
52 | column "b" {
53 | null = false
54 | type = interval(1)
55 | }
56 | column "c" {
57 | null = false
58 | type = second
59 | }
60 | column "d" {
61 | null = false
62 | type = second(1)
63 | }
64 | column "e" {
65 | null = true
66 | type = day_to_second(4)
67 | }
68 | }
69 | schema "script_column_interval" {
70 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/column-range.txtar:
--------------------------------------------------------------------------------
1 | only postgres14 postgres15
2 |
3 | apply 1.hcl
4 | cmpshow t 1.sql
5 |
6 | -- 1.hcl --
7 | schema "$db" {}
8 |
9 | table "t" {
10 | schema = schema.$db
11 | column "r1" {
12 | type = int4range
13 | }
14 | column "r2" {
15 | type = int8range
16 | }
17 | column "r3" {
18 | type = numrange
19 | }
20 | column "r4" {
21 | type = tsrange
22 | }
23 | column "r5" {
24 | type = tstzrange
25 | }
26 | column "r6" {
27 | type = daterange
28 | }
29 | column "r7" {
30 | type = int4multirange
31 | }
32 | column "r8" {
33 | type = int8multirange
34 | }
35 | column "r9" {
36 | type = nummultirange
37 | }
38 | column "r10" {
39 | type = tsmultirange
40 | }
41 | column "r11" {
42 | type = tstzmultirange
43 | }
44 | column "r12" {
45 | type = datemultirange
46 | }
47 | }
48 |
49 | -- 1.sql --
50 | Table "script_column_range.t"
51 | Column | Type | Collation | Nullable | Default
52 | --------+----------------+-----------+----------+---------
53 | r1 | int4range | | not null |
54 | r2 | int8range | | not null |
55 | r3 | numrange | | not null |
56 | r4 | tsrange | | not null |
57 | r5 | tstzrange | | not null |
58 | r6 | daterange | | not null |
59 | r7 | int4multirange | | not null |
60 | r8 | int8multirange | | not null |
61 | r9 | nummultirange | | not null |
62 | r10 | tsmultirange | | not null |
63 | r11 | tstzmultirange | | not null |
64 | r12 | datemultirange | | not null |
65 |
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/column-textsearch.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow t 1.sql
3 | cmphcl 1.inspect.hcl
4 |
5 | -- 1.hcl --
6 | schema "script_column_textsearch" {}
7 |
8 | table "t" {
9 | schema = schema.script_column_textsearch
10 | column "tsv" {
11 | type = tsvector
12 | }
13 | column "tsq" {
14 | type = tsquery
15 | }
16 | index "idx_tsv" {
17 | type = GIN
18 | columns = [column.tsv]
19 | }
20 | }
21 |
22 | -- 1.sql --
23 | Table "script_column_textsearch.t"
24 | Column | Type | Collation | Nullable | Default
25 | --------+----------+-----------+----------+---------
26 | tsv | tsvector | | not null |
27 | tsq | tsquery | | not null |
28 | Indexes:
29 | "idx_tsv" gin (tsv)
30 |
31 |
32 | -- 1.inspect.hcl --
33 | table "t" {
34 | schema = schema.script_column_textsearch
35 | column "tsv" {
36 | null = false
37 | type = tsvector
38 | }
39 | column "tsq" {
40 | null = false
41 | type = tsquery
42 | }
43 | index "idx_tsv" {
44 | columns = [column.tsv]
45 | type = GIN
46 | }
47 | }
48 | schema "script_column_textsearch" {
49 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/index-expr.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | apply 2.hcl
5 | cmpshow users 2.sql
6 |
7 | -- 1.hcl --
8 | schema "$db" {}
9 |
10 | table "users" {
11 | schema = schema.$db
12 | column "first_name" {
13 | null = false
14 | type = varchar(128)
15 | }
16 | column "last_name" {
17 | null = false
18 | type = varchar(128)
19 | }
20 | index "full_name" {
21 | on {
22 | expr = "first_name || ' ' || last_name"
23 | }
24 | }
25 | }
26 |
27 | -- 1.sql --
28 | Table "script_index_expr.users"
29 | Column | Type | Collation | Nullable | Default
30 | ------------+------------------------+-----------+----------+---------
31 | first_name | character varying(128) | | not null |
32 | last_name | character varying(128) | | not null |
33 | Indexes:
34 | "full_name" btree (((first_name::text || ' '::text) || last_name::text))
35 |
36 |
37 | -- 2.hcl --
38 | schema "$db" {}
39 |
40 | table "users" {
41 | schema = schema.$db
42 | column "first_name" {
43 | null = false
44 | type = varchar(128)
45 | }
46 | column "last_name" {
47 | null = false
48 | type = varchar(128)
49 | }
50 | index "full_name" {
51 | on {
52 | expr = "first_name || '''s first name'"
53 | }
54 | }
55 | }
56 |
57 | -- 2.sql --
58 | Table "script_index_expr.users"
59 | Column | Type | Collation | Nullable | Default
60 | ------------+------------------------+-----------+----------+---------
61 | first_name | character varying(128) | | not null |
62 | last_name | character varying(128) | | not null |
63 | Indexes:
64 | "full_name" btree ((first_name::text || '''s first name'::text))
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/index-issue-557.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow t1 t2 1.sql
3 |
4 | -- 1.hcl --
5 | schema "$db" {}
6 |
7 | table "t1" {
8 | schema = schema.$db
9 | column "a" {
10 | null = false
11 | type = uuid
12 | }
13 | column "b" {
14 | null = true
15 | type = timestamp(6)
16 | }
17 | index "t1_a_b" {
18 | on {
19 | column = column.a
20 | }
21 | on {
22 | desc = true
23 | column = column.b
24 | }
25 | unique = true
26 | }
27 | }
28 |
29 | table "t2" {
30 | schema = schema.$db
31 | column "a" {
32 | null = false
33 | type = uuid
34 | }
35 | primary_key {
36 | columns = [column.a]
37 | }
38 | }
39 |
40 | -- 1.sql --
41 | Table "script_index_issue_557.t1"
42 | Column | Type | Collation | Nullable | Default
43 | --------+-----------------------------+-----------+----------+---------
44 | a | uuid | | not null |
45 | b | timestamp without time zone | | |
46 | Indexes:
47 | "t1_a_b" UNIQUE, btree (a, b DESC)
48 |
49 |
50 | Table "script_index_issue_557.t2"
51 | Column | Type | Collation | Nullable | Default
52 | --------+------+-----------+----------+---------
53 | a | uuid | | not null |
54 | Indexes:
55 | "t2_pkey" PRIMARY KEY, btree (a)
56 |
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/index-partial.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | apply 2.hcl
5 | cmpshow users 2.sql
6 |
7 | -- 1.hcl --
8 | schema "$db" {}
9 |
10 | table "users" {
11 | schema = schema.$db
12 | column "name" {
13 | null = false
14 | type = text
15 | }
16 | column "active" {
17 | null = true
18 | type = boolean
19 | }
20 | index "users_name" {
21 | columns = [column.name]
22 | where = "active"
23 | }
24 | }
25 |
26 | -- 1.sql --
27 | Table "script_index_partial.users"
28 | Column | Type | Collation | Nullable | Default
29 | --------+---------+-----------+----------+---------
30 | name | text | | not null |
31 | active | boolean | | |
32 | Indexes:
33 | "users_name" btree (name) WHERE active
34 |
35 |
36 | -- 2.hcl --
37 | schema "$db" {}
38 |
39 | table "users" {
40 | schema = schema.$db
41 | column "name" {
42 | null = false
43 | type = text
44 | }
45 | column "active" {
46 | null = true
47 | type = boolean
48 | }
49 | index "users_name" {
50 | columns = [column.name]
51 | where = "active AND name <> ''"
52 | }
53 | }
54 |
55 | -- 2.sql --
56 | Table "script_index_partial.users"
57 | Column | Type | Collation | Nullable | Default
58 | --------+---------+-----------+----------+---------
59 | name | text | | not null |
60 | active | boolean | | |
61 | Indexes:
62 | "users_name" btree (name) WHERE active AND name <> ''::text
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/index-type-brin.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | # Add the "page_per_range" storage parameter.
5 | apply 2.hcl
6 | cmpshow users 2.sql
7 |
8 | # Change the "page_per_range" storage parameter.
9 | apply 3.hcl
10 | cmpshow users 3.sql
11 |
12 | -- 1.hcl --
13 | schema "$db" {}
14 |
15 | table "users" {
16 | schema = schema.$db
17 | column "c" {
18 | null = false
19 | type = int
20 | }
21 | index "users_c" {
22 | type = BRIN
23 | columns = [column.c]
24 | }
25 | }
26 |
27 | -- 1.sql --
28 | Table "script_index_type_brin.users"
29 | Column | Type | Collation | Nullable | Default
30 | --------+---------+-----------+----------+---------
31 | c | integer | | not null |
32 | Indexes:
33 | "users_c" brin (c)
34 |
35 | -- 2.hcl --
36 | schema "$db" {}
37 |
38 | table "users" {
39 | schema = schema.$db
40 | column "c" {
41 | null = false
42 | type = int
43 | }
44 | index "users_c" {
45 | type = BRIN
46 | columns = [column.c]
47 | page_per_range = 2
48 | }
49 | }
50 |
51 | -- 2.sql --
52 | Table "script_index_type_brin.users"
53 | Column | Type | Collation | Nullable | Default
54 | --------+---------+-----------+----------+---------
55 | c | integer | | not null |
56 | Indexes:
57 | "users_c" brin (c) WITH (pages_per_range='2')
58 |
59 |
60 | -- 3.hcl --
61 | schema "$db" {}
62 |
63 | table "users" {
64 | schema = schema.$db
65 | column "c" {
66 | null = false
67 | type = int
68 | }
69 | index "users_c" {
70 | type = BRIN
71 | columns = [column.c]
72 | page_per_range = 3
73 | }
74 | }
75 |
76 | -- 3.sql --
77 | Table "script_index_type_brin.users"
78 | Column | Type | Collation | Nullable | Default
79 | --------+---------+-----------+----------+---------
80 | c | integer | | not null |
81 | Indexes:
82 | "users_c" brin (c) WITH (pages_per_range='3')
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/index-type.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | # Change index type.
5 | apply 2.hcl
6 | cmpshow users 2.sql
7 |
8 | -- 1.hcl --
9 | schema "$db" {}
10 |
11 | table "users" {
12 | schema = schema.$db
13 | column "name" {
14 | null = false
15 | type = text
16 | }
17 | column "data" {
18 | null = true
19 | type = jsonb
20 | }
21 | index "users_name" {
22 | type = HASH
23 | columns = [column.name]
24 | }
25 | index "users_data" {
26 | type = GIN
27 | columns = [column.data]
28 | }
29 | }
30 |
31 | -- 1.sql --
32 | Table "script_index_type.users"
33 | Column | Type | Collation | Nullable | Default
34 | --------+-------+-----------+----------+---------
35 | name | text | | not null |
36 | data | jsonb | | |
37 | Indexes:
38 | "users_data" gin (data)
39 | "users_name" hash (name)
40 |
41 | -- 2.hcl --
42 | schema "$db" {}
43 |
44 | table "users" {
45 | schema = schema.$db
46 | column "name" {
47 | null = false
48 | type = text
49 | }
50 | column "data" {
51 | null = true
52 | type = jsonb
53 | }
54 | index "users_name" {
55 | columns = [column.name]
56 | # Index without "using" defaults to BTREE.
57 | }
58 | index "users_data" {
59 | columns = [column.data]
60 | }
61 | }
62 |
63 | -- 2.sql --
64 | Table "script_index_type.users"
65 | Column | Type | Collation | Nullable | Default
66 | --------+-------+-----------+----------+---------
67 | name | text | | not null |
68 | data | jsonb | | |
69 | Indexes:
70 | "users_data" btree (data)
71 | "users_name" btree (name)
72 |
73 |
--------------------------------------------------------------------------------
/internal/integration/testdata/postgres/primary-key.txtar:
--------------------------------------------------------------------------------
1 | only postgres15
2 |
3 | # Create table.
4 | apply 1.hcl
5 | cmpshow users 1.sql
6 |
7 | # Add a primary-key.
8 | apply 2.hcl
9 | cmpshow users 2.sql
10 |
11 | # Modify the primary-key include columns.
12 | apply 3.hcl
13 | cmpshow users 3.sql
14 |
15 | # Drop the primary-key.
16 | apply 1.hcl
17 | cmpshow users 1.sql
18 |
19 | -- 1.hcl --
20 | schema "$db" {}
21 |
22 | table "users" {
23 | schema = schema.$db
24 | column "id" {
25 | null = false
26 | type = int
27 | }
28 | column "c" {
29 | null = true
30 | type = int
31 | }
32 | }
33 |
34 | -- 1.sql --
35 | Table "script_primary_key.users"
36 | Column | Type | Collation | Nullable | Default
37 | --------+---------+-----------+----------+---------
38 | id | integer | | not null |
39 | c | integer | | |
40 |
41 | -- 2.hcl --
42 | schema "$db" {}
43 |
44 | table "users" {
45 | schema = schema.$db
46 | column "id" {
47 | null = false
48 | type = int
49 | }
50 | column "c" {
51 | null = true
52 | type = int
53 | }
54 | primary_key {
55 | columns = [column.id]
56 | }
57 | }
58 |
59 | -- 2.sql --
60 | Table "script_primary_key.users"
61 | Column | Type | Collation | Nullable | Default
62 | --------+---------+-----------+----------+---------
63 | id | integer | | not null |
64 | c | integer | | |
65 | Indexes:
66 | "users_pkey" PRIMARY KEY, btree (id)
67 |
68 |
69 | -- 3.hcl --
70 | schema "$db" {}
71 |
72 | table "users" {
73 | schema = schema.$db
74 | column "id" {
75 | null = false
76 | type = int
77 | }
78 | column "c" {
79 | null = true
80 | type = int
81 | }
82 | primary_key {
83 | columns = [column.id]
84 | include = [column.c]
85 | }
86 | }
87 |
88 | -- 3.sql --
89 | Table "script_primary_key.users"
90 | Column | Type | Collation | Nullable | Default
91 | --------+---------+-----------+----------+---------
92 | id | integer | | not null |
93 | c | integer | | |
94 | Indexes:
95 | "users_pkey" PRIMARY KEY, btree (id) INCLUDE (c)
96 |
97 |
98 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/autoincrement.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | -- 1.hcl --
5 | schema "main" {}
6 |
7 | table "users" {
8 | schema = schema.main
9 | column "id" {
10 | null = false
11 | type = integer
12 | auto_increment = true
13 | }
14 | primary_key {
15 | columns = [column.id]
16 | }
17 | }
18 |
19 | -- 1.sql --
20 | CREATE TABLE `users` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT)
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-apply-multifile.txtar:
--------------------------------------------------------------------------------
1 | atlas schema apply -f users.hcl -f schema.hcl -u URL --auto-approve
2 | cmpshow users expected.sql
3 |
4 | -- users.hcl --
5 | table "users" {
6 | schema = schema.main
7 | column "id" {
8 | null = false
9 | type = int
10 | }
11 | column "status" {
12 | null = true
13 | type = text
14 | default = "hello"
15 | }
16 | }
17 | -- schema.hcl --
18 | schema "main" {
19 | }
20 | -- expected.sql --
21 | CREATE TABLE `users` (
22 | `id` int NOT NULL,
23 | `status` text NULL DEFAULT 'hello'
24 | )
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-apply-project-multifile.txtar:
--------------------------------------------------------------------------------
1 | atlas schema apply --env local --auto-approve
2 | cmpshow users expected.sql
3 |
4 | -- atlas.hcl --
5 | env "local" {
6 | url = "URL"
7 | src = "./schema"
8 | def_val = "hello"
9 | }
10 | -- schema/vars.hcl --
11 | variable "def_val" {
12 | type = string
13 | }
14 | -- schema/table.hcl --
15 | table "users" {
16 | schema = schema.main
17 | column "id" {
18 | null = false
19 | type = int
20 | }
21 | column "status" {
22 | null = true
23 | type = text
24 | default = var.def_val
25 | }
26 | }
27 | -- schema/schema.hcl --
28 | schema "main" {
29 | }
30 | -- expected.sql --
31 | CREATE TABLE `users` (
32 | `id` int NOT NULL,
33 | `status` text NULL DEFAULT 'hello'
34 | )
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-apply-vars.txtar:
--------------------------------------------------------------------------------
1 | ! atlas schema apply --env local --auto-approve
2 | stderr 'missing value for required variable "def_val"'
3 |
4 | atlas schema apply --env local_with_vals --auto-approve
5 | cmpshow users expected.sql
6 |
7 | -- atlas.hcl --
8 | env "local" {
9 | url = "URL"
10 | src = "./1.hcl"
11 | }
12 | env "local_with_vals" {
13 | url = "URL"
14 | src = "./1.hcl"
15 |
16 | def_val = "hello"
17 | }
18 | -- 1.hcl --
19 | variable "def_val" {
20 | type = string
21 | }
22 | table "users" {
23 | schema = schema.main
24 | column "id" {
25 | null = false
26 | type = int
27 | }
28 | column "status" {
29 | null = true
30 | type = text
31 | default = var.def_val
32 | }
33 | }
34 | schema "main" {
35 | }
36 | -- expected.sql --
37 | CREATE TABLE `users` (
38 | `id` int NOT NULL,
39 | `status` text NULL DEFAULT 'hello'
40 | )
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-inspect.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 |
3 | # test url flag
4 | atlas schema inspect -u URL > inspected.hcl
5 | cmp inspected.hcl 1.hcl
6 |
7 | # test exclude flag on table.
8 | atlas schema inspect -u URL --exclude "users" > inspected.hcl
9 | cmp inspected.hcl notable.hcl
10 |
11 | # test exclude flag on column.
12 | atlas schema inspect -u URL --exclude "*.[ab]*" > inspected.hcl
13 | cmp inspected.hcl id.hcl
14 |
15 | # test exclude flag on column.
16 | atlas schema inspect -u URL --exclude "*.*" > inspected.hcl
17 | cmp inspected.hcl nocolumn.hcl
18 |
19 |
20 | -- 1.hcl --
21 | table "users" {
22 | schema = schema.main
23 | column "id" {
24 | null = false
25 | type = int
26 | }
27 | column "a" {
28 | null = false
29 | type = int
30 | }
31 | column "b" {
32 | null = false
33 | type = int
34 | }
35 | column "ab" {
36 | null = false
37 | type = int
38 | }
39 | column "ac" {
40 | null = false
41 | type = uint64
42 | }
43 | }
44 | schema "main" {
45 | }
46 | -- empty.hcl --
47 | -- notable.hcl --
48 | schema "main" {
49 | }
50 | -- id.hcl --
51 | table "users" {
52 | schema = schema.main
53 | column "id" {
54 | null = false
55 | type = int
56 | }
57 | }
58 | schema "main" {
59 | }
60 | -- nocolumn.hcl --
61 | table "users" {
62 | schema = schema.main
63 | }
64 | schema "main" {
65 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-diff-datasrc-hcl-paths.txtar:
--------------------------------------------------------------------------------
1 | atlas migrate diff --env local
2 | cmpmig 0 expected.sql
3 |
4 | -- atlas.hcl --
5 | data "hcl_schema" "app" {
6 | paths = glob("schema-*.hcl")
7 | vars = {
8 | default_value = "unknown"
9 | }
10 | }
11 |
12 | env "local" {
13 | src = data.hcl_schema.app.url
14 | dev = "sqlite://dev?mode=memory&_fk=1"
15 | }
16 |
17 | -- schema-1.hcl --
18 | schema "main" {}
19 |
20 | table "pets" {
21 | schema = schema.main
22 | column "name" {
23 | null = false
24 | type = text
25 | default = var.default_value
26 | }
27 | column "owner_id" {
28 | type = integer
29 | }
30 | foreign_key "owner_id" {
31 | columns = [column.owner_id]
32 | ref_columns = [table.users.column.id]
33 | on_update = NO_ACTION
34 | on_delete = NO_ACTION
35 | }
36 | }
37 |
38 | -- schema-2.hcl --
39 | variable "default_value" {
40 | type = string
41 | }
42 | table "users" {
43 | schema = schema.main
44 | column "id" {
45 | null = true
46 | type = integer
47 | }
48 | column "name" {
49 | null = false
50 | type = text
51 | default = var.default_value
52 | }
53 | }
54 |
55 | -- expected.sql --
56 | -- Create "pets" table
57 | CREATE TABLE `pets` (`name` text NOT NULL DEFAULT 'unknown', `owner_id` integer NOT NULL, CONSTRAINT `owner_id` FOREIGN KEY (`owner_id`) REFERENCES `users` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION);
58 | -- Create "users" table
59 | CREATE TABLE `users` (`id` integer NULL, `name` text NOT NULL DEFAULT 'unknown');
60 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-diff-datasrc-hcl.txtar:
--------------------------------------------------------------------------------
1 | atlas migrate diff --env local
2 | cmpmig 0 expected.sql
3 |
4 | -- atlas.hcl --
5 | data "hcl_schema" "app" {
6 | path = "schema.hcl"
7 | vars = {
8 | default_value = "unknown"
9 | }
10 | }
11 |
12 | env "local" {
13 | src = data.hcl_schema.app.url
14 | dev = "sqlite://dev?mode=memory&_fk=1"
15 | }
16 |
17 | -- schema.hcl --
18 | variable "default_value" {
19 | type = string
20 | }
21 |
22 | schema "main" {}
23 |
24 | table "users" {
25 | schema = schema.main
26 | column "name" {
27 | null = false
28 | type = text
29 | default = var.default_value
30 | }
31 | }
32 |
33 | -- expected.sql --
34 | -- Create "users" table
35 | CREATE TABLE `users` (`name` text NOT NULL DEFAULT 'unknown');
36 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-diff-minimal-env.txtar:
--------------------------------------------------------------------------------
1 | atlas migrate diff --env local
2 | cmpmig 0 diff.sql
3 | -- atlas.hcl --
4 | env "local" {
5 | src = "1.hcl"
6 | dev = "sqlite://devdb"
7 | }
8 | -- 1.hcl --
9 | table "users" {
10 | schema = schema.main
11 | column "id" {
12 | null = false
13 | type = int
14 | }
15 | }
16 | schema "main" {
17 | }
18 | -- diff.sql --
19 | -- Create "users" table
20 | CREATE TABLE `users` (`id` int NOT NULL);
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-diff-multifile.txtar:
--------------------------------------------------------------------------------
1 | ! atlas migrate diff --dev-url sqlite://devdb --to file://schema/ --to other://scheme --dir file://migrations
2 | stderr 'got mixed --to url schemes'
3 |
4 | ! atlas migrate diff --dev-url sqlite://devdb --to mysql://localhost/x --to mysql://localhost/y --dir file://migrations
5 | stderr 'got multiple --to urls of scheme'
6 |
7 | atlas migrate diff --dev-url sqlite://devdb --to file://schema/ --dir file://migrations
8 | cmpmig 0 diff.sql
9 |
10 | # reset dir
11 | exec rm -rf migrations/
12 |
13 | atlas migrate diff --dev-url sqlite://devdb --to file://schema/schema.hcl --to file://schema/table.hcl --dir file://migrations
14 | cmpmig 0 diff.sql
15 |
16 | -- schema/schema.hcl --
17 | schema "main" {
18 | }
19 | -- schema/table.hcl --
20 | table "users" {
21 | schema = schema.main
22 | column "id" {
23 | null = false
24 | type = int
25 | }
26 | }
27 | -- diff.sql --
28 | -- Create "users" table
29 | CREATE TABLE `users` (`id` int NOT NULL);
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-diff.txtar:
--------------------------------------------------------------------------------
1 | exec mkdir migrations
2 |
3 | ! atlas migrate diff --to file://1.hcl --dir file://migrations
4 | stderr '"dev-url" not set'
5 |
6 | ! atlas migrate diff --dev-url sqlite://devdb --dir file://migrations
7 | stderr '"to" not set'
8 |
9 | atlas migrate diff --dev-url sqlite://devdb --to file://1.hcl --dir file://migrations
10 | cmpmig 0 diff.sql
11 | -- 1.hcl --
12 | table "users" {
13 | schema = schema.main
14 | column "id" {
15 | null = false
16 | type = int
17 | }
18 | }
19 | schema "main" {
20 | }
21 | -- diff.sql --
22 | -- Create "users" table
23 | CREATE TABLE `users` (`id` int NOT NULL);
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-lint-add-notnull.txtar:
--------------------------------------------------------------------------------
1 | atlas migrate lint --dir file://migrations --dev-url URL --latest=2
2 | stdout 'Analyzing changes until version 2 \(2 migrations in total\):'
3 | stdout ''
4 | stdout ' -- analyzing version 1'
5 | stdout ' -- no diagnostics found'
6 | stdout ' -- ok \(.+\)'
7 | stdout ''
8 | stdout ' -- analyzing version 2'
9 | stdout ' -- data dependent changes detected:'
10 | stdout ' -- L1: Adding a non-nullable "int" column "c2" will fail in case table "users" is not empty'
11 | stdout ' https://atlasgo.io/lint/analyzers#MF103'
12 | stdout ' -- ok \(.+\)'
13 | stdout ''
14 | stdout ' -------------------------'
15 | stdout ' -- .+'
16 | stdout ' -- 1 version ok, 1 with warnings'
17 | stdout ' -- 4 schema changes'
18 | stdout ' -- 1 diagnostic'
19 |
20 | -- migrations/1.sql --
21 | CREATE TABLE users (id int);
22 |
23 | /* Adding a not-null column without default to a table created in this file should not report. */
24 | ALTER TABLE users ADD COLUMN c1 int NOT NULL;
25 |
26 | -- migrations/2.sql --
27 | ALTER TABLE users ADD COLUMN c2 int NOT NULL;
28 |
29 | ALTER TABLE users ADD COLUMN c3 int NOT NULL DEFAULT 1;
30 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-lint-destructive.txtar:
--------------------------------------------------------------------------------
1 | # Expect the command to fail; exit code 1.
2 | ! atlas migrate lint --dir file://migrations --dev-url URL --latest=1
3 | stdout 'Analyzing changes from version 2 to 3 \(1 migration in total\):'
4 | stdout ''
5 | stdout ' -- analyzing version 3'
6 | stdout ' -- destructive changes detected:'
7 | stdout ' -- L1: Dropping table "pets" https://atlasgo.io/lint/analyzers#DS102'
8 | stdout ' -- suggested fix:'
9 | stdout ' -> Add a pre-migration check to ensure table "pets" is empty before dropping it'
10 | stdout ' -- ok \(.+\)'
11 | stdout ''
12 | stdout ' -------------------------'
13 | stdout ' -- .+'
14 | stdout ' -- 1 version with errors'
15 | stdout ' -- 1 schema change'
16 | stdout ' -- 1 diagnostic'
17 |
18 | # Expect the command to fail; exit code 1.
19 | ! atlas migrate lint --dir file://migrations --dev-url URL --latest=2
20 | stdout 'Analyzing changes from version 1 to 3 \(2 migrations in total\):'
21 | stdout ''
22 | stdout ' -- analyzing version 2'
23 | stdout ' -- destructive changes detected:'
24 | stdout ' -- L1: Dropping table "users" https://atlasgo.io/lint/analyzers#DS102'
25 | stdout ' -- suggested fix:'
26 | stdout ' -> Add a pre-migration check to ensure table "users" is empty before dropping it'
27 | stdout ' -- ok \(.+\)'
28 | stdout ''
29 | stdout ' -- analyzing version 3'
30 | stdout ' -- destructive changes detected:'
31 | stdout ' -- L1: Dropping table "pets" https://atlasgo.io/lint/analyzers#DS102'
32 | stdout ' -- suggested fix:'
33 | stdout ' -> Add a pre-migration check to ensure table "pets" is empty before dropping it'
34 | stdout ' -- ok \(.+\)'
35 | stdout ''
36 | stdout ' -------------------------'
37 | stdout ' -- .+'
38 | stdout ' -- 2 versions with errors'
39 | stdout ' -- 2 schema changes'
40 | stdout ' -- 2 diagnostics'
41 |
42 | -- migrations/1.sql --
43 | CREATE TABLE users (id int);
44 |
45 | CREATE TABLE pets (id int);
46 |
47 | ALTER TABLE users RENAME COLUMN id TO oid;
48 |
49 | -- migrations/2.sql --
50 | DROP TABLE users;
51 |
52 | -- migrations/3.sql --
53 | DROP TABLE pets;
54 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-lint-minimal-env.txtar:
--------------------------------------------------------------------------------
1 | # Expect the command to fail; exit code 1.
2 | ! atlas migrate lint --env local --latest=2
3 | stdout 'Analyzing changes until version 2 \(2 migrations in total\):'
4 | stdout ''
5 | stdout ' -- analyzing version 1'
6 | stdout ' -- no diagnostics found'
7 | stdout ' -- ok \(.+\)'
8 | stdout ''
9 | stdout ' -- analyzing version 2'
10 | stdout ' -- destructive changes detected:'
11 | stdout ' -- L1: Dropping table "users" https://atlasgo.io/lint/analyzers#DS102'
12 | stdout ' -- suggested fix:'
13 | stdout ' -> Add a pre-migration check to ensure table "users" is empty before dropping it'
14 | stdout ' -- ok \(.+\)'
15 | stdout ''
16 | stdout ' -------------------------'
17 | stdout ' -- .+'
18 | stdout ' -- 1 version ok, 1 with errors'
19 | stdout ' -- 2 schema changes'
20 | stdout ' -- 1 diagnostic'
21 |
22 |
23 | -- atlas.hcl --
24 | env "local" {
25 | dev = "URL"
26 | }
27 | -- migrations/1.sql --
28 | CREATE TABLE users (id int);
29 | -- migrations/2.sql --
30 | DROP TABLE users;
31 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-lint-project.txtar:
--------------------------------------------------------------------------------
1 | atlas migrate lint --dir file://migrations --dev-url URL --env=log_name > got.txt
2 | cmp got.txt expected1.txt
3 |
4 | atlas migrate lint --dir file://migrations --dev-url URL --env=log_count > got.txt
5 | cmp got.txt expected2.txt
6 |
7 | -- migrations/1.sql --
8 | CREATE TABLE users (id int);
9 |
10 | CREATE TABLE pets (id int);
11 |
12 | ALTER TABLE users RENAME COLUMN id TO oid;
13 |
14 | -- migrations/2.sql --
15 | DROP TABLE users;
16 |
17 | -- migrations/3.sql --
18 | DROP TABLE pets;
19 |
20 | -- expected1.txt --
21 | 3.sql
22 | -- expected2.txt --
23 | 2
24 | -- atlas.hcl --
25 | lint {
26 | latest = 1
27 | destructive {
28 | error = false
29 | }
30 | }
31 |
32 | env "log_name" {
33 | lint {
34 | log = "{{ range .Files }}{{ println .Name }}{{ end }}"
35 | }
36 | }
37 |
38 | env "log_count" {
39 | lint {
40 | latest = 2
41 | log = "{{ len .Files | println }}"
42 | }
43 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-project-multifile.txtar:
--------------------------------------------------------------------------------
1 | atlas migrate diff --env local
2 | cmpmig 0 diff.sql
3 |
4 | # reset
5 | exec rm -rf migrations
6 |
7 | atlas migrate diff --env src_list
8 | cmpmig 0 diff.sql
9 |
10 | # reset
11 | exec rm -rf migrations
12 |
13 | atlas migrate diff --env single_elem
14 | cmpmig 0 diff.sql
15 | -- atlas.hcl --
16 | env "local" {
17 | url = "URL"
18 | dev = "sqlite://test?mode=memory&_fk=1"
19 | src = "./schema"
20 | migration {
21 | dir = "file://migrations"
22 | format = atlas
23 | }
24 | }
25 | env "src_list" {
26 | url = "URL"
27 | dev = "sqlite://test?mode=memory&_fk=1"
28 | src = [
29 | "./schema/1.hcl",
30 | "./schema/2.hcl",
31 | ]
32 | migration {
33 | dir = "file://migrations"
34 | format = atlas
35 | }
36 | }
37 | env "single_elem" {
38 | url = "URL"
39 | dev = "sqlite://test?mode=memory&_fk=1"
40 | src = [
41 | "./schema/",
42 | ]
43 | migration {
44 | dir = "file://migrations"
45 | format = atlas
46 | }
47 | }
48 | -- schema/1.hcl --
49 | table "users" {
50 | schema = schema.main
51 | column "id" {
52 | null = false
53 | type = int
54 | }
55 | }
56 | -- schema/2.hcl --
57 | schema "main" {
58 | }
59 | -- diff.sql --
60 | -- Create "users" table
61 | CREATE TABLE `users` (`id` int NOT NULL);
62 | -- empty.sql --
63 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-project.txtar:
--------------------------------------------------------------------------------
1 | exec mkdir migrations
2 | atlas migrate diff --env local
3 | cmpmig 0 diff.sql
4 |
5 | atlas migrate validate --env local
6 |
7 | atlas migrate new 1 --env local
8 | cmpmig 1 empty.sql
9 |
10 | exec touch migrations/2.sql
11 | ! atlas migrate validate --env local
12 | stderr 'Error: checksum mismatch'
13 |
14 | atlas migrate hash --env local
15 | atlas migrate validate --env local
16 |
17 | -- atlas.hcl --
18 | env "local" {
19 | url = "URL"
20 | dev = "sqlite://test?mode=memory&_fk=1"
21 | src = "./1.hcl"
22 | migration {
23 | dir = "file://migrations"
24 | format = atlas
25 | }
26 | }
27 | -- 1.hcl --
28 | table "users" {
29 | schema = schema.main
30 | column "id" {
31 | null = false
32 | type = int
33 | }
34 | }
35 | schema "main" {
36 | }
37 | -- diff.sql --
38 | -- Create "users" table
39 | CREATE TABLE `users` (`id` int NOT NULL);
40 | -- empty.sql --
41 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-migrate-set.txtar:
--------------------------------------------------------------------------------
1 | ! atlas migrate set 0
2 | stderr 'Error: checksum file not found'
3 | stdout 'You have a checksum error in your migration directory.'
4 |
5 | atlas migrate hash
6 |
7 | ! atlas migrate set --url URL
8 | stderr 'Error: accepts 1 arg\(s\), received 0'
9 |
10 | ! atlas migrate set --url URL foo bar
11 | stderr 'Error: accepts 1 arg\(s\), received 2'
12 |
13 | # Works on fresh database.
14 | atlas migrate set 1 --url URL
15 | atlas migrate apply 1 --url URL --dry-run
16 | stdout 'Migrating to version 2 from 1'
17 |
18 | # Set to second last migration.
19 | atlas migrate set 2 --url URL
20 | atlas migrate apply 1 --url URL --dry-run
21 | stdout 'Migrating to version 3 from 2'
22 |
23 | # Have one migration applied, manual do second, set revision and continue apply.
24 | clearSchema
25 | atlas migrate apply 1 --url URL
26 | stdout 'Migrating to version 1'
27 | atlas migrate set 2 --url URL
28 | atlas migrate apply 1 --url URL --dry-run
29 | stdout 'Migrating to version 3 from 2'
30 |
31 | # Set to non-existing migration requires flag.
32 | ! atlas migrate set 4 --url URL
33 | stderr 'Error: migration with version "4" not found'
34 |
35 | # If set to last version, nothing to do.
36 | atlas migrate set 3 --url URL
37 | atlas migrate apply --url URL
38 | stdout 'No migration files to execute'
39 |
40 | # Partially applied (error), fix with set.
41 | clearSchema
42 | mv broken.sql migrations/4.sql
43 | atlas migrate hash
44 | ! atlas migrate apply --url URL --tx-mode none
45 | stdout 'Migrating to version 4'
46 | atlas migrate set 4 --url URL
47 | atlas migrate apply --url URL
48 | stdout 'No migration files to execute'
49 |
50 | -- migrations/1_first.sql --
51 | CREATE TABLE `users` (`id` bigint NOT NULL, `age` bigint NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`));
52 |
53 | -- migrations/2_second.sql --
54 | ALTER TABLE `users` ADD UNIQUE INDEX `age` (`age`);
55 |
56 | -- migrations/3_third.sql --
57 | CREATE TABLE `pets` (`id` bigint NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`));
58 |
59 | -- broken.sql --
60 | CREATE TABLE `vets` (`id` bigint NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY(`id`));
61 | asdf ALTER TABLE `users` ADD UNIQUE INDEX `name` (`name`);
62 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-project-vars.txtar:
--------------------------------------------------------------------------------
1 | ! atlas schema apply --env local --auto-approve
2 | stderr 'Error: missing value for required variable "user_status_default"'
3 |
4 | atlas schema apply --env local --auto-approve --var user_status_default=hello
5 | cmpshow users expected.sql
6 |
7 | -- atlas.hcl --
8 | variable "user_status_default" {
9 | type = string
10 | }
11 | env "local" {
12 | url = "URL"
13 | src = "./1.hcl"
14 | def_val = var.user_status_default
15 | }
16 | -- 1.hcl --
17 | variable "def_val" {
18 | type = string
19 | }
20 | table "users" {
21 | schema = schema.main
22 | column "id" {
23 | null = false
24 | type = int
25 | }
26 | column "status" {
27 | null = true
28 | type = text
29 | default = var.def_val
30 | }
31 | }
32 | schema "main" {
33 | }
34 | -- expected.sql --
35 | CREATE TABLE `users` (
36 | `id` int NOT NULL,
37 | `status` text NULL DEFAULT 'hello'
38 | )
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/cli-schema-project-file.txtar:
--------------------------------------------------------------------------------
1 | ! atlas schema inspect
2 | stderr '"url" not set'
3 |
4 | ! atlas schema apply -f 1.hcl
5 | stderr '"url" not set'
6 |
7 | ! atlas schema apply --url URL
8 | stderr 'one of flag\(s\) "file" or "to" is required'
9 |
10 | ! atlas schema apply -f atlas.hcl -u URL
11 | stderr 'cannot parse project file'
12 |
13 | # Verify "url" and "src" attributes of the env are used.
14 | atlas schema apply --env local --auto-approve
15 | atlas schema inspect --env local > inspected.hcl
16 | cmp 1.hcl inspected.hcl
17 |
18 | # Verify the precedence of flag over project file.
19 | atlas schema apply --env local --auto-approve -f 2.hcl
20 | atlas schema inspect --env local > inspected.hcl
21 | cmp 2.hcl inspected.hcl
22 |
23 | -- atlas.hcl --
24 | env "local" {
25 | url = "URL"
26 | src = "./1.hcl"
27 | }
28 | -- 1.hcl --
29 | table "users" {
30 | schema = schema.main
31 | column "id" {
32 | null = false
33 | type = int
34 | }
35 | }
36 | schema "main" {
37 | }
38 | -- 2.hcl --
39 | table "other" {
40 | schema = schema.main
41 | column "id" {
42 | null = false
43 | type = int
44 | }
45 | }
46 | schema "main" {
47 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/column-default.txtar:
--------------------------------------------------------------------------------
1 | execsql 'CREATE TABLE tbl (col)'
2 | cmphcl 1.hcl
3 |
4 | -- 1.hcl --
5 | table "tbl" {
6 | schema = schema.main
7 | column "col" {
8 | null = true
9 | type = blob
10 | }
11 | }
12 | schema "main" {
13 | }
14 |
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/column-user-defined.txtar:
--------------------------------------------------------------------------------
1 | # Initial changes.
2 | atlas schema apply --url URL --dev-url DEV_URL --to file://schema.v1.hcl --auto-approve
3 | atlas schema apply --url URL --dev-url DEV_URL --to file://schema.v1.hcl --auto-approve
4 | stdout 'Schema is synced, no changes to be made'
5 | atlas schema inspect --url URL > got
6 | cmp schema.v1.hcl.inspected got
7 |
8 | # Changing user defined type.
9 | atlas schema apply --url URL --dev-url DEV_URL --to file://schema.v2.hcl --auto-approve
10 | atlas schema apply --url URL --dev-url DEV_URL --to file://schema.v2.hcl --auto-approve
11 | stdout 'Schema is synced, no changes to be made'
12 | atlas schema inspect --url URL > got
13 | cmp schema.v2.hcl.inspected got
14 |
15 | -- schema.v1.hcl --
16 | table "t" {
17 | schema = schema.main
18 | column "c" {
19 | null = true
20 | type = sql("USER_DEFINED")
21 | }
22 | }
23 | schema "main" {
24 | }
25 | -- schema.v1.hcl.inspected --
26 | table "t" {
27 | schema = schema.main
28 | column "c" {
29 | null = true
30 | type = sql("USER_DEFINED")
31 | }
32 | }
33 | schema "main" {
34 | }
35 | -- schema.v2.hcl --
36 | table "t" {
37 | schema = schema.main
38 | column "c" {
39 | null = true
40 | type = sql("USER_TYPE")
41 | }
42 | }
43 | schema "main" {
44 | }
45 | -- schema.v2.hcl.inspected --
46 | table "t" {
47 | schema = schema.main
48 | column "c" {
49 | null = true
50 | type = sql("USER_TYPE")
51 | }
52 | }
53 | schema "main" {
54 | }
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/index-desc.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | # Drop the "DESC" option from the key part.
5 | apply 2.hcl
6 | cmpshow users 2.sql
7 | # Use of "columns" instead of "on" should not trigger a change.
8 | synced 2-no-change.hcl
9 |
10 | apply 3.hcl
11 | cmpshow users 3.sql
12 |
13 | -- 1.hcl --
14 | schema "main" {}
15 |
16 | table "users" {
17 | schema = schema.main
18 | column "rank" {
19 | type = int
20 | }
21 | index "rank_idx" {
22 | on {
23 | desc = true
24 | column = table.users.column.rank
25 | }
26 | }
27 | }
28 |
29 | -- 1.sql --
30 | CREATE TABLE `users` (`rank` int NOT NULL)
31 | CREATE INDEX `rank_idx` ON `users` (`rank` DESC)
32 |
33 | -- 2.hcl --
34 | schema "main" {}
35 |
36 | table "users" {
37 | schema = schema.main
38 | column "rank" {
39 | type = int
40 | }
41 | index "rank_idx" {
42 | on {
43 | column = table.users.column.rank
44 | }
45 | }
46 | }
47 |
48 | -- 2.sql --
49 | CREATE TABLE "users" (`rank` int NOT NULL)
50 | CREATE INDEX `rank_idx` ON `users` (`rank`)
51 |
52 | -- 2-no-change.hcl --
53 | schema "main" {}
54 |
55 | table "users" {
56 | schema = schema.main
57 | column "rank" {
58 | type = int
59 | }
60 | index "rank_idx" {
61 | columns = [
62 | table.users.column.rank,
63 | ]
64 | }
65 | }
66 |
67 | -- 3.hcl --
68 | schema "main" {}
69 |
70 | table "users" {
71 | schema = schema.main
72 | column "rank" {
73 | type = int
74 | }
75 | column "score" {
76 | type = int
77 | }
78 | index "rank_score_idx" {
79 | on {
80 | column = table.users.column.rank
81 | }
82 | on {
83 | column = table.users.column.score
84 | desc = true
85 | }
86 | }
87 | }
88 |
89 | -- 3.sql --
90 | CREATE TABLE "users" (`rank` int NOT NULL, `score` int NOT NULL)
91 | CREATE INDEX `rank_score_idx` ON `users` (`rank`, `score` DESC)
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/index-expr.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | apply 2.hcl
5 | cmpshow users 2.sql
6 |
7 | -- 1.hcl --
8 | schema "main" {}
9 |
10 | table "users" {
11 | schema = schema.main
12 | column "first_name" {
13 | null = false
14 | type = text
15 | }
16 | column "last_name" {
17 | null = false
18 | type = text
19 | }
20 | index "full_name" {
21 | on {
22 | expr = "first_name || ' ' || last_name"
23 | }
24 | }
25 | }
26 |
27 | -- 1.sql --
28 | CREATE TABLE `users` (`first_name` text NOT NULL, `last_name` text NOT NULL)
29 | CREATE INDEX `full_name` ON `users` ((first_name || ' ' || last_name))
30 |
31 | -- 2.hcl --
32 | schema "main" {}
33 |
34 | table "users" {
35 | schema = schema.main
36 | column "first_name" {
37 | null = false
38 | type = text
39 | }
40 | index "full_name" {
41 | on {
42 | expr = "lower(first_name) || '''s first name'"
43 | }
44 | }
45 | }
46 |
47 | -- 2.sql --
48 | CREATE TABLE "users" (`first_name` text NOT NULL)
49 | CREATE INDEX `full_name` ON `users` ((lower(first_name) || '''s first name'))
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/index-partial.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow users 1.sql
3 |
4 | apply 2.hcl
5 | cmpshow users 2.sql
6 |
7 | -- 1.hcl --
8 | schema "main" {}
9 |
10 | table "users" {
11 | schema = schema.main
12 | column "name" {
13 | null = false
14 | type = text
15 | }
16 | column "active" {
17 | null = true
18 | type = boolean
19 | }
20 | index "users_name" {
21 | columns = [column.name]
22 | where = "active"
23 | }
24 | }
25 |
26 | -- 1.sql --
27 | CREATE TABLE `users` (`name` text NOT NULL, `active` boolean NULL)
28 | CREATE INDEX `users_name` ON `users` (`name`) WHERE active
29 |
30 | -- 2.hcl --
31 | schema "main" {}
32 |
33 | table "users" {
34 | schema = schema.main
35 | column "name" {
36 | null = false
37 | type = text
38 | }
39 | column "active" {
40 | null = true
41 | type = boolean
42 | }
43 | index "users_name" {
44 | columns = [column.name]
45 | where = "active AND name <> ''"
46 | }
47 | }
48 |
49 | -- 2.sql --
50 | CREATE TABLE "users" (`name` text NOT NULL, `active` boolean NULL)
51 | CREATE INDEX `users_name` ON `users` (`name`) WHERE active AND name <> ''
--------------------------------------------------------------------------------
/internal/integration/testdata/sqlite/table-options.txtar:
--------------------------------------------------------------------------------
1 | apply 1.hcl
2 | cmpshow t1 1.sql
3 | cmpshow t2 2.sql
4 | cmpshow t3 3.sql
5 |
6 | # Drop options.
7 | apply 2.hcl
8 | cmpshow t1 11.sql
9 |
10 | -- 1.hcl --
11 | schema "main" {}
12 |
13 | table "t1" {
14 | schema = schema.main
15 | column "id" {
16 | null = false
17 | type = integer
18 | }
19 | primary_key {
20 | columns = [column.id]
21 | }
22 | strict = true
23 | without_rowid = true
24 | }
25 |
26 | table "t2" {
27 | schema = schema.main
28 | column "id" {
29 | null = false
30 | type = integer
31 | }
32 | primary_key {
33 | columns = [column.id]
34 | }
35 | strict = true
36 | }
37 |
38 | table "t3" {
39 | schema = schema.main
40 | column "id" {
41 | null = false
42 | type = integer
43 | }
44 | primary_key {
45 | columns = [column.id]
46 | }
47 | without_rowid = true
48 | }
49 |
50 | -- 1.sql --
51 | CREATE TABLE `t1` (`id` integer NOT NULL, PRIMARY KEY (`id`)) WITHOUT ROWID, STRICT
52 |
53 | -- 2.sql --
54 | CREATE TABLE `t2` (`id` integer NOT NULL, PRIMARY KEY (`id`)) STRICT
55 |
56 | -- 3.sql --
57 | CREATE TABLE `t3` (`id` integer NOT NULL, PRIMARY KEY (`id`)) WITHOUT ROWID
58 |
59 | -- 2.hcl --
60 | schema "main" {}
61 |
62 | table "t1" {
63 | schema = schema.main
64 | column "id" {
65 | null = false
66 | type = integer
67 | }
68 | primary_key {
69 | columns = [column.id]
70 | }
71 | }
72 |
73 | -- 11.sql --
74 | CREATE TABLE "t1" (`id` integer NOT NULL, PRIMARY KEY (`id`))
75 |
--------------------------------------------------------------------------------
/internal/integration/tools.go:
--------------------------------------------------------------------------------
1 | //go:build tools
2 | // +build tools
3 |
4 | package main
5 |
6 | import (
7 | _ "ariga.io/atlas/cmd/atlas"
8 | )
9 |
--------------------------------------------------------------------------------
/schemahcl/testdata/a.hcl:
--------------------------------------------------------------------------------
1 | person "rotemtam" {
2 | hobby = var.hobby
3 | }
--------------------------------------------------------------------------------
/schemahcl/testdata/b.hcl:
--------------------------------------------------------------------------------
1 | person "tzuri" {
2 | hobby = "ice-cream"
3 | parent = person.rotemtam
4 | }
--------------------------------------------------------------------------------
/schemahcl/testdata/nested/c.hcl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ariga/atlas/907691a43e4d4571fb8dcbacedf0da15a0f5180a/schemahcl/testdata/nested/c.hcl
--------------------------------------------------------------------------------
/schemahcl/testdata/variables.hcl:
--------------------------------------------------------------------------------
1 | variable "hobby" {
2 | type = string
3 | }
--------------------------------------------------------------------------------
/sql/migrate/migrate_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package migrate
8 |
9 | import (
10 | "context"
11 | "fmt"
12 | )
13 |
14 | // IsCheckpoint reports whether the file is a checkpoint file.
15 | func (f *LocalFile) IsCheckpoint() bool {
16 | return f.isCheckpoint()
17 | }
18 |
19 | // CheckpointTag returns the tag of the checkpoint file, if defined.
20 | func (f *LocalFile) CheckpointTag() (string, error) {
21 | return f.checkpointTag()
22 | }
23 |
24 | // fileStmts returns the statements defined in the given file.
25 | func (e *Executor) fileStmts(f File) ([]*Stmt, error) {
26 | return FileStmtDecls(e.drv, f)
27 | }
28 |
29 | func (e *Executor) fileChecks(context.Context, File, *Revision) error {
30 | return nil // unimplemented
31 | }
32 |
33 | // ValidateDir before operating on it.
34 | func (e *Executor) ValidateDir(context.Context) error {
35 | if err := Validate(e.dir); err != nil {
36 | return fmt.Errorf("sql/migrate: validate migration directory: %w", err)
37 | }
38 | return nil
39 | }
40 |
41 | func (e *StmtExecError) Error() string {
42 | return fmt.Sprintf("sql/migrate: executing statement %q from version %q: %v", e.Stmt.Text, e.Version, e.Err)
43 | }
44 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/golang-migrate/1_base.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE t(c int);
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/1.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE t1(id int);
2 |
3 |
4 | CREATE TABLE t2(id int);
5 |
6 | CREATE TABLE t3(id int);
7 |
8 | CREATE TABLE t4(
9 | id int,
10 | name varchar(255)
11 | );
12 |
13 | CREATE TABLE t4(
14 | id int,
15 | `name` varchar(255) DEFAULT ';'
16 | ) ENGINE=InnoDB;
17 |
18 | CREATE TABLE t5(
19 | id int
20 | /* comment */
21 | -- comment
22 | ) ENGINE=InnoDB;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/1.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE TABLE t1(id int);
2 | -- end --
3 | CREATE TABLE t2(id int);
4 | -- end --
5 | CREATE TABLE t3(id int);
6 | -- end --
7 | CREATE TABLE t4(
8 | id int,
9 | name varchar(255)
10 | );
11 | -- end --
12 | CREATE TABLE t4(
13 | id int,
14 | `name` varchar(255) DEFAULT ';'
15 | ) ENGINE=InnoDB;
16 | -- end --
17 | CREATE TABLE t5(
18 | id int
19 | /* comment */
20 | -- comment
21 | ) ENGINE=InnoDB;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/10_delimiter_comment.sql:
--------------------------------------------------------------------------------
1 | -- atlas:delimiter -- end
2 |
3 | CREATE PROCEDURE dorepeat(p1 INT)
4 | BEGIN
5 | SET @x = 0;
6 | REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
7 | END;
8 | -- end
9 | CALL dorepeat(1000);
10 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/10_delimiter_comment.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE PROCEDURE dorepeat(p1 INT)
2 | BEGIN
3 | SET @x = 0;
4 | REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
5 | END;
6 | -- end --
7 | CALL dorepeat(1000);
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/11_delimiter_mysql_command.sql:
--------------------------------------------------------------------------------
1 | -- An example for supporting MySQL client delimiters.
2 |
3 | DELIMITER $$
4 |
5 | CREATE OR REPLACE FUNCTION gen_uuid() RETURNS VARCHAR(22)
6 | BEGIN
7 | RETURN concat(
8 | date_format(NOW(6), '%Y%m%d%i%s%f'),
9 | ROUND(1 + RAND() * (100 - 2))
10 | );
11 | END;$$
12 |
13 | DELIMITER ;
14 |
15 | CALL gen_uuid();
16 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/11_delimiter_mysql_command.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE OR REPLACE FUNCTION gen_uuid() RETURNS VARCHAR(22)
2 | BEGIN
3 | RETURN concat(
4 | date_format(NOW(6), '%Y%m%d%i%s%f'),
5 | ROUND(1 + RAND() * (100 - 2))
6 | );
7 | END;
8 | -- end --
9 | CALL gen_uuid();
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/12_delimiter_mysql_command.sql:
--------------------------------------------------------------------------------
1 | delimiter //
2 | create table t2 (a int) //
3 |
4 | delimiter ;
5 | delimiter //
6 |
7 | create table t3 (a int) //
8 | delimiter ;
9 |
10 | show tables;
11 | drop table t2, t3;
12 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/12_delimiter_mysql_command.sql.golden:
--------------------------------------------------------------------------------
1 | create table t2 (a int)
2 | -- end --
3 | create table t3 (a int)
4 | -- end --
5 | show tables;
6 | -- end --
7 | drop table t2, t3;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/13_delimiter_mysql_command.sql:
--------------------------------------------------------------------------------
1 | # Test delimiter :
2 | select "Test delimiter :" as " ";
3 | delimiter :
4 | select * from t1:
5 | /* Delimiter commands can have comments */
6 | delimiter ;
7 | select 'End test :';
8 |
9 | /* Test delimiter :; */
10 | select "Test delimiter :;" as " ";
11 | delimiter :;
12 | select * from t1 :;
13 | delimiter ;
14 | select 'End test :;';
15 |
16 | -- Test delimiter //
17 | select "Test delimiter //" as " ";
18 | delimiter //
19 | select * from t1//
20 | delimiter ;
21 | select 'End test //';
22 |
23 | # Test delimiter 'MySQL'
24 | select "Test delimiter MySQL" as " ";
25 | delimiter 'MySQL'
26 | select * from t1MySQL
27 | delimiter ;
28 | select 'End test MySQL';
29 |
30 | # Test delimiter 'delimiter'
31 | select "Test delimiter delimiter" as " ";
32 | delimiter delimiter
33 | select * from t1delimiter
34 | delimiter ;
35 | select 'End test delimiter';
36 |
37 | # Test delimiter @@
38 | select "Test delimiter @@" as " ";
39 | delimiter @@
40 | select * from t1 @@
41 | select * from t2@@
42 | alter table t add column c@@
43 | delimiter ;
44 | select 'End test @@';
45 |
46 | # Test delimiter \n\n
47 | select "Test delimiter \n\n" as " ";
48 | delimiter \n\n
49 | select * from t1
50 |
51 | select * from t2
52 |
53 | delimiter ;
54 | select 'End test \\n\\n';
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/13_delimiter_mysql_command.sql.golden:
--------------------------------------------------------------------------------
1 | select "Test delimiter :" as " ";
2 | -- end --
3 | select * from t1
4 | -- end --
5 | select 'End test :';
6 | -- end --
7 | select "Test delimiter :;" as " ";
8 | -- end --
9 | select * from t1
10 | -- end --
11 | select 'End test :;';
12 | -- end --
13 | select "Test delimiter //" as " ";
14 | -- end --
15 | select * from t1
16 | -- end --
17 | select 'End test //';
18 | -- end --
19 | select "Test delimiter MySQL" as " ";
20 | -- end --
21 | select * from t1
22 | -- end --
23 | select 'End test MySQL';
24 | -- end --
25 | select "Test delimiter delimiter" as " ";
26 | -- end --
27 | select * from t1
28 | -- end --
29 | select 'End test delimiter';
30 | -- end --
31 | select "Test delimiter @@" as " ";
32 | -- end --
33 | select * from t1
34 | -- end --
35 | select * from t2
36 | -- end --
37 | alter table t add column c
38 | -- end --
39 | select 'End test @@';
40 | -- end --
41 | select "Test delimiter \n\n" as " ";
42 | -- end --
43 | select * from t1
44 | -- end --
45 | select * from t2
46 | -- end --
47 | select 'End test \\n\\n';
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/14_delimiter_mysql_command.sql:
--------------------------------------------------------------------------------
1 | DELIMITER //
2 | CREATE PROCEDURE dorepeat(p1 INT)
3 | BEGIN
4 | SET @x = 0;
5 | REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
6 | END
7 | //
8 | DELIMITER ;
9 | CALL dorepeat(100)
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/14_delimiter_mysql_command.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE PROCEDURE dorepeat(p1 INT)
2 | BEGIN
3 | SET @x = 0;
4 | REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
5 | END
6 | -- end --
7 | CALL dorepeat(100)
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/16_begin_atomic.sql:
--------------------------------------------------------------------------------
1 | CREATE FUNCTION functest_S_1(a text, b date) RETURNS boolean
2 | LANGUAGE SQL
3 | RETURN a = 'abcd' AND b > '2001-01-01';
4 | CREATE FUNCTION functest_S_2(a text[]) RETURNS int
5 | RETURN a[1]::int;
6 | CREATE FUNCTION functest_S_3() RETURNS boolean
7 | RETURN false;
8 | CREATE FUNCTION functest_S_10(a text, b date) RETURNS boolean
9 | LANGUAGE SQL
10 | BEGIN ATOMIC
11 | SELECT a = 'abcd' AND b > '2001-01-01';
12 | END;
13 | CREATE FUNCTION functest_S_13() RETURNS boolean
14 | BEGIN ATOMIC
15 | SELECT 1;
16 | SELECT false;
17 | END;
18 | CREATE FUNCTION functest_S_15(x int) RETURNS boolean
19 | LANGUAGE SQL
20 | BEGIN ATOMIC
21 | select case when x % 2 = 0 then true else false end; -- tricky parsing
22 | END;
23 | CREATE FUNCTION functest_sri2() RETURNS SETOF int
24 | LANGUAGE SQL
25 | STABLE
26 | BEGIN ATOMIC
27 | SELECT * FROM functest3;
28 | END;
29 | CREATE TABLE functest1 (i int);
30 | CREATE FUNCTION functest_S_16(a int, b int) RETURNS void
31 | LANGUAGE SQL
32 | BEGIN ATOMIC
33 | INSERT INTO functest1 SELECT a + $2;
34 | END;
35 |
36 | CREATE FUNCTION functest_S_15(x int) RETURNS boolean
37 | LANGUAGE SQL
38 | BEGIN ATOMIC
39 | select case when x % 2 = 0 then true else false end;
40 | select case when x % 2 = 0 then true else false end;
41 | select case when x % 2 = 0 then true else false end;
42 | select case when x % 2 = 0 then true else false end;
43 | END;
44 |
45 | CREATE FUNCTION "functest_s_15" ("x" integer) RETURNS boolean LANGUAGE SQL BEGIN ATOMIC
46 | SELECT
47 | CASE
48 | WHEN ((x % 2) = 0) THEN true
49 | ELSE false
50 | END AS "case";
51 | END;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/16_begin_atomic.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE FUNCTION functest_S_1(a text, b date) RETURNS boolean
2 | LANGUAGE SQL
3 | RETURN a = 'abcd' AND b > '2001-01-01';
4 | -- end --
5 | CREATE FUNCTION functest_S_2(a text[]) RETURNS int
6 | RETURN a[1]::int;
7 | -- end --
8 | CREATE FUNCTION functest_S_3() RETURNS boolean
9 | RETURN false;
10 | -- end --
11 | CREATE FUNCTION functest_S_10(a text, b date) RETURNS boolean
12 | LANGUAGE SQL
13 | BEGIN ATOMIC
14 | SELECT a = 'abcd' AND b > '2001-01-01';
15 | END;
16 | -- end --
17 | CREATE FUNCTION functest_S_13() RETURNS boolean
18 | BEGIN ATOMIC
19 | SELECT 1;
20 | SELECT false;
21 | END;
22 | -- end --
23 | CREATE FUNCTION functest_S_15(x int) RETURNS boolean
24 | LANGUAGE SQL
25 | BEGIN ATOMIC
26 | select case when x % 2 = 0 then true else false end; -- tricky parsing
27 | END;
28 | -- end --
29 | CREATE FUNCTION functest_sri2() RETURNS SETOF int
30 | LANGUAGE SQL
31 | STABLE
32 | BEGIN ATOMIC
33 | SELECT * FROM functest3;
34 | END;
35 | -- end --
36 | CREATE TABLE functest1 (i int);
37 | -- end --
38 | CREATE FUNCTION functest_S_16(a int, b int) RETURNS void
39 | LANGUAGE SQL
40 | BEGIN ATOMIC
41 | INSERT INTO functest1 SELECT a + $2;
42 | END;
43 | -- end --
44 | CREATE FUNCTION functest_S_15(x int) RETURNS boolean
45 | LANGUAGE SQL
46 | BEGIN ATOMIC
47 | select case when x % 2 = 0 then true else false end;
48 | select case when x % 2 = 0 then true else false end;
49 | select case when x % 2 = 0 then true else false end;
50 | select case when x % 2 = 0 then true else false end;
51 | END;
52 | -- end --
53 | CREATE FUNCTION "functest_s_15" ("x" integer) RETURNS boolean LANGUAGE SQL BEGIN ATOMIC
54 | SELECT
55 | CASE
56 | WHEN ((x % 2) = 0) THEN true
57 | ELSE false
58 | END AS "case";
59 | END;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/17_paren.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE ONLY t ADD CONSTRAINT name1 EXCLUDE USING gist (id WITH =, cid WITH -|-);
2 | ALTER TABLE ONLY t
3 | ADD CONSTRAINT name2 EXCLUDE USING gist (id WITH =, cid WITH -|-);
4 | ALTER TABLE ONLY t
5 | ADD CONSTRAINT name3 EXCLUDE USING gist (id WITH =, cid WITH -|-),
6 | ADD CONSTRAINT name4 EXCLUDE USING gist (id WITH =, cid WITH -|-);
7 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/17_paren.sql.golden:
--------------------------------------------------------------------------------
1 | ALTER TABLE ONLY t ADD CONSTRAINT name1 EXCLUDE USING gist (id WITH =, cid WITH -|-);
2 | -- end --
3 | ALTER TABLE ONLY t
4 | ADD CONSTRAINT name2 EXCLUDE USING gist (id WITH =, cid WITH -|-);
5 | -- end --
6 | ALTER TABLE ONLY t
7 | ADD CONSTRAINT name3 EXCLUDE USING gist (id WITH =, cid WITH -|-),
8 | ADD CONSTRAINT name4 EXCLUDE USING gist (id WITH =, cid WITH -|-);
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/18_pg_expr.sql:
--------------------------------------------------------------------------------
1 | -- Comment 1.
2 | CREATE INDEX "i" ON "s"."t" (((c #>> '{a,b,c}'::text[])));
3 |
4 | /*
5 | Comment 2.
6 | */
7 | SELECT name
8 | FROM company.employees
9 | WHERE info #>> '{department, name}' = 'Engineering';
10 |
11 | /*
12 | SELECT name
13 | FROM company.employees
14 | WHERE info #>> '{contact, email}' = 'alice@company.com';
15 | */
16 | SELECT name
17 | FROM company.employees
18 | WHERE info #>> '{contact, email}' = 'alice@company.com';
19 |
20 | -- Comment 3.
21 | CREATE INDEX "idx_emp_department" ON "company"."employees" (
22 | (info #>> '{department, name}')
23 | );
24 |
25 | /*
26 |
27 | CREATE INDEX "idx_emp_contact" ON "company"."employees" (
28 | LOWER(info #>> '{contact, email}')
29 | );
30 | */
31 | CREATE INDEX "idx_emp_contact" ON "company"."employees" (
32 | LOWER(info #>> '{contact, email}')
33 | );
34 |
35 | /**
36 | SELECT
37 | info #>> '{department, name}' AS department,
38 | COUNT(*) AS emp_count
39 | FROM company.employees
40 | GROUP BY info #>> '{department, name}';
41 | */
42 | SELECT
43 | info #>> '{department, name}' AS department,
44 | COUNT(*) AS emp_count
45 | FROM company.employees
46 | GROUP BY info #>> '{department, name}';
47 |
48 | /**
49 | SELECT
50 | info #>> '{department, name}' AS department,
51 | COUNT(*) AS emp_count
52 | FROM company.employees
53 | GROUP BY info #>> '{department, name}';
54 | */
55 | /**
56 | SELECT
57 | info #>> '{department, name}' AS department,
58 | COUNT(*) AS emp_count
59 | FROM company.employees
60 | GROUP BY info #>> '{department, name}';
61 | */
62 | SELECT name
63 | FROM company.employees
64 | WHERE (info #>> '{department, name}' = 'Engineering'
65 | OR info #>> '{department, location}' = 'Building A')
66 | AND info #>> '{contact, email}' LIKE '%@company.com';
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/18_pg_expr.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE INDEX "i" ON "s"."t" (((c #>> '{a,b,c}'::text[])));
2 | -- end --
3 | SELECT name
4 | FROM company.employees
5 | WHERE info #>> '{department, name}' = 'Engineering';
6 | -- end --
7 | SELECT name
8 | FROM company.employees
9 | WHERE info #>> '{contact, email}' = 'alice@company.com';
10 | -- end --
11 | CREATE INDEX "idx_emp_department" ON "company"."employees" (
12 | (info #>> '{department, name}')
13 | );
14 | -- end --
15 | CREATE INDEX "idx_emp_contact" ON "company"."employees" (
16 | LOWER(info #>> '{contact, email}')
17 | );
18 | -- end --
19 | SELECT
20 | info #>> '{department, name}' AS department,
21 | COUNT(*) AS emp_count
22 | FROM company.employees
23 | GROUP BY info #>> '{department, name}';
24 | -- end --
25 | SELECT name
26 | FROM company.employees
27 | WHERE (info #>> '{department, name}' = 'Engineering'
28 | OR info #>> '{department, location}' = 'Building A')
29 | AND info #>> '{contact, email}' LIKE '%@company.com';
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/19_ms_gocmd.sql:
--------------------------------------------------------------------------------
1 | go
2 | SELECT 1
3 | -- comment here
4 | GO
5 | SELECT 2 -- another comment
6 | GO
7 | SELECT 3 GO
8 | GO
9 | SELECT 4
10 | GOTO
11 | SELECT 5
12 | GO 11
13 | SELECT 6
14 | GO
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/19_ms_gocmd.sql.golden:
--------------------------------------------------------------------------------
1 |
2 | -- end --
3 | SELECT 1
4 | -- comment here
5 | -- end --
6 | SELECT 2 -- another comment
7 | -- end --
8 | SELECT 3 GO
9 | -- end --
10 | SELECT 4
11 | GOTO
12 | SELECT 5
13 | -- end --
14 | SELECT 6
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/20_ms_go-delim.sql:
--------------------------------------------------------------------------------
1 | -- atlas:delimiter \nGO
2 |
3 | go
4 | SELECT 1
5 | -- comment here
6 | GO
7 | SELECT 2 -- another comment
8 | GO
9 | SELECT 3 GO
10 | gO
11 | SELECT 4
12 | GOTO -- this command is truncated by delimiter
13 | SELECT 5
14 | GO 11
15 | SELECT 6
16 | GO
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/20_ms_go-delim.sql.golden:
--------------------------------------------------------------------------------
1 |
2 | -- end --
3 | SELECT 1
4 | -- comment here
5 | -- end --
6 | SELECT 2 -- another comment
7 | -- end --
8 | SELECT 3 GO
9 | -- end --
10 | SELECT 4
11 | -- end --
12 | TO -- this command is truncated by delimiter
13 | SELECT 5
14 | -- end --
15 | SELECT 6
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/2_mysql.sql:
--------------------------------------------------------------------------------
1 | create table t1 (b char(0));
2 | create table t1 (b char(0) not null);
3 | create table if not exists t1 (b char(0) not null);
4 | create table t2 engine=heap select * from t1;
5 | create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) engine=heap;
6 | create table mysqltest.$test1 (a$1 int, $b int, c$ int);
7 | create table t2 (b int) select a as b, a+1 as b from t1;
8 | create table t1 select if('2002'='2002','Y','N');
9 | create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2));
10 | insert into t1 values ("a", 1), ("b", 2);
11 | create table t2
12 | select
13 | a,
14 | ifnull(b,cast(-7 as signed)) as b,
15 | ifnull(c,cast(7 as unsigned)) as c,
16 | ifnull(d,cast('2000-01-01' as date)) as d,
17 | ifnull(e,cast('b' as char)) as e,
18 | ifnull(f,cast('2000-01-01' as datetime)) as f,
19 | ifnull(g,cast('5:4:3' as time)) as g,
20 | ifnull(h,cast('yet another binary data' as binary)) as h,
21 | addtime(cast('1:0:0' as time),cast('1:0:0' as time)) as dd
22 | from t1;
23 | CREATE TABLE t1(id varchar(10) NOT NULL PRIMARY KEY, dsc longtext);
24 | INSERT INTO t1 VALUES ('5000000001', NULL),('5000000003', 'Test'),('5000000004', NULL);
25 | create table t1 (
26 | a varchar(112) charset utf8 collate utf8_bin not null,
27 | primary key (a)
28 | ) select 'test' as a ;
29 | create table טבלה_של_אריאל
30 | (
31 | כמות int
32 | );
33 |
34 |
35 |
36 | CREATE TABLE t1(
37 | c1 INT DEFAULT 12 COMMENT 'column1',
38 | c2 INT NULL COMMENT 'column2',
39 | c3 INT NOT NULL COMMENT 'column3',
40 | c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
41 | c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b',
42 | c6 VARCHAR(255))
43 | COLLATE latin1_bin;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/2_mysql.sql.golden:
--------------------------------------------------------------------------------
1 | create table t1 (b char(0));
2 | -- end --
3 | create table t1 (b char(0) not null);
4 | -- end --
5 | create table if not exists t1 (b char(0) not null);
6 | -- end --
7 | create table t2 engine=heap select * from t1;
8 | -- end --
9 | create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) engine=heap;
10 | -- end --
11 | create table mysqltest.$test1 (a$1 int, $b int, c$ int);
12 | -- end --
13 | create table t2 (b int) select a as b, a+1 as b from t1;
14 | -- end --
15 | create table t1 select if('2002'='2002','Y','N');
16 | -- end --
17 | create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2));
18 | -- end --
19 | insert into t1 values ("a", 1), ("b", 2);
20 | -- end --
21 | create table t2
22 | select
23 | a,
24 | ifnull(b,cast(-7 as signed)) as b,
25 | ifnull(c,cast(7 as unsigned)) as c,
26 | ifnull(d,cast('2000-01-01' as date)) as d,
27 | ifnull(e,cast('b' as char)) as e,
28 | ifnull(f,cast('2000-01-01' as datetime)) as f,
29 | ifnull(g,cast('5:4:3' as time)) as g,
30 | ifnull(h,cast('yet another binary data' as binary)) as h,
31 | addtime(cast('1:0:0' as time),cast('1:0:0' as time)) as dd
32 | from t1;
33 | -- end --
34 | CREATE TABLE t1(id varchar(10) NOT NULL PRIMARY KEY, dsc longtext);
35 | -- end --
36 | INSERT INTO t1 VALUES ('5000000001', NULL),('5000000003', 'Test'),('5000000004', NULL);
37 | -- end --
38 | create table t1 (
39 | a varchar(112) charset utf8 collate utf8_bin not null,
40 | primary key (a)
41 | ) select 'test' as a ;
42 | -- end --
43 | create table טבלה_של_אריאל
44 | (
45 | כמות int
46 | );
47 | -- end --
48 | CREATE TABLE t1(
49 | c1 INT DEFAULT 12 COMMENT 'column1',
50 | c2 INT NULL COMMENT 'column2',
51 | c3 INT NOT NULL COMMENT 'column3',
52 | c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a',
53 | c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b',
54 | c6 VARCHAR(255))
55 | COLLATE latin1_bin;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/3_delimiter.sql:
--------------------------------------------------------------------------------
1 | -- atlas:delimiter \n\n
2 |
3 | CREATE INDEX i1 ON t1(c1)
4 |
5 | CREATE INDEX i2 ON t2(c2)
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/3_delimiter.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE INDEX i1 ON t1(c1)
2 | -- end --
3 | CREATE INDEX i2 ON t2(c2)
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/4_delimiter.sql:
--------------------------------------------------------------------------------
1 | -- atlas:delimiter \n---\n
2 |
3 | CREATE INDEX i1 ON t1(c1)
4 | ---
5 | CREATE INDEX i2 ON t2(c2)
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/4_delimiter.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE INDEX i1 ON t1(c1)
2 | -- end --
3 | CREATE INDEX i2 ON t2(c2)
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/5_delimiter.sql:
--------------------------------------------------------------------------------
1 | -- atlas:delimiter \n-- end --\n
2 |
3 | CREATE DEFINER='boring' PROCEDURE proc ()
4 | COMMENT 'ATLAS_DELIMITER'
5 | SQL SECURITY INVOKER
6 | NOT DETERMINISTIC
7 | MODIFIES SQL DATA
8 | BEGIN
9 | UPDATE performance_schema.threads
10 | SET instrumented = 'YES'
11 | WHERE type = 'BACKGROUND';
12 |
13 | SELECT CONCAT('Enabled ', @rows := ROW_COUNT(), ' background thread', IF(@rows != 1, 's', '')) AS summary;
14 | END
15 |
16 | -- end --
17 |
18 | CALL proc();
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/5_delimiter.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE DEFINER='boring' PROCEDURE proc ()
2 | COMMENT 'ATLAS_DELIMITER'
3 | SQL SECURITY INVOKER
4 | NOT DETERMINISTIC
5 | MODIFIES SQL DATA
6 | BEGIN
7 | UPDATE performance_schema.threads
8 | SET instrumented = 'YES'
9 | WHERE type = 'BACKGROUND';
10 |
11 | SELECT CONCAT('Enabled ', @rows := ROW_COUNT(), ' background thread', IF(@rows != 1, 's', '')) AS summary;
12 | END
13 | -- end --
14 | CALL proc();
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/6_skip_comment.sql:
--------------------------------------------------------------------------------
1 | -- comment 1
2 | CREATE TABLE t1(id int);
3 | # CREATE TABLE t1(id int);
4 |
5 | -- comment 2
6 | # CREATE TABLE t2(id int);
7 | CREATE TABLE t2(id int);
8 | -- comment 3
9 | CREATE TABLE t3(id int);
10 |
11 | # CREATE TABLE t3(id int);
12 |
13 | /* comment 4 */
14 | CREATE TABLE t4(
15 | id int
16 | /* comment */
17 | -- comment
18 | ) ENGINE=InnoDB;
19 |
20 | /* comment 5
21 | */
22 | CREATE TABLE t5(
23 | id int
24 | /* comment */
25 | -- comment
26 | ) ENGINE=InnoDB;
27 |
28 | SELECT * FROM (
29 | SELECT * FROM t1 # comment
30 | );
31 |
32 | # This is a statement's comment.
33 | SELECT * FROM t2;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/6_skip_comment.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE TABLE t1(id int);
2 | -- end --
3 | CREATE TABLE t2(id int);
4 | -- end --
5 | CREATE TABLE t3(id int);
6 | -- end --
7 | CREATE TABLE t4(
8 | id int
9 | /* comment */
10 | -- comment
11 | ) ENGINE=InnoDB;
12 | -- end --
13 | CREATE TABLE t5(
14 | id int
15 | /* comment */
16 | -- comment
17 | ) ENGINE=InnoDB;
18 | -- end --
19 | SELECT * FROM (
20 | SELECT * FROM t1 # comment
21 | );
22 | -- end --
23 | SELECT * FROM t2;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/7_delimiter_2n.sql:
--------------------------------------------------------------------------------
1 | -- atlas:delimiter \n\n
2 |
3 | CREATE EXTENSION IF NOT EXISTS unaccent;
4 |
5 | CREATE OR REPLACE FUNCTION public.slugify(
6 | v TEXT
7 | ) RETURNS TEXT STRICT IMMUTABLE AS $$
8 | BEGIN
9 | RETURN trim(BOTH '-' FROM regexp_replace(lower(unaccent(trim(v))), '[^a-z0-9\\-_]+', '-', 'gi'));
10 | END;
11 | LANGUAGE plpgsql;
12 |
13 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/7_delimiter_2n.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE EXTENSION IF NOT EXISTS unaccent;
2 | -- end --
3 | CREATE OR REPLACE FUNCTION public.slugify(
4 | v TEXT
5 | ) RETURNS TEXT STRICT IMMUTABLE AS $$
6 | BEGIN
7 | RETURN trim(BOTH '-' FROM regexp_replace(lower(unaccent(trim(v))), '[^a-z0-9\\-_]+', '-', 'gi'));
8 | END;
9 | LANGUAGE plpgsql;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/8_delimiter_3n.sql:
--------------------------------------------------------------------------------
1 | -- atlas:delimiter \n\n\n
2 |
3 | CREATE EXTENSION IF NOT EXISTS unaccent;
4 |
5 |
6 | CREATE OR REPLACE FUNCTION public.slugify(
7 | v TEXT
8 | ) RETURNS TEXT STRICT IMMUTABLE AS $$
9 | BEGIN
10 | RETURN trim(BOTH '-' FROM regexp_replace(lower(unaccent(trim(v))), '[^a-z0-9\\-_]+', '-', 'gi'));
11 | END;
12 | LANGUAGE plpgsql;
13 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/8_delimiter_3n.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE EXTENSION IF NOT EXISTS unaccent;
2 | -- end --
3 | CREATE OR REPLACE FUNCTION public.slugify(
4 | v TEXT
5 | ) RETURNS TEXT STRICT IMMUTABLE AS $$
6 | BEGIN
7 | RETURN trim(BOTH '-' FROM regexp_replace(lower(unaccent(trim(v))), '[^a-z0-9\\-_]+', '-', 'gi'));
8 | END;
9 | LANGUAGE plpgsql;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/9_delimiter_3n.sql:
--------------------------------------------------------------------------------
1 | -- atlas:delimiter \n\n\n
2 |
3 | CREATE PROCEDURE dorepeat(p1 INT)
4 | BEGIN
5 | SET @x = 0;
6 | REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
7 | END;
8 |
9 |
10 | CALL dorepeat(1000);
11 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/lex/9_delimiter_3n.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE PROCEDURE dorepeat(p1 INT)
2 | BEGIN
3 | SET @x = 0;
4 | REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
5 | END;
6 | -- end --
7 | CALL dorepeat(1000);
--------------------------------------------------------------------------------
/sql/migrate/testdata/lexescaped/1.my.sql:
--------------------------------------------------------------------------------
1 | create table t (c text default '\\');
2 | create table t (c text default "\\");
3 | create table t (c text default "\"");
4 | create table t (c text default "\"" + '\'');
5 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/lexescaped/1.my.sql.golden:
--------------------------------------------------------------------------------
1 | create table t (c text default '\\');
2 | -- end --
3 | create table t (c text default "\\");
4 | -- end --
5 | create table t (c text default "\"");
6 | -- end --
7 | create table t (c text default "\"" + '\'');
--------------------------------------------------------------------------------
/sql/migrate/testdata/lexescaped/2.pg.sql:
--------------------------------------------------------------------------------
1 | create table t1 (c text default '\');
2 | create table t1 (c text default E'\\');
3 | create table t1 (c text default '\A\');
4 | create table t1 (c text default e'\\A\\');
--------------------------------------------------------------------------------
/sql/migrate/testdata/lexescaped/2.pg.sql.golden:
--------------------------------------------------------------------------------
1 | create table t1 (c text default '\');
2 | -- end --
3 | create table t1 (c text default E'\\');
4 | -- end --
5 | create table t1 (c text default '\A\');
6 | -- end --
7 | create table t1 (c text default e'\\A\\');
--------------------------------------------------------------------------------
/sql/migrate/testdata/lexgroup/3_delimiter.sql:
--------------------------------------------------------------------------------
1 | -- delimiter should not conflict with compound statements scanning.
2 |
3 | create function `add2` (a int, b int) returns int deterministic no sql return a + b;
4 | create function `add3` (a int, b int, c int) returns int deterministic no sql return a + b + c;
5 | delimiter |
6 | -- error 1418
7 | create function fn1(x int) returns int deterministic
8 | begin
9 | insert into t1 values (x);
10 | return x+2;
11 | end|
12 | create function fn2(x int) returns int deterministic
13 | begin
14 | insert into t1 values (x);
15 | return x+2;
16 | end|
17 | delimiter ;
18 | create function `add4` (a int, b int, c int, d int) returns int deterministic no sql return a + b + c + d;
--------------------------------------------------------------------------------
/sql/migrate/testdata/lexgroup/3_delimiter.sql.golden:
--------------------------------------------------------------------------------
1 | create function `add2` (a int, b int) returns int deterministic no sql return a + b;
2 | -- end --
3 | create function `add3` (a int, b int, c int) returns int deterministic no sql return a + b + c;
4 | -- end --
5 | create function fn1(x int) returns int deterministic
6 | begin
7 | insert into t1 values (x);
8 | return x+2;
9 | end
10 | -- end --
11 | create function fn2(x int) returns int deterministic
12 | begin
13 | insert into t1 values (x);
14 | return x+2;
15 | end
16 | -- end --
17 | create function `add4` (a int, b int, c int, d int) returns int deterministic no sql return a + b + c + d;
--------------------------------------------------------------------------------
/sql/migrate/testdata/migrate/1_initial.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS t;
--------------------------------------------------------------------------------
/sql/migrate/testdata/migrate/1_initial.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE t(c int);
--------------------------------------------------------------------------------
/sql/migrate/testdata/migrate/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:M74RrNK69S2pj6C541LR1ew5O32/i0WoyNgsJmyuiUk=
2 | 1_initial.down.sql h1:0zypK43rgPbgvVUgVJABGN25VgM1QSeU+LJDBb8cEQI=
3 | 1_initial.up.sql h1:hFhs5XhRml4KTWGF5td6h1s7xNqAFnaEBbC5Y/NF7i4=
4 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/migrate/sub/1.a_sub.up.sql:
--------------------------------------------------------------------------------
1 | -- create table "t_sub"
2 | CREATE TABLE t_sub(c int);
3 | -- add c1 column
4 | ALTER TABLE t_sub ADD c1 int;
--------------------------------------------------------------------------------
/sql/migrate/testdata/migrate/sub/2.10.x-20_description.sql:
--------------------------------------------------------------------------------
1 | -- add c2 column
2 | ALTER TABLE t_sub ADD c2 int;
--------------------------------------------------------------------------------
/sql/migrate/testdata/migrate/sub/3_partly.sql:
--------------------------------------------------------------------------------
1 | -- add c3 column
2 | ALTER TABLE t_sub ADD c3 int;
3 | -- add c4 column
4 | ALTER TABLE t_sub ADD c4 int;
--------------------------------------------------------------------------------
/sql/migrate/testdata/migrate/sub/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:VpH77zWOBMwX5QhvnQo0XQvXCrOYZg4h1o0XlJTQnl0=
2 | 1.a_sub.up.sql h1:nXyZR020M/mH7LxkoTkJr7BcQkipVg90imQ9I4595dw=
3 | 2.10.x-20_description.sql h1:wQB3Vh3PHVXQg9OD3Gn7TBxbZN3r1Qb7TtAE1g3q9mQ=
4 | 3_partly.sql h1:lHlMz6mEvBfvjry5lFXjs2vi6Et9xb9CWicaOXD42Qc=
5 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/partial-checkpoint/1_first.sql:
--------------------------------------------------------------------------------
1 | create table `tbl_1` (`col` int);
2 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/partial-checkpoint/2_second.sql:
--------------------------------------------------------------------------------
1 | create table `tbl_2` (`col` int);
2 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/partial-checkpoint/3_checkpoint.sql:
--------------------------------------------------------------------------------
1 | -- atlas:checkpoint
2 |
3 | CREATE TABLE `tbl_1` (`col` int);
4 | CREATE TABLE `tbl_2` (`col` int);
5 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/partial-checkpoint/4_fourth.sql:
--------------------------------------------------------------------------------
1 | create table `tbl_3` (`col` int);
2 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/partial-checkpoint/5_checkpoint.sql:
--------------------------------------------------------------------------------
1 | -- atlas:checkpoint
2 |
3 | CREATE TABLE `tbl_1` (`col` int);
4 | CREATE TABLE `tbl_2` (`col` int);
5 | create table `tbl_3` (`col` int);
6 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/partial-checkpoint/6_sixth.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `tbl_4` (`col` int);
2 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/partial-checkpoint/atlas.sum:
--------------------------------------------------------------------------------
1 | h1:POfbsH2G2GIXAZQ2CdPa5ufTxcLpcnperz/gX0Vw6Uk=
2 | 1_first.sql h1:uJ2MyyeTqXx4rCqtRMQAvRrfsvdwmvsZ3LcadVvCdOc=
3 | 2_second.sql h1:TLO00GtsqSi8o0ySoaofBqxemrElL8fHOs3IRnqYvB8=
4 | 3_checkpoint.sql h1:LR4UjDYVtrRuHLN5GQwLAYnXrSf/iO70psY8hTmLmjw=
5 | 4_fourth.sql h1:QvaneqKxg+3R+zNzCP/wW43XkECdHkUwEpxJKPICEP8=
6 | 5_checkpoint.sql h1:syyuaJb/hoMRO7MJlv4AMhYqMCoSb8ZgcHENO8RqN3I=
7 | 6_sixth.sql h1:JNhpyBtH7XKqGBNRHQ+AvM9IDpO08C3G/swWPHfLkfw=
8 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/sqlserver/1_return_table.sql:
--------------------------------------------------------------------------------
1 | CREATE FUNCTION [f2](@a as INT, @b as INT = 1)
2 | RETURNS TABLE
3 | AS RETURN SELECT @a as [a], @b as [b], (@a+@b)*2 as [p], @a*@b as [s];
4 | CREATE FUNCTION [f3] (@a int, @b int = 1) RETURNS @t1 TABLE ([c1] int NOT NULL, [c2] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [c3] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS DEFAULT N'G' NULL, [c4] int NOT NULL, PRIMARY KEY CLUSTERED ([c1] ASC), INDEX [idx] NONCLUSTERED ([c2] ASC), UNIQUE NONCLUSTERED ([c2] ASC, [c3] DESC), UNIQUE NONCLUSTERED ([c3] DESC, [c4] ASC), CHECK ([c4]>(0))) AS BEGIN
5 | INSERT @t1
6 | SELECT 1 AS [c1], 'A' AS [c2], NULL AS [c3], @a * @a + @b AS [c4];
7 | RETURN
8 | END
9 |
--------------------------------------------------------------------------------
/sql/migrate/testdata/sqlserver/1_return_table.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE FUNCTION [f2](@a as INT, @b as INT = 1)
2 | RETURNS TABLE
3 | AS RETURN SELECT @a as [a], @b as [b], (@a+@b)*2 as [p], @a*@b as [s];
4 | -- end --
5 | CREATE FUNCTION [f3] (@a int, @b int = 1) RETURNS @t1 TABLE ([c1] int NOT NULL, [c2] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [c3] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS DEFAULT N'G' NULL, [c4] int NOT NULL, PRIMARY KEY CLUSTERED ([c1] ASC), INDEX [idx] NONCLUSTERED ([c2] ASC), UNIQUE NONCLUSTERED ([c2] ASC, [c3] DESC), UNIQUE NONCLUSTERED ([c3] DESC, [c4] ASC), CHECK ([c4]>(0))) AS BEGIN
6 | INSERT @t1
7 | SELECT 1 AS [c1], 'A' AS [c2], NULL AS [c3], @a * @a + @b AS [c4];
8 | RETURN
9 | END
--------------------------------------------------------------------------------
/sql/migrate/testdata/sqlserver/2_function.sql:
--------------------------------------------------------------------------------
1 | -- atlas:delimiter \nGO
2 |
3 | CREATE FUNCTION [f3] (@a int, @b int = 1) RETURNS @t1 TABLE ([c1] int NOT NULL, [c2] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [c3] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS DEFAULT N'G' NULL, [c4] int NOT NULL, PRIMARY KEY CLUSTERED ([c1] ASC), INDEX [idx] NONCLUSTERED ([c2] ASC), UNIQUE NONCLUSTERED ([c2] ASC, [c3] DESC), UNIQUE NONCLUSTERED ([c3] DESC, [c4] ASC), CHECK ([c4]>(0))) AS BEGIN
4 | INSERT @t1
5 | SELECT 1 AS [c1], 'A' AS [c2], NULL AS [c3], @a * @a + @b AS [c4];
6 | RETURN
7 | END
8 | GO
9 | CREATE FUNCTION [f3] (@a int, @b int = 1) RETURNS @t1 TABLE ([c1] int NOT NULL, [c2] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [c3] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS DEFAULT N'G' NULL, [c4] int NOT NULL, PRIMARY KEY CLUSTERED ([c1] ASC), INDEX [idx] NONCLUSTERED ([c2] ASC), UNIQUE NONCLUSTERED ([c2] ASC, [c3] DESC), UNIQUE NONCLUSTERED ([c3] DESC, [c4] ASC), CHECK ([c4]>(0))) AS BEGIN
10 | INSERT @t1
11 | SELECT 1 AS [c1], 'A' AS [c2], NULL AS [c3], @a * @a + @b AS [c4];
12 | RETURN
13 | END
14 | GO
15 | CREATE FUNCTION [f3] (@a int, @b int = 1) RETURNS @t1 TABLE ([c1] int NOT NULL, [c2] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [c3] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS DEFAULT N'G' NULL, [c4] int NOT NULL, PRIMARY KEY CLUSTERED ([c1] ASC), INDEX [idx] NONCLUSTERED ([c2] ASC), UNIQUE NONCLUSTERED ([c2] ASC, [c3] DESC), UNIQUE NONCLUSTERED ([c3] DESC, [c4] ASC), CHECK ([c4]>(0))) AS BEGIN
16 | INSERT @t1
17 | SELECT 1 AS [c1], 'A' AS [c2], NULL AS [c3], @a * @a + @b AS [c4];
18 | RETURN
19 | END
--------------------------------------------------------------------------------
/sql/migrate/testdata/sqlserver/2_function.sql.golden:
--------------------------------------------------------------------------------
1 | CREATE FUNCTION [f3] (@a int, @b int = 1) RETURNS @t1 TABLE ([c1] int NOT NULL, [c2] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [c3] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS DEFAULT N'G' NULL, [c4] int NOT NULL, PRIMARY KEY CLUSTERED ([c1] ASC), INDEX [idx] NONCLUSTERED ([c2] ASC), UNIQUE NONCLUSTERED ([c2] ASC, [c3] DESC), UNIQUE NONCLUSTERED ([c3] DESC, [c4] ASC), CHECK ([c4]>(0))) AS BEGIN
2 | INSERT @t1
3 | SELECT 1 AS [c1], 'A' AS [c2], NULL AS [c3], @a * @a + @b AS [c4];
4 | RETURN
5 | END
6 | -- end --
7 | CREATE FUNCTION [f3] (@a int, @b int = 1) RETURNS @t1 TABLE ([c1] int NOT NULL, [c2] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [c3] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS DEFAULT N'G' NULL, [c4] int NOT NULL, PRIMARY KEY CLUSTERED ([c1] ASC), INDEX [idx] NONCLUSTERED ([c2] ASC), UNIQUE NONCLUSTERED ([c2] ASC, [c3] DESC), UNIQUE NONCLUSTERED ([c3] DESC, [c4] ASC), CHECK ([c4]>(0))) AS BEGIN
8 | INSERT @t1
9 | SELECT 1 AS [c1], 'A' AS [c2], NULL AS [c3], @a * @a + @b AS [c4];
10 | RETURN
11 | END
12 | -- end --
13 | CREATE FUNCTION [f3] (@a int, @b int = 1) RETURNS @t1 TABLE ([c1] int NOT NULL, [c2] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [c3] nvarchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS DEFAULT N'G' NULL, [c4] int NOT NULL, PRIMARY KEY CLUSTERED ([c1] ASC), INDEX [idx] NONCLUSTERED ([c2] ASC), UNIQUE NONCLUSTERED ([c2] ASC, [c3] DESC), UNIQUE NONCLUSTERED ([c3] DESC, [c4] ASC), CHECK ([c4]>(0))) AS BEGIN
14 | INSERT @t1
15 | SELECT 1 AS [c1], 'A' AS [c2], NULL AS [c3], @a * @a + @b AS [c4];
16 | RETURN
17 | END
--------------------------------------------------------------------------------
/sql/mysql/internal/mysqlversion/is/.README.md:
--------------------------------------------------------------------------------
1 | ## Charset and Collation of MySQL and MariaDB latest versions
2 |
3 | `collate2charset` and `collate2charset.maria` hold a mapping from the collation to their charset.
4 |
5 | ```sql
6 | select json_objectagg(collation_name, character_set_name) from information_schema.collations\G;
7 | ```
8 |
9 | `charset2collate` and `charset2collate.maria` hold a mapping from the charset to its default collation extracted
10 | by the following query:
11 |
12 | ```sql
13 | select json_objectagg(character_set_name, default_collate_name) from information_schema.character_sets\G;
14 | ```
--------------------------------------------------------------------------------
/sql/mysql/internal/mysqlversion/is/charset2collate:
--------------------------------------------------------------------------------
1 | {"gbk": "gbk_chinese_ci", "hp8": "hp8_english_ci", "big5": "big5_chinese_ci", "dec8": "dec8_swedish_ci", "sjis": "sjis_japanese_ci", "swe7": "swe7_swedish_ci", "ucs2": "ucs2_general_ci", "ujis": "ujis_japanese_ci", "ascii": "ascii_general_ci", "cp850": "cp850_general_ci", "cp852": "cp852_general_ci", "cp866": "cp866_general_ci", "cp932": "cp932_japanese_ci", "euckr": "euckr_korean_ci", "greek": "greek_general_ci", "koi8r": "koi8r_general_ci", "koi8u": "koi8u_general_ci", "macce": "macce_general_ci", "utf16": "utf16_general_ci", "utf32": "utf32_general_ci", "binary": "binary", "cp1250": "cp1250_general_ci", "cp1251": "cp1251_general_ci", "cp1256": "cp1256_general_ci", "cp1257": "cp1257_general_ci", "gb2312": "gb2312_chinese_ci", "hebrew": "hebrew_general_ci", "latin1": "latin1_swedish_ci", "latin2": "latin2_general_ci", "latin5": "latin5_turkish_ci", "latin7": "latin7_general_ci", "tis620": "tis620_thai_ci", "eucjpms": "eucjpms_japanese_ci", "gb18030": "gb18030_chinese_ci", "geostd8": "geostd8_general_ci", "keybcs2": "keybcs2_general_ci", "utf16le": "utf16le_general_ci", "utf8mb3": "utf8mb3_general_ci", "utf8mb4": "utf8mb4_0900_ai_ci", "armscii8": "armscii8_general_ci", "macroman": "macroman_general_ci","utf8": "utf8_general_ci"}
--------------------------------------------------------------------------------
/sql/mysql/internal/mysqlversion/is/charset2collate.maria:
--------------------------------------------------------------------------------
1 | {"big5":"big5_chinese_ci", "dec8":"dec8_swedish_ci", "cp850":"cp850_general_ci", "hp8":"hp8_english_ci", "koi8r":"koi8r_general_ci", "latin1":"latin1_swedish_ci", "latin2":"latin2_general_ci", "swe7":"swe7_swedish_ci", "ascii":"ascii_general_ci", "ujis":"ujis_japanese_ci", "sjis":"sjis_japanese_ci", "hebrew":"hebrew_general_ci", "tis620":"tis620_thai_ci", "euckr":"euckr_korean_ci", "koi8u":"koi8u_general_ci", "gb2312":"gb2312_chinese_ci", "greek":"greek_general_ci", "cp1250":"cp1250_general_ci", "gbk":"gbk_chinese_ci", "latin5":"latin5_turkish_ci", "armscii8":"armscii8_general_ci", "utf8mb3":"utf8mb3_general_ci", "ucs2":"ucs2_general_ci", "cp866":"cp866_general_ci", "keybcs2":"keybcs2_general_ci", "macce":"macce_general_ci", "macroman":"macroman_general_ci", "cp852":"cp852_general_ci", "latin7":"latin7_general_ci", "utf8mb4":"utf8mb4_general_ci", "cp1251":"cp1251_general_ci", "utf16":"utf16_general_ci", "utf16le":"utf16le_general_ci", "cp1256":"cp1256_general_ci", "cp1257":"cp1257_general_ci", "utf32":"utf32_general_ci", "binary":"binary", "geostd8":"geostd8_general_ci", "cp932":"cp932_japanese_ci", "eucjpms":"eucjpms_japanese_ci"}
--------------------------------------------------------------------------------
/sql/mysql/internal/mysqlversion/mysqlversion_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | package mysqlversion_test
6 |
7 | import (
8 | "testing"
9 |
10 | "ariga.io/atlas/sql/mysql/internal/mysqlversion"
11 | "github.com/DATA-DOG/go-sqlmock"
12 | "github.com/stretchr/testify/require"
13 | )
14 |
15 | func TestV_SupportsGeneratedColumns(t *testing.T) {
16 | tests := []struct {
17 | v string
18 | want bool
19 | }{
20 | {"5.6", false},
21 | {"5.7", true},
22 | {"5.7.0", true},
23 | {"5.7.40-0ubuntu0.18.04.1", true},
24 | {"8.0.0", true},
25 | {"10.1.1-MariaDB", false},
26 | {"10.2.1-MariaDB-10.2.1+maria~bionic", true},
27 | {"10.3.1-MariaDB-10.2.1+maria~bionic-log", true},
28 | }
29 | for _, tt := range tests {
30 | t.Run(tt.v, func(t *testing.T) {
31 | if got := mysqlversion.V(tt.v).SupportsGeneratedColumns(); got != tt.want {
32 | t.Errorf("V.SupportsGeneratedColumns() = %v, want %v", got, tt.want)
33 | }
34 | })
35 | }
36 | }
37 |
38 | func TestV_CollateToCharset(t *testing.T) {
39 | c2c, err := mysqlversion.V("8.0.0").CollateToCharset(nil)
40 | require.NoError(t, err)
41 | require.Equal(t, "utf8mb4", c2c["utf8mb4_general_ci"])
42 | require.Empty(t, c2c["custom"])
43 |
44 | db, mk, err := sqlmock.New()
45 | require.NoError(t, err)
46 | mk.ExpectQuery("SELECT COLLATION_NAME, CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS").
47 | WillReturnRows(sqlmock.NewRows([]string{"COLLATION_NAME", "CHARACTER_SET_NAME"}).AddRow("custom", "unknown"))
48 | c2c, err = mysqlversion.V("8.0.0").CollateToCharset(db)
49 | require.NoError(t, err)
50 | require.Equal(t, "unknown", c2c["custom"])
51 | }
52 |
--------------------------------------------------------------------------------
/sql/mysql/mysqlcheck/mysqlcheck_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package mysqlcheck
8 |
9 | import (
10 | "ariga.io/atlas/sql/mysql"
11 | "ariga.io/atlas/sql/sqlcheck"
12 | )
13 |
14 | func init() {
15 | sqlcheck.Register(mysql.DriverName, analyzers)
16 | }
17 |
--------------------------------------------------------------------------------
/sql/postgres/postgrescheck/postgrescheck.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | package postgrescheck
6 |
7 | import (
8 | "fmt"
9 |
10 | "ariga.io/atlas/schemahcl"
11 | "ariga.io/atlas/sql/postgres"
12 | "ariga.io/atlas/sql/sqlcheck"
13 | "ariga.io/atlas/sql/sqlcheck/condrop"
14 | "ariga.io/atlas/sql/sqlcheck/datadepend"
15 | "ariga.io/atlas/sql/sqlcheck/destructive"
16 | "ariga.io/atlas/sql/sqlcheck/incompatible"
17 | )
18 |
19 | func addNotNull(p *datadepend.ColumnPass) (diags []sqlcheck.Diagnostic, err error) {
20 | tt, err := postgres.FormatType(p.Column.Type.Type)
21 | if err != nil {
22 | return nil, err
23 | }
24 | return []sqlcheck.Diagnostic{
25 | {
26 | Pos: p.Change.Stmt.Pos,
27 | Text: fmt.Sprintf(
28 | "Adding a non-nullable %q column %q will fail in case table %q is not empty",
29 | tt, p.Column.Name, p.Table.Name,
30 | ),
31 | },
32 | }, nil
33 | }
34 |
35 | func analyzers(r *schemahcl.Resource) ([]sqlcheck.Analyzer, error) {
36 | ds, err := destructive.New(r)
37 | if err != nil {
38 | return nil, err
39 | }
40 | cd, err := condrop.New(r)
41 | if err != nil {
42 | return nil, err
43 | }
44 | dd, err := datadepend.New(r, datadepend.Handler{
45 | AddNotNull: addNotNull,
46 | })
47 | if err != nil {
48 | return nil, err
49 | }
50 | bc, err := incompatible.New(r)
51 | if err != nil {
52 | return nil, err
53 | }
54 | return []sqlcheck.Analyzer{ds, dd, cd, bc}, nil
55 | }
56 |
--------------------------------------------------------------------------------
/sql/postgres/postgrescheck/postgrescheck_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package postgrescheck
8 |
9 | import (
10 | "ariga.io/atlas/sql/postgres"
11 | "ariga.io/atlas/sql/sqlcheck"
12 | )
13 |
14 | func init() {
15 | sqlcheck.Register(postgres.DriverName, analyzers)
16 | }
17 |
--------------------------------------------------------------------------------
/sql/postgres/postgrescheck/postgrescheck_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | package postgrescheck_test
6 |
7 | import (
8 | "context"
9 | "testing"
10 |
11 | "ariga.io/atlas/sql/migrate"
12 | "ariga.io/atlas/sql/postgres"
13 | _ "ariga.io/atlas/sql/postgres/postgrescheck"
14 | "ariga.io/atlas/sql/schema"
15 | "ariga.io/atlas/sql/sqlcheck"
16 |
17 | "github.com/stretchr/testify/require"
18 | )
19 |
20 | func TestDataDepend_MightFail(t *testing.T) {
21 | var (
22 | report *sqlcheck.Report
23 | pass = &sqlcheck.Pass{
24 | File: &sqlcheck.File{
25 | File: testFile{name: "1.sql"},
26 | Changes: []*sqlcheck.Change{
27 | {
28 | Stmt: &migrate.Stmt{
29 | Text: "ALTER TABLE users",
30 | },
31 | Changes: schema.Changes{
32 | &schema.ModifyTable{
33 | T: schema.NewTable("users").
34 | SetSchema(schema.New("test")).
35 | AddColumns(
36 | schema.NewIntColumn("a", postgres.TypeInt),
37 | schema.NewIntColumn("b", postgres.TypeInt),
38 | ),
39 | Changes: []schema.Change{
40 | &schema.AddColumn{C: schema.NewTimeColumn("b", postgres.TypeInt)},
41 | },
42 | },
43 | },
44 | },
45 | },
46 | },
47 | Reporter: sqlcheck.ReportWriterFunc(func(r sqlcheck.Report) {
48 | report = &r
49 | }),
50 | }
51 | )
52 | azs, err := sqlcheck.AnalyzerFor(postgres.DriverName, nil)
53 | require.NoError(t, err)
54 | require.NoError(t, sqlcheck.Analyzers(azs).Analyze(context.Background(), pass))
55 | require.Equal(t, report.Diagnostics[0].Text, `Adding a non-nullable "int" column "b" will fail in case table "users" is not empty`)
56 | }
57 |
58 | type testFile struct {
59 | name string
60 | migrate.File
61 | }
62 |
63 | func (t testFile) Name() string {
64 | return t.name
65 | }
66 |
--------------------------------------------------------------------------------
/sql/schema/changekind_string.go:
--------------------------------------------------------------------------------
1 | // Code generated by "stringer -type ChangeKind"; DO NOT EDIT.
2 |
3 | package schema
4 |
5 | import "strconv"
6 |
7 | func _() {
8 | // An "invalid array index" compiler error signifies that the constant values have changed.
9 | // Re-run the stringer command to generate them again.
10 | var x [1]struct{}
11 | _ = x[NoChange-0]
12 | _ = x[ChangeAttr-1]
13 | _ = x[ChangeCharset-2]
14 | _ = x[ChangeCollate-4]
15 | _ = x[ChangeComment-8]
16 | _ = x[ChangeNull-16]
17 | _ = x[ChangeType-32]
18 | _ = x[ChangeDefault-64]
19 | _ = x[ChangeGenerated-128]
20 | _ = x[ChangeUnique-256]
21 | _ = x[ChangeParts-512]
22 | _ = x[ChangeColumn-1024]
23 | _ = x[ChangeRefColumn-2048]
24 | _ = x[ChangeRefTable-4096]
25 | _ = x[ChangeUpdateAction-8192]
26 | _ = x[ChangeDeleteAction-16384]
27 | }
28 |
29 | const _ChangeKind_name = "NoChangeChangeAttrChangeCharsetChangeCollateChangeCommentChangeNullChangeTypeChangeDefaultChangeGeneratedChangeUniqueChangePartsChangeColumnChangeRefColumnChangeRefTableChangeUpdateActionChangeDeleteAction"
30 |
31 | var _ChangeKind_map = map[ChangeKind]string{
32 | 0: _ChangeKind_name[0:8],
33 | 1: _ChangeKind_name[8:18],
34 | 2: _ChangeKind_name[18:31],
35 | 4: _ChangeKind_name[31:44],
36 | 8: _ChangeKind_name[44:57],
37 | 16: _ChangeKind_name[57:67],
38 | 32: _ChangeKind_name[67:77],
39 | 64: _ChangeKind_name[77:90],
40 | 128: _ChangeKind_name[90:105],
41 | 256: _ChangeKind_name[105:117],
42 | 512: _ChangeKind_name[117:128],
43 | 1024: _ChangeKind_name[128:140],
44 | 2048: _ChangeKind_name[140:155],
45 | 4096: _ChangeKind_name[155:169],
46 | 8192: _ChangeKind_name[169:187],
47 | 16384: _ChangeKind_name[187:205],
48 | }
49 |
50 | func (i ChangeKind) String() string {
51 | if str, ok := _ChangeKind_map[i]; ok {
52 | return str
53 | }
54 | return "ChangeKind(" + strconv.FormatInt(int64(i), 10) + ")"
55 | }
56 |
--------------------------------------------------------------------------------
/sql/sqlcheck/destructive/destructive_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package destructive
8 |
9 | import (
10 | "errors"
11 |
12 | "ariga.io/atlas/sql/migrate"
13 | "ariga.io/atlas/sql/schema"
14 | "ariga.io/atlas/sql/sqlcheck"
15 | )
16 |
17 | func (*Analyzer) hasEmptyTableCheck(*sqlcheck.Pass, *schema.Table) bool {
18 | return false // unimplemented.
19 | }
20 |
21 | func (*Analyzer) hasEmptyColumnCheck(*sqlcheck.Pass, *schema.Table, *schema.Column) bool {
22 | return false // unimplemented.
23 | }
24 |
25 | func (*Analyzer) emptyTableCheckStmt(*sqlcheck.Pass, *schema.Table) (*migrate.Stmt, error) {
26 | return nil, errors.New("unimplemented")
27 | }
28 |
29 | func (*Analyzer) emptyColumnCheckStmt(*sqlcheck.Pass, *schema.Table, string) (*migrate.Stmt, error) {
30 | return nil, errors.New("unimplemented")
31 | }
32 |
33 | func withSuggestion(_ *sqlcheck.Pass, r sqlcheck.Report, _ []*migrate.Stmt) sqlcheck.Report {
34 | return r // unimplemented.
35 | }
36 |
--------------------------------------------------------------------------------
/sql/sqlite/sqlitecheck/sqlitecheck_oss.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !ent
6 |
7 | package sqlitecheck
8 |
9 | import (
10 | "ariga.io/atlas/sql/sqlcheck"
11 | "ariga.io/atlas/sql/sqlite"
12 | )
13 |
14 | func init() {
15 | sqlcheck.Register(sqlite.DriverName, analyzers)
16 | }
17 |
--------------------------------------------------------------------------------
/sql/sqltool/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | // Package sqltool contains logic to integrate existing tools like Flyway or Liquibase with the Atlas CLI.
6 | package sqltool
7 |
--------------------------------------------------------------------------------
/sql/sqltool/hidden.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | //go:build !windows
6 |
7 | package sqltool
8 |
9 | import "path/filepath"
10 |
11 | func hidden(path string) (bool, error) {
12 | return filepath.Base(path)[0] == '.', nil
13 | }
14 |
--------------------------------------------------------------------------------
/sql/sqltool/hidden_windows.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021-present The Atlas Authors. All rights reserved.
2 | // This source code is licensed under the Apache 2.0 license found
3 | // in the LICENSE file in the root directory of this source tree.
4 |
5 | package sqltool
6 |
7 | import (
8 | "path/filepath"
9 | "syscall"
10 | )
11 |
12 | func hidden(path string) (bool, error) {
13 | abs, err := filepath.Abs(path)
14 | if err != nil {
15 | return false, err
16 | }
17 | p, err := syscall.UTF16PtrFromString(abs)
18 | if err != nil {
19 | return false, err
20 | }
21 | attr, err := syscall.GetFileAttributes(p)
22 | if err != nil {
23 | return false, err
24 | }
25 | return attr&syscall.FILE_ATTRIBUTE_HIDDEN != 0, nil
26 | }
27 |
--------------------------------------------------------------------------------
/sql/sqltool/testdata/dbmate/1_initial.sql:
--------------------------------------------------------------------------------
1 | -- migrate:up
2 | CREATE TABLE post
3 | (
4 | id int NOT NULL,
5 | title text,
6 | body text,
7 | PRIMARY KEY (id)
8 | );
9 |
10 | /*
11 | Multiline comment ...
12 | */
13 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
14 |
15 | INSERT INTO post (title) VALUES (
16 | 'This is
17 | my multiline
18 |
19 | value');
20 |
21 | -- migrate:down
22 |
23 |
24 | DROP TABLE post;
--------------------------------------------------------------------------------
/sql/sqltool/testdata/dbmate/2_second_migration.sql:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -- migrate:up
5 |
6 |
7 |
8 |
9 | CREATE TABLE tbl_2 (col INT);
--------------------------------------------------------------------------------
/sql/sqltool/testdata/flyway/B2__baseline.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE post
2 | (
3 | id int NOT NULL,
4 | title text,
5 | body text,
6 | created_at TIMESTAMP NOT NULL
7 | PRIMARY KEY (id)
8 | );
9 |
10 | INSERT INTO post (title, created_at) VALUES (
11 | 'This is
12 | my multiline
13 |
14 | value', NOW());
--------------------------------------------------------------------------------
/sql/sqltool/testdata/flyway/R__views.sql:
--------------------------------------------------------------------------------
1 | CREATE VIEW `my_view` AS SELECT * FROM `post`;
--------------------------------------------------------------------------------
/sql/sqltool/testdata/flyway/U1__initial.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE tbl;
--------------------------------------------------------------------------------
/sql/sqltool/testdata/flyway/V1__initial.sql:
--------------------------------------------------------------------------------
1 | -- comment
2 | CREATE TABLE post
3 | (
4 | id int NOT NULL,
5 | title text,
6 | body text,
7 | PRIMARY KEY (id)
8 | );
9 |
10 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
11 |
12 | INSERT INTO post (title, created_at) VALUES (
13 | 'This is
14 | my multiline
15 |
16 | value', NOW());
17 |
--------------------------------------------------------------------------------
/sql/sqltool/testdata/flyway/V2__second_migration.sql:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -- migrate:up
5 |
6 |
7 |
8 |
9 | CREATE TABLE tbl_2 (col INT);
--------------------------------------------------------------------------------
/sql/sqltool/testdata/flyway/V3__third_migration.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE tbl_2 ADD col_1 INTEGER NOT NULL;
--------------------------------------------------------------------------------
/sql/sqltool/testdata/flyway/v3/V3_1__fourth_migration.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE tbl_2 ADD col_2 INTEGER NOT NULL;
--------------------------------------------------------------------------------
/sql/sqltool/testdata/golang-migrate/1_initial.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE tbl;
--------------------------------------------------------------------------------
/sql/sqltool/testdata/golang-migrate/1_initial.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE tbl
2 | (
3 | col INT
4 | );
--------------------------------------------------------------------------------
/sql/sqltool/testdata/golang-migrate/2_second_migration.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE tbl_2;
--------------------------------------------------------------------------------
/sql/sqltool/testdata/golang-migrate/2_second_migration.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE tbl_2 (col INT);
--------------------------------------------------------------------------------
/sql/sqltool/testdata/goose/1_initial.sql:
--------------------------------------------------------------------------------
1 | -- +goose Up
2 | CREATE TABLE post
3 | (
4 | id int NOT NULL,
5 | title text,
6 | body text,
7 | PRIMARY KEY (id)
8 | );
9 |
10 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
11 |
12 | INSERT INTO post (title) VALUES (
13 | 'This is
14 | my multiline
15 |
16 | value');
17 |
18 | -- +goose Down
19 | DROP TABLE post;
--------------------------------------------------------------------------------
/sql/sqltool/testdata/goose/2_second_migration.sql:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -- +goose Up
5 |
6 |
7 | ALTER TABLE post ADD updated_at TIMESTAMP NOT NULL;
8 |
9 | -- +goose StatementBegin
10 | -- Comment for the function declaration.
11 | CREATE
12 | OR REPLACE FUNCTION histories_partition_creation( DATE, DATE )
13 | returns void AS $$
14 | DECLARE
15 | create_query text;
16 | BEGIN
17 | FOR create_query IN
18 | SELECT 'CREATE TABLE IF NOT EXISTS histories_'
19 | || TO_CHAR(d, 'YYYY_MM')
20 | || ' ( CHECK( created_at >= timestamp '''
21 | || TO_CHAR(d, 'YYYY-MM-DD 00:00:00')
22 | || ''' AND created_at < timestamp '''
23 | || TO_CHAR(d + INTERVAL '1 month', 'YYYY-MM-DD 00:00:00')
24 | || ''' ) ) inherits ( histories );'
25 | FROM generate_series($1, $2, '1 month') AS d LOOP
26 | EXECUTE create_query;
27 | END LOOP; -- LOOP END
28 | END; -- FUNCTION END
29 | $$
30 | language plpgsql;
31 | -- +goose StatementEnd
--------------------------------------------------------------------------------
/sql/sqltool/testdata/liquibase/1_initial.sql:
--------------------------------------------------------------------------------
1 | --liquibase formatted sql
2 |
3 | --changeset atlas:1-1
4 | CREATE TABLE post
5 | (
6 | id int NOT NULL,
7 | title text,
8 | body text,
9 | PRIMARY KEY (id)
10 | );
11 | --rollback: DROP TABLE post;
12 |
13 | --changeset atlas:1-2
14 | ALTER TABLE post ADD created_at TIMESTAMP NOT NULL;
15 | --rollback: ALTER TABLE post DROP created_at;
16 |
17 | --changeset atlas:1-3
18 | INSERT INTO post (title) VALUES (
19 | 'This is
20 | my multiline
21 |
22 | value');
23 |
--------------------------------------------------------------------------------
/sql/sqltool/testdata/liquibase/2_second_migration.sql:
--------------------------------------------------------------------------------
1 | --liquibase formatted sql
2 |
3 | --changeset atlas:2-1
4 | CREATE TABLE tbl_2 (col INT);
5 | --rollback DROP TABLE tbl_2;
6 |
--------------------------------------------------------------------------------