Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions internal/diff/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,15 @@ func compareExpressions(expr1, expr2 *pg_query.Node) bool {
return compareCoalesceExprs(coalesceExpr1, coalesceExpr2)
}

// Handle NullTest (IS NULL, IS NOT NULL)
if nullTest1 := expr1.GetNullTest(); nullTest1 != nil {
nullTest2 := expr2.GetNullTest()
if nullTest2 == nil {
return false
}
return compareNullTests(nullTest1, nullTest2)
}

// TODO: Add other expression types as needed

return false
Expand Down Expand Up @@ -569,6 +578,21 @@ func getColumnName(colRef *pg_query.ColumnRef) string {
return ""
}

// compareNullTests compares NULL test expressions (IS NULL, IS NOT NULL)
func compareNullTests(null1, null2 *pg_query.NullTest) bool {
if null1 == nil || null2 == nil {
return null1 == null2
}

// Must have the same null test type (IS NULL vs IS NOT NULL)
if null1.Nulltesttype != null2.Nulltesttype {
return false
}

// Compare the argument expressions
return compareExpressions(null1.Arg, null2.Arg)
}

// compareAConsts compares constant values
func compareAConsts(const1, const2 *pg_query.A_Const) bool {
if const1 == nil || const2 == nil {
Expand Down
18 changes: 18 additions & 0 deletions ir/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ func (f *postgreSQLFormatter) formatExpression(expr *pg_query.Node) {
f.formatSubLink(expr.GetSubLink())
case expr.GetCoalesceExpr() != nil:
f.formatCoalesceExpr(expr.GetCoalesceExpr())
case expr.GetNullTest() != nil:
f.formatNullTest(expr.GetNullTest())
default:
// Fallback to deparse for complex expressions
if deparseResult, err := f.deparseNode(expr); err == nil {
Expand Down Expand Up @@ -550,3 +552,19 @@ func (f *postgreSQLFormatter) formatSubLink(subLink *pg_query.SubLink) {
f.buffer.WriteString(deparseResult)
}
}

// formatNullTest formats NULL test expressions (IS NULL, IS NOT NULL)
func (f *postgreSQLFormatter) formatNullTest(nullTest *pg_query.NullTest) {
// Format the argument expression
if nullTest.Arg != nil {
f.formatExpression(nullTest.Arg)
}

// Add the appropriate NULL test operator
switch nullTest.Nulltesttype {
case pg_query.NullTestType_IS_NULL:
f.buffer.WriteString(" IS NULL")
case pg_query.NullTestType_IS_NOT_NULL:
f.buffer.WriteString(" IS NOT NULL")
}
}
14 changes: 8 additions & 6 deletions testdata/diff/create_view/add_view/diff.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
CREATE OR REPLACE VIEW active_employees AS
CREATE OR REPLACE VIEW employee_department_view AS
SELECT
id,
name,
salary
FROM employees
WHERE status = 'active';
e.id,
e.name AS employee_name,
d.name AS department_name,
d.manager_id
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE e.name IS NOT NULL AND d.manager_id IS NOT NULL;
27 changes: 17 additions & 10 deletions testdata/diff/create_view/add_view/new.sql
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
CREATE TABLE public.employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
salary DECIMAL(10,2) NOT NULL,
status VARCHAR(20) DEFAULT 'active'
name VARCHAR(100),
department_id INTEGER
);

CREATE VIEW public.active_employees AS
SELECT
id,
name,
salary
FROM employees
WHERE status = 'active';
CREATE TABLE public.departments (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
manager_id INTEGER
);

CREATE VIEW public.employee_department_view AS
SELECT
e.id,
e.name AS employee_name,
d.name AS department_name,
d.manager_id
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE e.name IS NOT NULL AND d.manager_id IS NOT NULL;
11 changes: 8 additions & 3 deletions testdata/diff/create_view/add_view/old.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CREATE TABLE public.employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
salary DECIMAL(10,2) NOT NULL,
status VARCHAR(20) DEFAULT 'active'
name VARCHAR(100),
department_id INTEGER
);

CREATE TABLE public.departments (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
manager_id INTEGER
);
8 changes: 4 additions & 4 deletions testdata/diff/create_view/add_view/plan.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"version": "1.0.0",
"pgschema_version": "1.0.0",
"pgschema_version": "1.2.0",
"created_at": "1970-01-01T00:00:00Z",
"source_fingerprint": {
"hash": "9d5778b7b11d01c6ae81040401fac81834395f4d86bd09b45077a694a1301edd"
"hash": "95ad22fa390833179c9661028a1d5b17d27f87223dac3481576654941198336c"
},
"groups": [
{
"steps": [
{
"sql": "CREATE OR REPLACE VIEW active_employees AS\n SELECT\n id,\n name,\n salary\n FROM employees\n WHERE status = 'active';",
"sql": "CREATE OR REPLACE VIEW employee_department_view AS\n SELECT\n e.id,\n e.name AS employee_name,\n d.name AS department_name,\n d.manager_id\n FROM employees e\n JOIN departments d ON e.department_id = d.id\n WHERE e.name IS NOT NULL AND d.manager_id IS NOT NULL;",
"type": "view",
"operation": "create",
"path": "public.active_employees"
"path": "public.employee_department_view"
}
]
}
Expand Down
14 changes: 8 additions & 6 deletions testdata/diff/create_view/add_view/plan.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
CREATE OR REPLACE VIEW active_employees AS
CREATE OR REPLACE VIEW employee_department_view AS
SELECT
id,
name,
salary
FROM employees
WHERE status = 'active';
e.id,
e.name AS employee_name,
d.name AS department_name,
d.manager_id
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE e.name IS NOT NULL AND d.manager_id IS NOT NULL;
16 changes: 9 additions & 7 deletions testdata/diff/create_view/add_view/plan.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ Summary by type:
views: 1 to add

Views:
+ active_employees
+ employee_department_view

DDL to be executed:
--------------------------------------------------

CREATE OR REPLACE VIEW active_employees AS
CREATE OR REPLACE VIEW employee_department_view AS
SELECT
id,
name,
salary
FROM employees
WHERE status = 'active';
e.id,
e.name AS employee_name,
d.name AS department_name,
d.manager_id
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE e.name IS NOT NULL AND d.manager_id IS NOT NULL;