From 0cba1f6401957d597dbd58e0d69a0d7f46190bf9 Mon Sep 17 00:00:00 2001 From: go-jet Date: Fri, 16 Oct 2020 13:26:53 +0200 Subject: [PATCH] Lateral - initial commit. --- internal/jet/select_table.go | 22 ++++++++++++++++++++-- postgres/lateral.go | 13 +++++++++++++ postgres/lateral_test.go | 9 +++++++++ tests/postgres/select_test.go | 31 +++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 postgres/lateral.go create mode 100644 postgres/lateral_test.go diff --git a/internal/jet/select_table.go b/internal/jet/select_table.go index 52689d4..1421b14 100644 --- a/internal/jet/select_table.go +++ b/internal/jet/select_table.go @@ -13,8 +13,8 @@ type selectTableImpl struct { } // NewSelectTable func -func NewSelectTable(selectStmt SerializerStatement, alias string) SelectTable { - selectTable := &selectTableImpl{selectStmt: selectStmt, alias: alias} +func NewSelectTable(selectStmt SerializerStatement, alias string) selectTableImpl { + selectTable := selectTableImpl{selectStmt: selectStmt, alias: alias} return selectTable } @@ -38,3 +38,21 @@ func (s selectTableImpl) serialize(statement StatementType, out *SQLBuilder, opt out.WriteString("AS") out.WriteIdentifier(s.alias) } + +// -------------------------------------- + +type lateralImpl struct { + selectTableImpl +} + +func NewLateral(selectStmt SerializerStatement, alias string) SelectTable { + return lateralImpl{selectTableImpl: NewSelectTable(selectStmt, alias)} +} + +func (s lateralImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { + out.WriteString("LATERAL") + s.selectStmt.serialize(statement, out) + + out.WriteString("AS") + out.WriteIdentifier(s.alias) +} diff --git a/postgres/lateral.go b/postgres/lateral.go new file mode 100644 index 0000000..fbbe953 --- /dev/null +++ b/postgres/lateral.go @@ -0,0 +1,13 @@ +package postgres + +import "github.com/go-jet/jet/v2/internal/jet" + +func LATERAL(selectStmt SelectStatement, alias string) SelectTable { + subQuery := &selectTableImpl{ + SelectTable: jet.NewLateral(selectStmt, alias), + } + + subQuery.readableTableInterfaceImpl.parent = subQuery + + return subQuery +} diff --git a/postgres/lateral_test.go b/postgres/lateral_test.go new file mode 100644 index 0000000..a401a1e --- /dev/null +++ b/postgres/lateral_test.go @@ -0,0 +1,9 @@ +package postgres + +import "testing" + +func TestLATERAL(t *testing.T) { + assertSerialize(t, LATERAL(SELECT(Int(1)), "lat1"), `LATERAL ( + SELECT $1 +) AS lat1`) +} diff --git a/tests/postgres/select_test.go b/tests/postgres/select_test.go index 8bd6f53..afa7230 100644 --- a/tests/postgres/select_test.go +++ b/tests/postgres/select_test.go @@ -1893,3 +1893,34 @@ WHERE ($1 AND (customer.customer_id = $2)) AND (customer.activebool = $3); require.Len(t, dest, 1) testutils.AssertDeepEqual(t, dest[0], customer0) } + +func TestLateral(t *testing.T) { + + languages := LATERAL( + SELECT( + Language.AllColumns, + ).FROM( + Language, + ).WHERE( + Language.Name.NOT_IN(String("spanish")). + AND(Film.LanguageID.EQ(Language.LanguageID)), + ), + "films") + + stmt := SELECT( + Film.AllColumns, + languages.AllColumns(), + ).FROM( + Film.CROSS_JOIN(languages), + ).WHERE( + Film.FilmID.EQ(Int(1)), + ) + + var dest []struct { + model.Film + model.Language + } + + err := stmt.Query(db, &dest) + require.NoError(t, err) +}