From 392ba63bc5d2fe483c4914ab18595f5ea1f2d80c Mon Sep 17 00:00:00 2001 From: go-jet Date: Thu, 30 Dec 2021 16:23:59 +0100 Subject: [PATCH] Add helper method to set ProjectionList alias. --- internal/jet/projection.go | 22 ++++++++++++++ tests/postgres/with_test.go | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/internal/jet/projection.go b/internal/jet/projection.go index b85702f..16abe5b 100644 --- a/internal/jet/projection.go +++ b/internal/jet/projection.go @@ -1,5 +1,7 @@ package jet +import "strings" + // Projection is interface for all projection types. Types that can be part of, for instance SELECT clause. type Projection interface { serializeForProjection(statement StatementType, out *SQLBuilder) @@ -27,3 +29,23 @@ func (cl ProjectionList) fromImpl(subQuery SelectTable) Projection { func (cl ProjectionList) serializeForProjection(statement StatementType, out *SQLBuilder) { SerializeProjectionList(statement, cl, out) } + +// As is used to set aliases of the projection list. alias should be in the form 'name' or 'name.*'. +// For instance: If projection list has a column 'Artist.Name', and alias is 'Musician.*', returned projection list will +// have column wrapped in alias 'Musician.Name'. +func (cl ProjectionList) As(alias string) ProjectionList { + alias = strings.TrimRight(alias, ".*") + + newProjectionList := ProjectionList{} + + for _, projection := range cl { + switch p := projection.(type) { + case ProjectionList: + newProjectionList = append(newProjectionList, p.As(alias)) + case ColumnExpression: + newProjectionList = append(newProjectionList, newAlias(p, alias+"."+p.Name())) + } + } + + return newProjectionList +} diff --git a/tests/postgres/with_test.go b/tests/postgres/with_test.go index 27d5ce0..3b682d8 100644 --- a/tests/postgres/with_test.go +++ b/tests/postgres/with_test.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "fmt" "github.com/go-jet/jet/v2/internal/testutils" . "github.com/go-jet/jet/v2/postgres" "github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/northwind/model" @@ -746,3 +747,62 @@ WHERE not_from_us_or_aus."suppliers.contact_name" != 'John'; require.NoError(t, err) require.Len(t, dest, 11) } + +func TestWitStatement_CTE_NotMaterialized(t *testing.T) { + orders1 := CTE("orders1") + orders1ID := Orders.OrderID.From(orders1) + orders2 := orders1.ALIAS("orders2") + orders2ID := Orders.OrderID.From(orders2) + + stmt := WITH( + orders1.AS_NOT_MATERIALIZED( + SELECT( + Orders.OrderID, + Orders.EmployeeID, + Orders.ShipCity, + ).FROM( + Orders, + ), + ), + )( + SELECT( + orders1.AllColumns().As("orders1.*"), + orders2.AllColumns().As("orders2.*"), + ).FROM( + orders1. + INNER_JOIN(orders2, orders1ID.EQ(orders2ID)), + ).WHERE( + orders1ID.LT(Int(10320)), + ), + ) + + // fmt.Println(stmt.Sql()) + + testutils.AssertStatementSql(t, stmt, ` +WITH orders1 AS NOT MATERIALIZED ( + SELECT orders.order_id AS "orders.order_id", + orders.employee_id AS "orders.employee_id", + orders.ship_city AS "orders.ship_city" + FROM northwind.orders +) +SELECT orders1."orders.order_id" AS "orders1.order_id", + orders1."orders.employee_id" AS "orders1.employee_id", + orders1."orders.ship_city" AS "orders1.ship_city", + orders2."orders.order_id" AS "orders2.order_id", + orders2."orders.employee_id" AS "orders2.employee_id", + orders2."orders.ship_city" AS "orders2.ship_city" +FROM orders1 + INNER JOIN orders1 AS orders2 ON (orders1."orders.order_id" = orders2."orders.order_id") +WHERE orders1."orders.order_id" < $1; +`) + + var dest []struct { + Orders1 model.Orders `alias:"orders1.*"` + Orders2 model.Orders `alias:"orders2.*"` + } + + err := stmt.Query(db, &dest) + require.NoError(t, err) + require.Len(t, dest, 72) + fmt.Println(len(dest)) +}