From 5c8935fd374a331ba25cb62a1d8ec7f24119a922 Mon Sep 17 00:00:00 2001 From: Christopher Hlubek Date: Wed, 26 Jun 2024 13:09:02 +0200 Subject: [PATCH] Implement ANY/ALL Fixes #7 --- builder/functions_subquery_comparison.go | 36 ++++++++++++++++++++++++ root.go | 10 +++++++ select_builder_test.go | 34 ++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 builder/functions_subquery_comparison.go diff --git a/builder/functions_subquery_comparison.go b/builder/functions_subquery_comparison.go new file mode 100644 index 0000000..b973fea --- /dev/null +++ b/builder/functions_subquery_comparison.go @@ -0,0 +1,36 @@ +package builder + +type subqueryExp struct { + op string + exp Exp +} + +func (s subqueryExp) IsExp() {} + +func (s subqueryExp) WriteSQL(sb *SQLBuilder) { + sb.WriteString(s.op) + sb.WriteRune(' ') + + _, isSelect := s.exp.(SelectExp) + if !isSelect { + sb.WriteRune('(') + } + s.exp.WriteSQL(sb) + if !isSelect { + sb.WriteRune(')') + } +} + +func Any(exp Exp) Exp { + return subqueryExp{ + op: "ANY", + exp: exp, + } +} + +func All(exp Exp) Exp { + return subqueryExp{ + op: "ALL", + exp: exp, + } +} diff --git a/root.go b/root.go index c2d78bd..a366750 100644 --- a/root.go +++ b/root.go @@ -158,6 +158,16 @@ func Exists(subquery builder.SelectExp) builder.Exp { return builder.Exists(subquery) } +// --- Row and Array Comparisons + +func Any(exp builder.Exp) builder.Exp { + return builder.Any(exp) +} + +func All(exp builder.Exp) builder.Exp { + return builder.All(exp) +} + // --- Commands func InsertInto(tableName builder.Identer) builder.InsertBuilder { diff --git a/select_builder_test.go b/select_builder_test.go index 4e557a1..f3eadf5 100644 --- a/select_builder_test.go +++ b/select_builder_test.go @@ -937,6 +937,40 @@ func TestSelectBuilder_Where(t *testing.T) { q, ) }) + + t.Run("where all with subselect", func(t *testing.T) { + q := qrb.Select(qrb.N("*")). + From(qrb.N("employees")). + Where(qrb.N("salary").Gt(qrb.All(qrb.Select(qrb.N("salary")).From(qrb.N("managers"))))) + + testhelper.AssertSQLWriterEquals( + t, + ` + SELECT * + FROM employees + WHERE salary > ALL (SELECT salary FROM managers) + `, + nil, + q, + ) + }) + + t.Run("where any with array", func(t *testing.T) { + q := qrb.Select(qrb.N("*")). + From(qrb.N("table")). + Where(qrb.N("column").Eq(qrb.Any(qrb.Array(qrb.Int(1), qrb.Int(2), qrb.Int(3))))) + + testhelper.AssertSQLWriterEquals( + t, + ` + SELECT * + FROM table + WHERE column = ANY (ARRAY[1, 2, 3]) + `, + nil, + q, + ) + }) } func TestSelectBuilder_GroupBy(t *testing.T) {