From 120e6a38d5b7ed1c3dd2be5198051f06bffaee85 Mon Sep 17 00:00:00 2001 From: Radoslav Kirilov Date: Sat, 23 Dec 2023 22:13:19 +0200 Subject: [PATCH] feat: environment variables interpolation (#604) Co-authored-by: Mike Fridman --- CHANGELOG.md | 20 +++++ README.md | 42 ++++++++++ go.mod | 1 + go.sum | 2 + internal/sqlparser/parser.go | 28 ++++++- internal/sqlparser/parser_test.go | 78 ++++++++++++++----- .../testdata/envsub/test01/01.down.golden.sql | 1 + .../testdata/envsub/test01/01.up.golden.sql | 6 ++ .../testdata/envsub/test01/02.up.golden.sql | 1 + .../testdata/envsub/test01/03.up.golden.sql | 1 + .../testdata/envsub/test01/04.up.golden.sql | 1 + .../testdata/envsub/test01/input.sql | 17 ++++ .../testdata/envsub/test02/01.up.golden.sql | 8 ++ .../testdata/envsub/test02/02.up.golden.sql | 8 ++ .../testdata/envsub/test02/03.up.golden.sql | 6 ++ .../testdata/envsub/test02/input.sql | 32 ++++++++ .../testdata/envsub/test03/01.up.golden.sql | 8 ++ .../testdata/envsub/test03/input.sql | 9 +++ .../{01.golden.sql => 01.up.golden.sql} | 0 .../{02.golden.sql => 02.up.golden.sql} | 0 .../{03.golden.sql => 03.up.golden.sql} | 0 .../{01.golden.sql => 01.up.golden.sql} | 0 .../{01.golden.sql => 01.up.golden.sql} | 0 .../{01.golden.sql => 01.up.golden.sql} | 0 .../{02.golden.sql => 02.up.golden.sql} | 0 .../{03.golden.sql => 03.up.golden.sql} | 0 .../{01.golden.sql => 01.up.golden.sql} | 0 .../{02.golden.sql => 02.up.golden.sql} | 0 .../{01.golden.sql => 01.up.golden.sql} | 0 .../{02.golden.sql => 02.up.golden.sql} | 0 .../{03.golden.sql => 03.up.golden.sql} | 0 .../{04.golden.sql => 04.up.golden.sql} | 0 .../{05.golden.sql => 05.up.golden.sql} | 0 .../{01.golden.sql => 01.up.golden.sql} | 0 .../{01.golden.sql => 01.up.golden.sql} | 0 .../{02.golden.sql => 02.up.golden.sql} | 0 .../{03.golden.sql => 03.up.golden.sql} | 0 .../{04.golden.sql => 04.up.golden.sql} | 0 .../{05.golden.sql => 05.up.golden.sql} | 0 .../{06.golden.sql => 06.up.golden.sql} | 0 .../{01.golden.sql => 01.up.golden.sql} | 0 41 files changed, 247 insertions(+), 22 deletions(-) create mode 100644 internal/sqlparser/testdata/envsub/test01/01.down.golden.sql create mode 100644 internal/sqlparser/testdata/envsub/test01/01.up.golden.sql create mode 100644 internal/sqlparser/testdata/envsub/test01/02.up.golden.sql create mode 100644 internal/sqlparser/testdata/envsub/test01/03.up.golden.sql create mode 100644 internal/sqlparser/testdata/envsub/test01/04.up.golden.sql create mode 100644 internal/sqlparser/testdata/envsub/test01/input.sql create mode 100644 internal/sqlparser/testdata/envsub/test02/01.up.golden.sql create mode 100644 internal/sqlparser/testdata/envsub/test02/02.up.golden.sql create mode 100644 internal/sqlparser/testdata/envsub/test02/03.up.golden.sql create mode 100644 internal/sqlparser/testdata/envsub/test02/input.sql create mode 100644 internal/sqlparser/testdata/envsub/test03/01.up.golden.sql create mode 100644 internal/sqlparser/testdata/envsub/test03/input.sql rename internal/sqlparser/testdata/valid-up/test01/{01.golden.sql => 01.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test01/{02.golden.sql => 02.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test01/{03.golden.sql => 03.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test02/{01.golden.sql => 01.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test03/{01.golden.sql => 01.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test04/{01.golden.sql => 01.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test04/{02.golden.sql => 02.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test04/{03.golden.sql => 03.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test05/{01.golden.sql => 01.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test05/{02.golden.sql => 02.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test06/{01.golden.sql => 01.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test06/{02.golden.sql => 02.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test06/{03.golden.sql => 03.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test06/{04.golden.sql => 04.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test06/{05.golden.sql => 05.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test07/{01.golden.sql => 01.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test08/{01.golden.sql => 01.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test08/{02.golden.sql => 02.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test08/{03.golden.sql => 03.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test08/{04.golden.sql => 04.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test08/{05.golden.sql => 05.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test08/{06.golden.sql => 06.up.golden.sql} (100%) rename internal/sqlparser/testdata/valid-up/test09/{01.golden.sql => 01.up.golden.sql} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb9a8ba7c..a81fe14ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,26 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +- Add environment variable substitution for SQL migrations. (#604) + + - This feature is **disabled by default**, and can be enabled by adding an annotation to the + migration file: + + ```sql + -- +goose ENVSUB ON + ``` + + - When enabled, goose will attempt to substitute environment variables in the SQL migration + queries until the end of the file, or until the annotation `-- +goose ENVSUB OFF` is found. For + example, if the environment variable `REGION` is set to `us_east_1`, the following SQL migration + will be substituted to `SELECT * FROM regions WHERE name = 'us_east_1';` + + ```sql + -- +goose ENVSUB ON + -- +goose Up + SELECT * FROM regions WHERE name = '${REGION}'; + ``` + ## [v3.17.0] - 2023-12-15 - Standardised the MIT license (#647) diff --git a/README.md b/README.md index cceb0d9af..4da15e111 100644 --- a/README.md +++ b/README.md @@ -282,6 +282,48 @@ language plpgsql; -- +goose StatementEnd ``` +Goose supports environment variable substitution in SQL migrations through annotations. To enable +this feature, use the `-- +goose ENVSUB ON` annotation before the queries where you want +substitution applied. It stays active until the `-- +goose ENVSUB OFF` annotation is encountered. +You can use these annotations multiple times within a file. + +This feature is disabled by default for backward compatibility with existing scripts. + +For `PL/pgSQL` functions or other statements where substitution is not desired, wrap the annotations +explicitly around the relevant parts. For example, to exclude escaping the `**` characters: + +```sql +-- +goose StatementBegin +CREATE OR REPLACE FUNCTION test_func() +RETURNS void AS $$ +-- +goose ENVSUB ON +BEGIN + RAISE NOTICE '${SOME_ENV_VAR}'; +END; +-- +goose ENVSUB OFF +$$ LANGUAGE plpgsql; +-- +goose StatementEnd +``` + +
+Supported expansions (click here to expand): + +- `${VAR}` or $VAR - expands to the value of the environment variable `VAR` +- `${VAR:-default}` - expands to the value of the environment variable `VAR`, or `default` if `VAR` + is unset or null +- `${VAR-default}` - expands to the value of the environment variable `VAR`, or `default` if `VAR` + is unset +- `${VAR?err_msg}` - expands to the value of the environment variable `VAR`, or prints `err_msg` and + error if `VAR` unset +- ~~`${VAR:?err_msg}` - expands to the value of the environment variable `VAR`, or prints `err_msg` + and error if `VAR` unset or null.~~ **THIS IS NOT SUPPORTED** + +See +[mfridman/interpolate](https://github.com/mfridman/interpolate?tab=readme-ov-file#supported-expansions) +for more details on supported expansions. + +
+ ## Embedded sql migrations Go 1.16 introduced new feature: [compile-time embedding](https://pkg.go.dev/embed/) files into binary and diff --git a/go.mod b/go.mod index 5e69f43a9..cec99b568 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/ClickHouse/clickhouse-go/v2 v2.16.0 github.com/go-sql-driver/mysql v1.7.1 github.com/jackc/pgx/v5 v5.5.1 + github.com/mfridman/interpolate v0.0.2 github.com/microsoft/go-mssqldb v1.6.0 github.com/ory/dockertest/v3 v3.10.0 github.com/sethvargo/go-retry v0.2.4 diff --git a/go.sum b/go.sum index d75950045..792eba8e7 100644 --- a/go.sum +++ b/go.sum @@ -174,6 +174,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= +github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= diff --git a/internal/sqlparser/parser.go b/internal/sqlparser/parser.go index a62846026..bba79905a 100644 --- a/internal/sqlparser/parser.go +++ b/internal/sqlparser/parser.go @@ -7,8 +7,11 @@ import ( "fmt" "io" "log" + "os" "strings" "sync" + + "github.com/mfridman/interpolate" ) type Direction string @@ -107,6 +110,7 @@ func ParseSQLMigration(r io.Reader, direction Direction, debug bool) (stmts []st stateMachine := newStateMachine(start, debug) useTx = true + useEnvsub := false var buf bytes.Buffer for scanner.Scan() { @@ -171,6 +175,14 @@ func ParseSQLMigration(r io.Reader, direction Direction, debug bool) (stmts []st case "+goose NO TRANSACTION": useTx = false continue + + case "+goose ENVSUB ON": + useEnvsub = true + continue + + case "+goose ENVSUB OFF": + useEnvsub = false + continue } } // Once we've started parsing a statement the buffer is no longer empty, @@ -187,6 +199,13 @@ func ParseSQLMigration(r io.Reader, direction Direction, debug bool) (stmts []st case gooseStatementEndDown, gooseStatementEndUp: // Do not include the "+goose StatementEnd" annotation in the final statement. default: + if useEnvsub { + expanded, err := interpolate.Interpolate(&envWrapper{}, line) + if err != nil { + return nil, false, fmt.Errorf("variable substitution failed: %w:\n%s", err, line) + } + line = expanded + } // Write SQL line to a buffer. if _, err := buf.WriteString(line + "\n"); err != nil { return nil, false, fmt.Errorf("failed to write to buf: %w", err) @@ -266,7 +285,14 @@ func missingSemicolonError(state parserState, direction Direction, s string) err ) } -// cleanupStatement trims whitespace from the given statement. +type envWrapper struct{} + +var _ interpolate.Env = (*envWrapper)(nil) + +func (e *envWrapper) Get(key string) (string, bool) { + return os.LookupEnv(key) +} + func cleanupStatement(input string) string { return strings.TrimSpace(input) } diff --git a/internal/sqlparser/parser_test.go b/internal/sqlparser/parser_test.go index a98c51635..efe47d7e5 100644 --- a/internal/sqlparser/parser_test.go +++ b/internal/sqlparser/parser_test.go @@ -380,9 +380,9 @@ func TestValidUp(t *testing.T) { // to the parser. Then we compare the statements against the golden files. // Each golden file is equivalent to one statement. // - // ├── 01.golden.sql - // ├── 02.golden.sql - // ├── 03.golden.sql + // ├── 01.up.golden.sql + // ├── 02.up.golden.sql + // ├── 03.up.golden.sql // └── input.sql tests := []struct { Name string @@ -401,36 +401,36 @@ func TestValidUp(t *testing.T) { for _, tc := range tests { path := filepath.Join("testdata", "valid-up", tc.Name) t.Run(tc.Name, func(t *testing.T) { - testValidUp(t, path, tc.StatementsCount) + testValid(t, path, tc.StatementsCount, DirectionUp) }) } } -func testValidUp(t *testing.T, dir string, count int) { +func testValid(t *testing.T, dir string, count int, direction Direction) { t.Helper() f, err := os.Open(filepath.Join(dir, "input.sql")) check.NoError(t, err) t.Cleanup(func() { f.Close() }) - statements, _, err := ParseSQLMigration(f, DirectionUp, debug) + statements, _, err := ParseSQLMigration(f, direction, debug) check.NoError(t, err) check.Number(t, len(statements), count) - compareStatements(t, dir, statements) + compareStatements(t, dir, statements, direction) } -func compareStatements(t *testing.T, dir string, statements []string) { +func compareStatements(t *testing.T, dir string, statements []string, direction Direction) { t.Helper() - files, err := filepath.Glob(filepath.Join(dir, "*.golden.sql")) + files, err := filepath.Glob(filepath.Join(dir, fmt.Sprintf("*.%s.golden.sql", direction))) check.NoError(t, err) if len(statements) != len(files) { - t.Fatalf("mismatch between parsed statements (%d) and golden files (%d), did you check in NN.golden.sql file in %q?", len(statements), len(files), dir) + t.Fatalf("mismatch between parsed statements (%d) and golden files (%d), did you check in NN.{up|down}.golden.sql file in %q?", len(statements), len(files), dir) } for _, goldenFile := range files { goldenFile = filepath.Base(goldenFile) - before, _, ok := cut(goldenFile, ".") + before, _, ok := strings.Cut(goldenFile, ".") if !ok { - t.Fatal(`failed to cut on file delimiter ".", must be of the format NN.golden.sql`) + t.Fatal(`failed to cut on file delimiter ".", must be of the format NN.{up|down}.golden.sql`) } index, err := strconv.Atoi(before) check.NoError(t, err) @@ -458,16 +458,52 @@ func compareStatements(t *testing.T, dir string, statements []string) { } } -// copied directly from strings.Cut (go1.18) to support older Go versions. -// In the future, replace this with the upstream function. -func cut(s, sep string) (before, after string, found bool) { - if i := strings.Index(s, sep); i >= 0 { - return s[:i], s[i+len(sep):], true - } - return s, "", false -} - func isCIEnvironment() bool { ok, _ := strconv.ParseBool(os.Getenv("CI")) return ok } + +func TestEnvsub(t *testing.T) { + // Do not run in parallel, as this test sets environment variables. + + // Test valid migrations with ${var} like statements when on are substituted for the whole + // migration. + t.Setenv("GOOSE_ENV_REGION", "us_east_") + t.Setenv("GOOSE_ENV_SET_BUT_EMPTY_VALUE", "") + t.Setenv("GOOSE_ENV_NAME", "foo") + + tests := []struct { + Name string + DownCount int + UpCount int + }{ + {Name: "test01", UpCount: 4, DownCount: 1}, + {Name: "test02", UpCount: 3, DownCount: 0}, + {Name: "test03", UpCount: 1, DownCount: 0}, + } + for _, tc := range tests { + t.Run(tc.Name, func(t *testing.T) { + dir := filepath.Join("testdata", "envsub", tc.Name) + testValid(t, dir, tc.UpCount, DirectionUp) + testValid(t, dir, tc.DownCount, DirectionDown) + }) + } +} + +func TestEnvsubError(t *testing.T) { + t.Parallel() + + s := ` +-- +goose ENVSUB ON +-- +goose Up +CREATE TABLE post ( + id int NOT NULL, + title text, + ${SOME_UNSET_VAR?required env var not set} text, + PRIMARY KEY(id) +); +` + _, _, err := ParseSQLMigration(strings.NewReader(s), DirectionUp, debug) + check.HasError(t, err) + check.Contains(t, err.Error(), "variable substitution failed: $SOME_UNSET_VAR: required env var not set:") +} diff --git a/internal/sqlparser/testdata/envsub/test01/01.down.golden.sql b/internal/sqlparser/testdata/envsub/test01/01.down.golden.sql new file mode 100644 index 000000000..ec9529335 --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test01/01.down.golden.sql @@ -0,0 +1 @@ +DROP TABLE us_east_post; -- 1st stmt \ No newline at end of file diff --git a/internal/sqlparser/testdata/envsub/test01/01.up.golden.sql b/internal/sqlparser/testdata/envsub/test01/01.up.golden.sql new file mode 100644 index 000000000..fc597fdc2 --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test01/01.up.golden.sql @@ -0,0 +1,6 @@ +CREATE TABLE us_east_post ( + id int NOT NULL, + title text, + body text, + PRIMARY KEY(id) +); -- 1st stmt \ No newline at end of file diff --git a/internal/sqlparser/testdata/envsub/test01/02.up.golden.sql b/internal/sqlparser/testdata/envsub/test01/02.up.golden.sql new file mode 100644 index 000000000..193fc1599 --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test01/02.up.golden.sql @@ -0,0 +1 @@ +SELECT 2; -- 2nd stmt \ No newline at end of file diff --git a/internal/sqlparser/testdata/envsub/test01/03.up.golden.sql b/internal/sqlparser/testdata/envsub/test01/03.up.golden.sql new file mode 100644 index 000000000..3d949d37a --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test01/03.up.golden.sql @@ -0,0 +1 @@ +SELECT 3; SELECT 3; -- 3rd stmt \ No newline at end of file diff --git a/internal/sqlparser/testdata/envsub/test01/04.up.golden.sql b/internal/sqlparser/testdata/envsub/test01/04.up.golden.sql new file mode 100644 index 000000000..1e9b96104 --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test01/04.up.golden.sql @@ -0,0 +1 @@ +SELECT 4; -- 4th stmt \ No newline at end of file diff --git a/internal/sqlparser/testdata/envsub/test01/input.sql b/internal/sqlparser/testdata/envsub/test01/input.sql new file mode 100644 index 000000000..9774edf1b --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test01/input.sql @@ -0,0 +1,17 @@ +-- +goose ENVSUB ON +-- +goose Up +CREATE TABLE ${GOOSE_ENV_REGION}post ( + id int NOT NULL, + title text, + body text, + PRIMARY KEY(id) +); -- 1st stmt + +-- comment +SELECT 2; -- 2nd stmt +SELECT 3; SELECT 3; -- 3rd stmt +SELECT 4; -- 4th stmt + +-- +goose Down +-- comment +DROP TABLE ${GOOSE_ENV_REGION}post; -- 1st stmt diff --git a/internal/sqlparser/testdata/envsub/test02/01.up.golden.sql b/internal/sqlparser/testdata/envsub/test02/01.up.golden.sql new file mode 100644 index 000000000..ee37c8ece --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test02/01.up.golden.sql @@ -0,0 +1,8 @@ +CREATE TABLE post ( + id int NOT NULL, + title text, + foo text, + footitle3 text, + defaulttitle4 text, + title5 text, +); \ No newline at end of file diff --git a/internal/sqlparser/testdata/envsub/test02/02.up.golden.sql b/internal/sqlparser/testdata/envsub/test02/02.up.golden.sql new file mode 100644 index 000000000..ceaee7e84 --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test02/02.up.golden.sql @@ -0,0 +1,8 @@ +CREATE TABLE post ( + id int NOT NULL, + title text, + $GOOSE_ENV_NAME text, + ${GOOSE_ENV_NAME}title3 text, + ${ANOTHER_VAR:-default}title4 text, + ${GOOSE_ENV_SET_BUT_EMPTY_VALUE-default}title5 text, +); \ No newline at end of file diff --git a/internal/sqlparser/testdata/envsub/test02/03.up.golden.sql b/internal/sqlparser/testdata/envsub/test02/03.up.golden.sql new file mode 100644 index 000000000..1fb015ee5 --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test02/03.up.golden.sql @@ -0,0 +1,6 @@ +CREATE OR REPLACE FUNCTION test_func() +RETURNS void AS $$ +BEGIN + RAISE NOTICE 'foo $GOOSE_ENV_NAME $GOOSE_ENV_NAME'; +END; +$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/internal/sqlparser/testdata/envsub/test02/input.sql b/internal/sqlparser/testdata/envsub/test02/input.sql new file mode 100644 index 000000000..32ae6ac07 --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test02/input.sql @@ -0,0 +1,32 @@ +-- +goose Up + +-- +goose ENVSUB ON +CREATE TABLE post ( + id int NOT NULL, + title text, + $GOOSE_ENV_NAME text, + ${GOOSE_ENV_NAME}title3 text, + ${ANOTHER_VAR:-default}title4 text, + ${GOOSE_ENV_SET_BUT_EMPTY_VALUE-default}title5 text, +); +-- +goose ENVSUB OFF + +CREATE TABLE post ( + id int NOT NULL, + title text, + $GOOSE_ENV_NAME text, + ${GOOSE_ENV_NAME}title3 text, + ${ANOTHER_VAR:-default}title4 text, + ${GOOSE_ENV_SET_BUT_EMPTY_VALUE-default}title5 text, +); + +-- +goose StatementBegin +CREATE OR REPLACE FUNCTION test_func() +RETURNS void AS $$ +-- +goose ENVSUB ON +BEGIN + RAISE NOTICE '${GOOSE_ENV_NAME} \$GOOSE_ENV_NAME \$GOOSE_ENV_NAME'; +END; +-- +goose ENVSUB OFF +$$ LANGUAGE plpgsql; +-- +goose StatementEnd diff --git a/internal/sqlparser/testdata/envsub/test03/01.up.golden.sql b/internal/sqlparser/testdata/envsub/test03/01.up.golden.sql new file mode 100644 index 000000000..b31a3e63c --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test03/01.up.golden.sql @@ -0,0 +1,8 @@ +CREATE TABLE post ( + id int NOT NULL, + title text, + $NAME text, + ${NAME}title3 text, + ${ANOTHER_VAR:-default}title4 text, + ${SET_BUT_EMPTY_VALUE-default}title5 text, +); \ No newline at end of file diff --git a/internal/sqlparser/testdata/envsub/test03/input.sql b/internal/sqlparser/testdata/envsub/test03/input.sql new file mode 100644 index 000000000..d63dd9fba --- /dev/null +++ b/internal/sqlparser/testdata/envsub/test03/input.sql @@ -0,0 +1,9 @@ +-- +goose Up +CREATE TABLE post ( + id int NOT NULL, + title text, + $NAME text, + ${NAME}title3 text, + ${ANOTHER_VAR:-default}title4 text, + ${SET_BUT_EMPTY_VALUE-default}title5 text, +); diff --git a/internal/sqlparser/testdata/valid-up/test01/01.golden.sql b/internal/sqlparser/testdata/valid-up/test01/01.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test01/01.golden.sql rename to internal/sqlparser/testdata/valid-up/test01/01.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test01/02.golden.sql b/internal/sqlparser/testdata/valid-up/test01/02.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test01/02.golden.sql rename to internal/sqlparser/testdata/valid-up/test01/02.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test01/03.golden.sql b/internal/sqlparser/testdata/valid-up/test01/03.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test01/03.golden.sql rename to internal/sqlparser/testdata/valid-up/test01/03.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test02/01.golden.sql b/internal/sqlparser/testdata/valid-up/test02/01.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test02/01.golden.sql rename to internal/sqlparser/testdata/valid-up/test02/01.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test03/01.golden.sql b/internal/sqlparser/testdata/valid-up/test03/01.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test03/01.golden.sql rename to internal/sqlparser/testdata/valid-up/test03/01.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test04/01.golden.sql b/internal/sqlparser/testdata/valid-up/test04/01.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test04/01.golden.sql rename to internal/sqlparser/testdata/valid-up/test04/01.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test04/02.golden.sql b/internal/sqlparser/testdata/valid-up/test04/02.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test04/02.golden.sql rename to internal/sqlparser/testdata/valid-up/test04/02.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test04/03.golden.sql b/internal/sqlparser/testdata/valid-up/test04/03.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test04/03.golden.sql rename to internal/sqlparser/testdata/valid-up/test04/03.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test05/01.golden.sql b/internal/sqlparser/testdata/valid-up/test05/01.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test05/01.golden.sql rename to internal/sqlparser/testdata/valid-up/test05/01.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test05/02.golden.sql b/internal/sqlparser/testdata/valid-up/test05/02.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test05/02.golden.sql rename to internal/sqlparser/testdata/valid-up/test05/02.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test06/01.golden.sql b/internal/sqlparser/testdata/valid-up/test06/01.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test06/01.golden.sql rename to internal/sqlparser/testdata/valid-up/test06/01.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test06/02.golden.sql b/internal/sqlparser/testdata/valid-up/test06/02.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test06/02.golden.sql rename to internal/sqlparser/testdata/valid-up/test06/02.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test06/03.golden.sql b/internal/sqlparser/testdata/valid-up/test06/03.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test06/03.golden.sql rename to internal/sqlparser/testdata/valid-up/test06/03.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test06/04.golden.sql b/internal/sqlparser/testdata/valid-up/test06/04.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test06/04.golden.sql rename to internal/sqlparser/testdata/valid-up/test06/04.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test06/05.golden.sql b/internal/sqlparser/testdata/valid-up/test06/05.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test06/05.golden.sql rename to internal/sqlparser/testdata/valid-up/test06/05.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test07/01.golden.sql b/internal/sqlparser/testdata/valid-up/test07/01.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test07/01.golden.sql rename to internal/sqlparser/testdata/valid-up/test07/01.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test08/01.golden.sql b/internal/sqlparser/testdata/valid-up/test08/01.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test08/01.golden.sql rename to internal/sqlparser/testdata/valid-up/test08/01.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test08/02.golden.sql b/internal/sqlparser/testdata/valid-up/test08/02.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test08/02.golden.sql rename to internal/sqlparser/testdata/valid-up/test08/02.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test08/03.golden.sql b/internal/sqlparser/testdata/valid-up/test08/03.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test08/03.golden.sql rename to internal/sqlparser/testdata/valid-up/test08/03.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test08/04.golden.sql b/internal/sqlparser/testdata/valid-up/test08/04.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test08/04.golden.sql rename to internal/sqlparser/testdata/valid-up/test08/04.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test08/05.golden.sql b/internal/sqlparser/testdata/valid-up/test08/05.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test08/05.golden.sql rename to internal/sqlparser/testdata/valid-up/test08/05.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test08/06.golden.sql b/internal/sqlparser/testdata/valid-up/test08/06.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test08/06.golden.sql rename to internal/sqlparser/testdata/valid-up/test08/06.up.golden.sql diff --git a/internal/sqlparser/testdata/valid-up/test09/01.golden.sql b/internal/sqlparser/testdata/valid-up/test09/01.up.golden.sql similarity index 100% rename from internal/sqlparser/testdata/valid-up/test09/01.golden.sql rename to internal/sqlparser/testdata/valid-up/test09/01.up.golden.sql