Improvements on sub-query projection reference.

This commit is contained in:
go-jet 2019-06-18 14:35:32 +02:00
parent d9ffa86453
commit 565b670188
17 changed files with 512 additions and 134 deletions

View file

@ -356,6 +356,185 @@ func TestTimeOperators(t *testing.T) {
assert.NilError(t, err)
}
func TestSubQueryColumnReference(t *testing.T) {
type expected struct {
sql string
args []interface{}
}
subQueries := map[ExpressionTable]expected{}
selectSubQuery := AllTypes.SELECT(
AllTypes.Boolean,
AllTypes.Integer,
AllTypes.Real,
AllTypes.Text,
AllTypes.Time,
AllTypes.Timez,
AllTypes.Timestamp,
AllTypes.Timestampz,
AllTypes.Date,
AllTypes.Bytea.AS("aliasedColumn"),
).
LIMIT(2).
AsTable("subQuery")
var selectExpectedSql = ` (
SELECT all_types.boolean AS "all_types.boolean",
all_types.integer AS "all_types.integer",
all_types.real AS "all_types.real",
all_types.text AS "all_types.text",
all_types.time AS "all_types.time",
all_types.timez AS "all_types.timez",
all_types.timestamp AS "all_types.timestamp",
all_types.timestampz AS "all_types.timestampz",
all_types.date AS "all_types.date",
all_types.bytea AS "aliasedColumn"
FROM test_sample.all_types
LIMIT 2
) AS "subQuery"`
unionSubQuery :=
UNION_ALL(
AllTypes.SELECT(
AllTypes.Boolean,
AllTypes.Integer,
AllTypes.Real,
AllTypes.Text,
AllTypes.Time,
AllTypes.Timez,
AllTypes.Timestamp,
AllTypes.Timestampz,
AllTypes.Date,
AllTypes.Bytea.AS("aliasedColumn"),
).
LIMIT(1),
AllTypes.SELECT(
AllTypes.Boolean,
AllTypes.Integer,
AllTypes.Real,
AllTypes.Text,
AllTypes.Time,
AllTypes.Timez,
AllTypes.Timestamp,
AllTypes.Timestampz,
AllTypes.Date,
AllTypes.Bytea.AS("aliasedColumn"),
).
LIMIT(1).OFFSET(1),
).
AsTable("subQuery")
unionExpectedSql := `
(
(
SELECT all_types.boolean AS "all_types.boolean",
all_types.integer AS "all_types.integer",
all_types.real AS "all_types.real",
all_types.text AS "all_types.text",
all_types.time AS "all_types.time",
all_types.timez AS "all_types.timez",
all_types.timestamp AS "all_types.timestamp",
all_types.timestampz AS "all_types.timestampz",
all_types.date AS "all_types.date",
all_types.bytea AS "aliasedColumn"
FROM test_sample.all_types
LIMIT 1
)
UNION ALL
(
SELECT all_types.boolean AS "all_types.boolean",
all_types.integer AS "all_types.integer",
all_types.real AS "all_types.real",
all_types.text AS "all_types.text",
all_types.time AS "all_types.time",
all_types.timez AS "all_types.timez",
all_types.timestamp AS "all_types.timestamp",
all_types.timestampz AS "all_types.timestampz",
all_types.date AS "all_types.date",
all_types.bytea AS "aliasedColumn"
FROM test_sample.all_types
LIMIT 1
OFFSET 1
)
) AS "subQuery"`
subQueries[selectSubQuery] = expected{sql: selectExpectedSql, args: []interface{}{int64(2)}}
subQueries[unionSubQuery] = expected{sql: unionExpectedSql, args: []interface{}{int64(1), int64(1), int64(1)}}
for subQuery, expected := range subQueries {
boolColumn := AllTypes.Boolean.From(subQuery)
intColumn := AllTypes.Integer.From(subQuery)
floatColumn := AllTypes.Real.From(subQuery)
stringColumn := AllTypes.Text.From(subQuery)
timeColumn := AllTypes.Time.From(subQuery)
timezColumn := AllTypes.Timez.From(subQuery)
timestampColumn := AllTypes.Timestamp.From(subQuery)
timestampzColumn := AllTypes.Timestampz.From(subQuery)
dateColumn := AllTypes.Date.From(subQuery)
aliasedColumn := StringColumn("aliasedColumn").From(subQuery)
stmt1 := SELECT(
boolColumn,
intColumn,
floatColumn,
stringColumn,
timeColumn,
timezColumn,
timestampColumn,
timestampzColumn,
dateColumn,
aliasedColumn,
).
FROM(subQuery)
var expectedSql = `
SELECT "subQuery"."all_types.boolean" AS "all_types.boolean",
"subQuery"."all_types.integer" AS "all_types.integer",
"subQuery"."all_types.real" AS "all_types.real",
"subQuery"."all_types.text" AS "all_types.text",
"subQuery"."all_types.time" AS "all_types.time",
"subQuery"."all_types.timez" AS "all_types.timez",
"subQuery"."all_types.timestamp" AS "all_types.timestamp",
"subQuery"."all_types.timestampz" AS "all_types.timestampz",
"subQuery"."all_types.date" AS "all_types.date",
"subQuery"."aliasedColumn" AS "aliasedColumn"
FROM`
assertStatementSql(t, stmt1, expectedSql+expected.sql+";\n", expected.args...)
dest1 := []model.AllTypes{}
err := stmt1.Query(db, &dest1)
assert.NilError(t, err)
assert.Equal(t, len(dest1), 2)
assert.Equal(t, dest1[0].Boolean, allTypesRow0.Boolean)
assert.Equal(t, dest1[0].Integer, allTypesRow0.Integer)
assert.Equal(t, dest1[0].Real, allTypesRow0.Real)
assert.Equal(t, dest1[0].Text, allTypesRow0.Text)
assert.DeepEqual(t, dest1[0].Time, allTypesRow0.Time)
assert.DeepEqual(t, dest1[0].Timez, allTypesRow0.Timez)
assert.DeepEqual(t, dest1[0].Timestamp, allTypesRow0.Timestamp)
assert.DeepEqual(t, dest1[0].Timestampz, allTypesRow0.Timestampz)
assert.DeepEqual(t, dest1[0].Date, allTypesRow0.Date)
stmt2 := SELECT(
subQuery.AllColumns(),
).
FROM(subQuery)
fmt.Println(stmt2.DebugSql())
assertStatementSql(t, stmt2, expectedSql+expected.sql+";\n", expected.args...)
dest2 := []model.AllTypes{}
err = stmt2.Query(db, &dest2)
assert.NilError(t, err)
assert.DeepEqual(t, dest1, dest2)
}
}
var allTypesRow0 = model.AllTypes{
SmallintPtr: int16Ptr(1),
Smallint: 1,

View file

@ -3,6 +3,7 @@ package tests
import (
"encoding/json"
"fmt"
"github.com/davecgh/go-spew/spew"
. "github.com/go-jet/jet/sqlbuilder"
"github.com/go-jet/jet/tests/.test_files/dvd_rental/chinook/model"
. "github.com/go-jet/jet/tests/.test_files/dvd_rental/chinook/table"
@ -151,6 +152,65 @@ ORDER BY "Album.AlbumId";
assert.DeepEqual(t, dest[1], album2)
}
func TestSubQueriesForQuotedNames(t *testing.T) {
first10Artist := Artist.
SELECT(Artist.AllColumns).
ORDER_BY(Artist.ArtistId).
LIMIT(10).
AsTable("first10Artist")
artistId := Artist.ArtistId.From(first10Artist)
first10Albums := Album.
SELECT(Album.AllColumns).
ORDER_BY(Album.AlbumId).
LIMIT(10).
AsTable("first10Albums")
albumArtistId := Album.ArtistId.From(first10Albums)
stmt := first10Artist.
INNER_JOIN(first10Albums, artistId.EQ(albumArtistId)).
SELECT(first10Artist.AllColumns(), first10Albums.AllColumns()).
ORDER_BY(artistId)
assertStatementSql(t, stmt, `
SELECT "first10Artist"."Artist.ArtistId" AS "Artist.ArtistId",
"first10Artist"."Artist.Name" AS "Artist.Name",
"first10Albums"."Album.AlbumId" AS "Album.AlbumId",
"first10Albums"."Album.Title" AS "Album.Title",
"first10Albums"."Album.ArtistId" AS "Album.ArtistId"
FROM (
SELECT "Artist"."ArtistId" AS "Artist.ArtistId",
"Artist"."Name" AS "Artist.Name"
FROM chinook."Artist"
ORDER BY "Artist"."ArtistId"
LIMIT 10
) AS "first10Artist"
INNER JOIN (
SELECT "Album"."AlbumId" AS "Album.AlbumId",
"Album"."Title" AS "Album.Title",
"Album"."ArtistId" AS "Album.ArtistId"
FROM chinook."Album"
ORDER BY "Album"."AlbumId"
LIMIT 10
) AS "first10Albums" ON ("first10Artist"."Artist.ArtistId" = "first10Albums"."Album.ArtistId")
ORDER BY "first10Artist"."Artist.ArtistId";
`, int64(10), int64(10))
var dest []struct {
model.Artist
Album []model.Album
}
err := stmt.Query(db, &dest)
assert.NilError(t, err)
spew.Dump(dest)
}
func assertJson(t *testing.T, jsonFilePath string, data interface{}) {
fileJsonData, err := ioutil.ReadFile(jsonFilePath)
assert.NilError(t, err)

View file

@ -907,7 +907,7 @@ SELECT customer.customer_id AS "customer.customer_id",
customer.create_date AS "customer.create_date",
customer.last_update AS "customer.last_update",
customer.active AS "customer.active",
customer_payment_sum.amount_sum AS "customer_with_amounts.amount_sum"
customer_payment_sum."amount_sum" AS "CustomerWithAmounts.AmountSum"
FROM dvds.customer
INNER JOIN (
SELECT payment.customer_id AS "payment.customer_id",
@ -915,7 +915,7 @@ FROM dvds.customer
FROM dvds.payment
GROUP BY payment.customer_id
) AS customer_payment_sum ON (customer.customer_id = customer_payment_sum."payment.customer_id")
ORDER BY customer_payment_sum.amount_sum ASC;
ORDER BY customer_payment_sum."amount_sum" ASC;
`
customersPayments := Payment.
@ -933,7 +933,7 @@ ORDER BY customer_payment_sum.amount_sum ASC;
INNER_JOIN(customersPayments, Customer.CustomerID.EQ(customerId)).
SELECT(
Customer.AllColumns,
amountSum.AS("customer_with_amounts.amount_sum"),
amountSum.AS("CustomerWithAmounts.AmountSum"),
).
ORDER_BY(amountSum.ASC())

View file

@ -17,6 +17,7 @@ func assertStatementSql(t *testing.T, query sqlbuilder.Statement, expectedQuery
assert.DeepEqual(t, args, expectedArgs)
debuqSql, err := query.DebugSql()
assert.NilError(t, err)
assert.Equal(t, debuqSql, expectedQuery)
}