Skip to content

Commit

Permalink
Added a few more unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ShivanshGahlot committed Dec 20, 2024
1 parent c0f2b77 commit 788e744
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
4 changes: 2 additions & 2 deletions yb-voyager/src/query/queryissue/issues_dml.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ var copyFromWhereIssue = issue.Issue{
TypeDescription: "",
Suggestion: "",
GH: "",
DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#copy-from-where-is-not-yet-supported",
DocsLink: "",
}

func NewCopyFromWhereIssue(objectType string, objectName string, sqlStatement string) QueryIssue {
Expand All @@ -89,7 +89,7 @@ var copyOnErrorIssue = issue.Issue{
TypeDescription: "",
Suggestion: "",
GH: "",
DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#copy-on-error-is-not-yet-supported",
DocsLink: "",
}

func NewCopyOnErrorIssue(objectType string, objectName string, sqlStatement string) QueryIssue {
Expand Down
27 changes: 27 additions & 0 deletions yb-voyager/src/query/queryissue/issues_dml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,29 @@ func testLOFunctionsIssue(t *testing.T) {
assertErrorCorrectlyThrownForIssueForYBVersion(t, err, "Transaction for catalog table write operation 'pg_largeobject_metadata' not found", loDatatypeIssue)
}

func testCopyOnErrorIssue(t *testing.T) {
ctx := context.Background()
conn, err := getConn()
assert.NoError(t, err)

defer conn.Close(context.Background())
// In case the COPY ... ON_ERROR construct gets supported in the future, this test will fail with a different error message-something related to the data.csv file not being found.
_, err = conn.Exec(ctx, `COPY pg_largeobject (loid, pageno, data) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR IGNORE);`)
assertErrorCorrectlyThrownForIssueForYBVersion(t, err, "ERROR: option \"on_error\" not recognized (SQLSTATE 42601)", copyOnErrorIssue)

}

func testCopyFromWhereIssue(t *testing.T) {
ctx := context.Background()
conn, err := getConn()
assert.NoError(t, err)

defer conn.Close(context.Background())
// In case the COPY FROM ... WHERE construct gets supported in the future, this test will fail with a different error message-something related to the data.csv file not being found.
_, err = conn.Exec(ctx, `COPY pg_largeobject (loid, pageno, data) FROM '/path/to/data.csv' WHERE loid = 1 WITH (FORMAT csv, HEADER true);`)
assertErrorCorrectlyThrownForIssueForYBVersion(t, err, "ERROR: syntax error at or near \"WHERE\" (SQLSTATE 42601)", copyFromWhereIssue)
}

func TestDMLIssuesInYBVersion(t *testing.T) {
var err error
ybVersion := os.Getenv("YB_VERSION")
Expand Down Expand Up @@ -68,4 +91,8 @@ func TestDMLIssuesInYBVersion(t *testing.T) {
success := t.Run(fmt.Sprintf("%s-%s", "lo functions", ybVersion), testLOFunctionsIssue)
assert.True(t, success)

success = t.Run(fmt.Sprintf("%s-%s", "copy on error", ybVersion), testCopyOnErrorIssue)
assert.True(t, success)

success = t.Run(fmt.Sprintf("%s-%s", "copy from where", ybVersion), testCopyFromWhereIssue)
}
38 changes: 36 additions & 2 deletions yb-voyager/src/query/queryissue/parser_issue_detector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ BEGIN
END;
$$ LANGUAGE plpgsql;
`,
`CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
`CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
FOR EACH ROW EXECUTE FUNCTION lo_manage(raster);`,
}

Expand Down Expand Up @@ -448,7 +448,6 @@ $$ LANGUAGE plpgsql;
expectedSQLsWithIssues[sqls[3]] = modifyiedIssuesforPLPGSQL(expectedSQLsWithIssues[sqls[3]], "PROCEDURE", "read_large_object")
expectedSQLsWithIssues[sqls[4]] = modifyiedIssuesforPLPGSQL(expectedSQLsWithIssues[sqls[4]], "FUNCTION", "write_to_large_object")


parserIssueDetector := NewParserIssueDetector()

for stmt, expectedIssues := range expectedSQLsWithIssues {
Expand All @@ -466,6 +465,7 @@ $$ LANGUAGE plpgsql;
}
}
}

// currently, both FuncCallDetector and XmlExprDetector can detect XMLFunctionsIssue
// statement below has both XML functions and XML expressions.
// but we want to only return one XMLFunctionsIssue from parserIssueDetector.getDMLIssues
Expand All @@ -485,3 +485,37 @@ func TestSingleXMLIssueIsDetected(t *testing.T) {
fatalIfError(t, err)
assert.Equal(t, 1, len(issues))
}

func TestCopyUnsupportedConstructIssuesDetected(t *testing.T) {
expectedIssues := map[string][]QueryIssue{
`COPY my_table FROM '/path/to/data.csv' WHERE col1 > 100;`: {NewCopyFromWhereIssue("DML_QUERY", "", `COPY my_table FROM '/path/to/data.csv' WHERE col1 > 100;`)},
`COPY my_table(col1, col2) FROM '/path/to/data.csv' WHERE col2 = 'test';`: {NewCopyFromWhereIssue("DML_QUERY", "", `COPY my_table(col1, col2) FROM '/path/to/data.csv' WHERE col2 = 'test';`)},
`COPY my_table FROM '/path/to/data.csv' WHERE TRUE;`: {NewCopyFromWhereIssue("DML_QUERY", "", `COPY my_table FROM '/path/to/data.csv' WHERE TRUE;`)},

`COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR IGNORE);`: {NewCopyOnErrorIssue("DML_QUERY", "", `COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR IGNORE);`)},
`COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR STOP);`: {NewCopyOnErrorIssue("DML_QUERY", "", `COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR STOP);`)},

`COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR IGNORE) WHERE age > 18;`: {NewCopyFromWhereIssue("DML_QUERY", "", `COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR IGNORE) WHERE age > 18;`), NewCopyOnErrorIssue("DML_QUERY", "", `COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR IGNORE) WHERE age > 18;`)},
`COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR STOP) WHERE name = 'Alice';`: {NewCopyFromWhereIssue("DML_QUERY", "", `COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR STOP) WHERE name = 'Alice';`), NewCopyOnErrorIssue("DML_QUERY", "", `COPY table_name (name, age) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true, ON_ERROR STOP) WHERE name = 'Alice';`)},

`COPY my_table FROM '/path/to/data.csv' WITH (FORMAT csv);`: {},
`COPY my_table FROM '/path/to/data.csv' WITH (FORMAT text);`: {},
`COPY my_table FROM '/path/to/data.csv';`: {},
`COPY my_table FROM '/path/to/data.csv' WITH (DELIMITER ',');`: {},
`COPY my_table(col1, col2) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true);`: {},
}

parserIssueDetector := NewParserIssueDetector()

for stmt, expectedIssues := range expectedIssues {
issues, err := parserIssueDetector.getDMLIssues(stmt)
fatalIfError(t, err)
assert.Equal(t, len(expectedIssues), len(issues))
for _, expectedIssue := range expectedIssues {
found := slices.ContainsFunc(issues, func(queryIssue QueryIssue) bool {
return cmp.Equal(expectedIssue, queryIssue)
})
assert.True(t, found)
}
}
}

0 comments on commit 788e744

Please sign in to comment.