diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 09d8cddc5..505cc265c 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -26,7 +26,7 @@ jobs:
- name: Test
run: |
cd yb-voyager
- go test -v ./...
+ go test -v -skip 'TestDDLIssuesInYBVersion' ./...
- name: Vet
run: |
diff --git a/.github/workflows/issue-tests.yml b/.github/workflows/issue-tests.yml
new file mode 100644
index 000000000..94e95b16f
--- /dev/null
+++ b/.github/workflows/issue-tests.yml
@@ -0,0 +1,50 @@
+name: Go
+
+on:
+ push:
+ branches: ['main', '*.*-dev', '*.*.*-dev']
+ pull_request:
+ branches: [main]
+
+jobs:
+
+ test-issues-against-all-yb-versions:
+ strategy:
+ matrix:
+ version: [2.23.1.0-b220, 2024.1.3.1-b8, 2.20.8.0-b53, 2.18.9.0-b17]
+ env:
+ YB_VERSION: ${{ matrix.version }}
+ YB_CONN_STR: "postgres://yugabyte:yugabyte@127.0.0.1:5433/yugabyte"
+
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up Go
+ uses: actions/setup-go@v3
+ with:
+ go-version: "1.23.1"
+
+ - name: Setup YugabyteDB
+ run: |
+ # using s3 release instead of docker image to allow testing against un-released versions
+ wget https://s3.us-west-2.amazonaws.com/releases.yugabyte.com/${YB_VERSION}/yugabyte-${YB_VERSION}-centos-x86_64.tar.gz
+ mkdir -p yugabyte-${YB_VERSION}
+ tar -xvzf yugabyte-${YB_VERSION}-centos-x86_64.tar.gz -C yugabyte-${YB_VERSION} --strip-components=1
+ yugabyte-${YB_VERSION}/bin/yugabyted start --advertise_address 127.0.0.1
+ sleep 20
+
+ - name: Test YugabyteDB connection
+ run: |
+ psql "${YB_CONN_STR}" -c "SELECT version();"
+
+ - name: Build
+ run: |
+ cd yb-voyager
+ go build -v ./...
+
+ - name: Test Issues Against YB Version
+ run: |
+ cd yb-voyager
+ go test -v -run '^TestDDLIssuesInYBVersion$' ./...
+
diff --git a/yb-voyager/go.mod b/yb-voyager/go.mod
index b761c2d4a..93e64b1e7 100644
--- a/yb-voyager/go.mod
+++ b/yb-voyager/go.mod
@@ -11,6 +11,7 @@ require (
github.com/aws/aws-sdk-go-v2/config v1.18.15
github.com/aws/aws-sdk-go-v2/service/s3 v1.30.5
github.com/davecgh/go-spew v1.1.1
+ github.com/docker/go-connections v0.5.0
github.com/dustin/go-humanize v1.0.1
github.com/fatih/color v1.13.0
github.com/fergusstrange/embedded-postgres v1.29.0
@@ -23,6 +24,7 @@ require (
github.com/jackc/pgconn v1.13.0
github.com/jackc/pgx/v4 v4.17.2
github.com/jackc/pgx/v5 v5.0.3
+ github.com/lib/pq v1.10.9
github.com/mattn/go-sqlite3 v1.14.17
github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2
github.com/mitchellh/go-ps v1.0.0
@@ -35,6 +37,7 @@ require (
github.com/stretchr/testify v1.9.0
github.com/tebeka/atexit v0.3.0
github.com/testcontainers/testcontainers-go v0.34.0
+ github.com/testcontainers/testcontainers-go/modules/yugabytedb v0.34.0
github.com/vbauerster/mpb/v8 v8.4.0
gocloud.dev v0.29.0
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
@@ -54,7 +57,6 @@ require (
github.com/cpuguy83/dockercfg v0.3.2 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/docker v27.1.1+incompatible // indirect
- github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.1 // indirect
@@ -64,7 +66,6 @@ require (
github.com/jackc/puddle v1.3.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/klauspost/compress v1.17.4 // indirect
- github.com/lib/pq v1.10.9 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
diff --git a/yb-voyager/go.sum b/yb-voyager/go.sum
index a0de89791..1369ff42c 100644
--- a/yb-voyager/go.sum
+++ b/yb-voyager/go.sum
@@ -1127,6 +1127,7 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -1259,6 +1260,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.1/go.mod h1:G+WkljZi4mflcqVxYSgv
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
+github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
+github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hanwen/go-fuse/v2 v2.2.0/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
@@ -1921,6 +1924,8 @@ github.com/tebeka/atexit v0.3.0/go.mod h1:WJmSUSmMT7WoR7etUOaGBVXk+f5/ZJ+67qwued
github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0=
github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
+github.com/testcontainers/testcontainers-go/modules/yugabytedb v0.34.0 h1:9wIqSZJwBr4s8Q7R3S+rhe1J2zqHHxH0S1bN17ld+CI=
+github.com/testcontainers/testcontainers-go/modules/yugabytedb v0.34.0/go.mod h1:bgHrbdYjpNPSstf8HfxChUxc6XztBCSoqDR0syb1Oeg=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
@@ -1965,6 +1970,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
+github.com/yugabyte/gocql v1.6.0-yb-1 h1:3anNiHsJwKQ8Dn7RdmkTEuIzV1l7e9QJZ8wkOZ87ELg=
+github.com/yugabyte/gocql v1.6.0-yb-1/go.mod h1:LAokR6+vevDCrTxk52U7p6ki+4qELu4XU7JUGYa2O2M=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -2942,6 +2949,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
+gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/yb-voyager/src/queryissue/ddl_issues_test.go b/yb-voyager/src/queryissue/ddl_issues_test.go
new file mode 100644
index 000000000..105f56587
--- /dev/null
+++ b/yb-voyager/src/queryissue/ddl_issues_test.go
@@ -0,0 +1,121 @@
+/*
+Copyright (c) YugabyteDB, Inc.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package queryissue
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "testing"
+
+ "github.com/jackc/pgx/v5"
+ "github.com/stretchr/testify/assert"
+ "github.com/testcontainers/testcontainers-go/modules/yugabytedb"
+)
+
+var (
+ yugabytedbContainer *yugabytedb.Container
+ yugabytedbConnStr string
+ versions = []string{}
+)
+
+func getConn() (*pgx.Conn, error) {
+ ctx := context.Background()
+ var connStr string
+ var err error
+ if yugabytedbConnStr != "" {
+ connStr = yugabytedbConnStr
+ } else {
+ connStr, err = yugabytedbContainer.YSQLConnectionString(ctx, "sslmode=disable")
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ conn, err := pgx.Connect(ctx, connStr)
+ if err != nil {
+ return nil, err
+ }
+
+ return conn, nil
+}
+
+func testXMLFunctionIssue(t *testing.T) {
+ ctx := context.Background()
+ conn, err := getConn()
+ assert.NoError(t, err)
+
+ defer conn.Close(context.Background())
+ _, err = conn.Exec(ctx, "SELECT xmlconcat('', 'foo')")
+ assert.ErrorContains(t, err, "unsupported XML feature")
+}
+
+func testStoredGeneratedFunctionsIssue(t *testing.T) {
+ ctx := context.Background()
+ conn, err := getConn()
+ assert.NoError(t, err)
+
+ defer conn.Close(context.Background())
+ _, err = conn.Exec(ctx, `
+ CREATE TABLE rectangles (
+ id SERIAL PRIMARY KEY,
+ length NUMERIC NOT NULL,
+ width NUMERIC NOT NULL,
+ area NUMERIC GENERATED ALWAYS AS (length * width) STORED
+ )`)
+ assert.ErrorContains(t, err, "syntax error")
+}
+
+func testUnloggedTableIssue(t *testing.T) {
+ ctx := context.Background()
+ conn, err := getConn()
+ assert.NoError(t, err)
+
+ defer conn.Close(context.Background())
+ _, err = conn.Exec(ctx, "CREATE UNLOGGED TABLE unlogged_table (a int)")
+ assert.ErrorContains(t, err, "UNLOGGED database object not supported yet")
+}
+
+func TestDDLIssuesInYBVersion(t *testing.T) {
+ ybVersion := os.Getenv("YB_VERSION")
+ if ybVersion == "" {
+ panic("YB_VERSION env variable is not set. Set YB_VERSIONS=2024.1.3.0-b105 for example")
+ }
+
+ yugabytedbConnStr = os.Getenv("YB_CONN_STR")
+ if yugabytedbConnStr == "" {
+ // spawn yugabytedb container
+ var err error
+ ctx := context.Background()
+ yugabytedbContainer, err = yugabytedb.Run(
+ ctx,
+ "yugabytedb/yugabyte:"+ybVersion,
+ )
+ assert.NoError(t, err)
+ defer yugabytedbContainer.Terminate(context.Background())
+ }
+
+ // run tests
+ var success bool
+ success = t.Run(fmt.Sprintf("%s-%s", "xml functions", ybVersion), testXMLFunctionIssue)
+ assert.True(t, success)
+
+ success = t.Run(fmt.Sprintf("%s-%s", "stored generated functions", ybVersion), testStoredGeneratedFunctionsIssue)
+ assert.True(t, success)
+
+ success = t.Run(fmt.Sprintf("%s-%s", "unlogged table", ybVersion), testUnloggedTableIssue)
+ assert.True(t, success)
+
+}