Add support for strict scan.
If there are unused columns in query result set Query method panics.
This commit is contained in:
parent
cfc264221b
commit
d86f14e665
9 changed files with 402 additions and 207 deletions
|
|
@ -145,7 +145,11 @@ LIMIT 30;
|
|||
|
||||
testutils.AssertDebugStatementSql(t, query, expectedSQL, int64(30))
|
||||
|
||||
var dest []model.Payment
|
||||
var dest []struct {
|
||||
model.Payment
|
||||
|
||||
Customer model.Customer
|
||||
}
|
||||
|
||||
err := query.Query(db, &dest)
|
||||
|
||||
|
|
@ -246,8 +250,10 @@ LIMIT 12;
|
|||
testutils.AssertDebugStatementSql(t, query, expectedSQL, int64(1), int64(1), int64(10), int64(1), int64(2), int64(1), int64(12))
|
||||
|
||||
var dest []struct{}
|
||||
err := query.Query(db, &dest)
|
||||
require.NoError(t, err)
|
||||
allowUnusedColumns(func() {
|
||||
err := query.Query(db, &dest)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSelectFetchFirst(t *testing.T) {
|
||||
|
|
@ -369,10 +375,7 @@ OFFSET (
|
|||
func TestSelectJoinQueryStruct(t *testing.T) {
|
||||
|
||||
expectedSQL := `
|
||||
SELECT film_actor.actor_id AS "film_actor.actor_id",
|
||||
film_actor.film_id AS "film_actor.film_id",
|
||||
film_actor.last_update AS "film_actor.last_update",
|
||||
film.film_id AS "film.film_id",
|
||||
SELECT film.film_id AS "film.film_id",
|
||||
film.title AS "film.title",
|
||||
film.description AS "film.description",
|
||||
film.release_year AS "film.release_year",
|
||||
|
|
@ -420,7 +423,6 @@ LIMIT 1000;
|
|||
INNER_JOIN(Inventory, Inventory.FilmID.EQ(Film.FilmID)).
|
||||
INNER_JOIN(Rental, Rental.InventoryID.EQ(Inventory.InventoryID)).
|
||||
SELECT(
|
||||
FilmActor.AllColumns,
|
||||
Film.AllColumns,
|
||||
Language.AllColumns,
|
||||
Actor.AllColumns,
|
||||
|
|
@ -1235,6 +1237,8 @@ func TestSelectOrderByAscDesc(t *testing.T) {
|
|||
|
||||
func TestSelectOrderBy(t *testing.T) {
|
||||
|
||||
var destRentals []model.Rental
|
||||
|
||||
t.Run("default", func(t *testing.T) {
|
||||
stmt := SELECT(
|
||||
Rental.AllColumns,
|
||||
|
|
@ -1256,7 +1260,8 @@ FROM dvds.rental
|
|||
ORDER BY rental.return_date
|
||||
LIMIT 200;
|
||||
`)
|
||||
require.NoError(t, stmt.Query(db, &struct{}{}))
|
||||
|
||||
require.NoError(t, stmt.Query(db, &destRentals))
|
||||
})
|
||||
|
||||
t.Run("NULLS FIRST", func(t *testing.T) {
|
||||
|
|
@ -1280,7 +1285,7 @@ FROM dvds.rental
|
|||
ORDER BY rental.return_date NULLS FIRST
|
||||
LIMIT 200;
|
||||
`)
|
||||
require.NoError(t, stmt.Query(db, &struct{}{}))
|
||||
require.NoError(t, stmt.Query(db, &destRentals))
|
||||
})
|
||||
|
||||
t.Run("NULLS LAST", func(t *testing.T) {
|
||||
|
|
@ -1304,7 +1309,7 @@ FROM dvds.rental
|
|||
ORDER BY rental.return_date NULLS LAST
|
||||
LIMIT 200;
|
||||
`)
|
||||
require.NoError(t, stmt.Query(db, &struct{}{}))
|
||||
require.NoError(t, stmt.Query(db, &destRentals))
|
||||
})
|
||||
|
||||
t.Run("ASC", func(t *testing.T) {
|
||||
|
|
@ -1328,7 +1333,7 @@ FROM dvds.rental
|
|||
ORDER BY rental.return_date ASC
|
||||
LIMIT 200;
|
||||
`)
|
||||
require.NoError(t, stmt.Query(db, &struct{}{}))
|
||||
require.NoError(t, stmt.Query(db, &destRentals))
|
||||
})
|
||||
|
||||
t.Run("ASC NULLS FIRST", func(t *testing.T) {
|
||||
|
|
@ -1353,7 +1358,7 @@ ORDER BY rental.return_date ASC NULLS FIRST
|
|||
LIMIT 200;
|
||||
`)
|
||||
|
||||
require.NoError(t, stmt.Query(db, &struct{}{}))
|
||||
require.NoError(t, stmt.Query(db, &destRentals))
|
||||
})
|
||||
|
||||
t.Run("ASC NULLS LAST", func(t *testing.T) {
|
||||
|
|
@ -1379,7 +1384,7 @@ LIMIT 200
|
|||
OFFSET 15800;
|
||||
`)
|
||||
|
||||
require.NoError(t, stmt.Query(db, &struct{}{}))
|
||||
require.NoError(t, stmt.Query(db, &destRentals))
|
||||
})
|
||||
|
||||
t.Run("DESC", func(t *testing.T) {
|
||||
|
|
@ -1405,7 +1410,7 @@ LIMIT 200
|
|||
OFFSET 15800;
|
||||
`)
|
||||
|
||||
require.NoError(t, stmt.Query(db, &struct{}{}))
|
||||
require.NoError(t, stmt.Query(db, &destRentals))
|
||||
})
|
||||
|
||||
t.Run("DESC NULLS LAST", func(t *testing.T) {
|
||||
|
|
@ -1431,7 +1436,7 @@ LIMIT 200
|
|||
OFFSET 15800;
|
||||
`)
|
||||
|
||||
require.NoError(t, stmt.Query(db, &struct{}{}))
|
||||
require.NoError(t, stmt.Query(db, &destRentals))
|
||||
})
|
||||
|
||||
t.Run("DESC NULLS FIRST", func(t *testing.T) {
|
||||
|
|
@ -1456,7 +1461,7 @@ ORDER BY rental.return_date DESC NULLS FIRST
|
|||
LIMIT 200;
|
||||
`)
|
||||
|
||||
require.NoError(t, stmt.Query(db, &struct{}{}))
|
||||
require.NoError(t, stmt.Query(db, &destRentals))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -1552,14 +1557,14 @@ LIMIT 1000;
|
|||
|
||||
testutils.AssertDebugStatementSql(t, query, expectedSQL, int64(1000))
|
||||
|
||||
var customerAddresCrosJoined []struct {
|
||||
var customerAddersCrossJoined []struct {
|
||||
model.Customer
|
||||
model.Address
|
||||
}
|
||||
|
||||
err := query.Query(db, &customerAddresCrosJoined)
|
||||
err := query.Query(db, &customerAddersCrossJoined)
|
||||
|
||||
require.Equal(t, len(customerAddresCrosJoined), 1000)
|
||||
require.Equal(t, len(customerAddersCrossJoined), 1000)
|
||||
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
|
@ -1682,7 +1687,6 @@ func TestSelectSubQuery(t *testing.T) {
|
|||
SELECT(
|
||||
rRatingFilms.AllColumns(),
|
||||
Actor.AllColumns,
|
||||
FilmActor.AllColumns,
|
||||
).FROM(
|
||||
rRatingFilms.
|
||||
INNER_JOIN(FilmActor, FilmActor.FilmID.EQ(rFilmID)).
|
||||
|
|
@ -1701,10 +1705,7 @@ SELECT "rFilms"."film.film_id" AS "film.film_id",
|
|||
actor.actor_id AS "actor.actor_id",
|
||||
actor.first_name AS "actor.first_name",
|
||||
actor.last_name AS "actor.last_name",
|
||||
actor.last_update AS "actor.last_update",
|
||||
film_actor.actor_id AS "film_actor.actor_id",
|
||||
film_actor.film_id AS "film_actor.film_id",
|
||||
film_actor.last_update AS "film_actor.last_update"
|
||||
actor.last_update AS "actor.last_update"
|
||||
FROM (
|
||||
SELECT film.film_id AS "film.film_id",
|
||||
film.title AS "film.title",
|
||||
|
|
@ -1871,9 +1872,7 @@ SELECT customer.customer_id AS "customer.customer_id",
|
|||
customer.active AS "customer.active",
|
||||
SUM(payment.amount) AS "amount.sum",
|
||||
AVG(payment.amount) AS "amount.avg",
|
||||
MAX(payment.payment_date) AS "amount.max_date",
|
||||
MAX(payment.amount) AS "amount.max",
|
||||
MIN(payment.payment_date) AS "amount.min_date",
|
||||
MIN(payment.amount) AS "amount.min",
|
||||
COUNT(payment.amount) AS "amount.count"
|
||||
FROM dvds.payment
|
||||
|
|
@ -1887,9 +1886,7 @@ ORDER BY customer.customer_id, SUM(payment.amount) ASC;
|
|||
|
||||
SUMf(Payment.Amount).AS("amount.sum"),
|
||||
AVG(Payment.Amount).AS("amount.avg"),
|
||||
MAX(Payment.PaymentDate).AS("amount.max_date"),
|
||||
MAXf(Payment.Amount).AS("amount.max"),
|
||||
MIN(Payment.PaymentDate).AS("amount.min_date"),
|
||||
MINf(Payment.Amount).AS("amount.min"),
|
||||
COUNT(Payment.Amount).AS("amount.count"),
|
||||
).FROM(
|
||||
|
|
@ -2795,8 +2792,10 @@ ORDER BY actor.actor_id ASC, film.film_id ASC;
|
|||
Actors []model.Actor
|
||||
}
|
||||
|
||||
err = stmt.Query(db, &dest2)
|
||||
require.NoError(t, err)
|
||||
allowUnusedColumns(func() {
|
||||
err = stmt.Query(db, &dest2)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
//testutils.SaveJSONFile(dest2, "./testdata/results/postgres/quick-start-dest2.json")
|
||||
testutils.AssertJSONFile(t, dest2, "./testdata/results/postgres/quick-start-dest2.json")
|
||||
|
|
@ -2819,18 +2818,19 @@ func TestSelectQuickStartWithSubQueries(t *testing.T) {
|
|||
|
||||
categoryID := Category.CategoryID.From(categoriesNotAction)
|
||||
|
||||
stmt := Actor.
|
||||
INNER_JOIN(FilmActor, Actor.ActorID.EQ(FilmActor.ActorID)).
|
||||
INNER_JOIN(filmLogerThan180, filmID.EQ(FilmActor.FilmID)).
|
||||
INNER_JOIN(Language, Language.LanguageID.EQ(filmLanguageID)).
|
||||
INNER_JOIN(FilmCategory, FilmCategory.FilmID.EQ(filmID)).
|
||||
INNER_JOIN(categoriesNotAction, categoryID.EQ(FilmCategory.CategoryID)).
|
||||
SELECT(
|
||||
Actor.AllColumns,
|
||||
filmLogerThan180.AllColumns(),
|
||||
Language.AllColumns,
|
||||
categoriesNotAction.AllColumns(),
|
||||
).ORDER_BY(
|
||||
stmt := SELECT(
|
||||
Actor.AllColumns,
|
||||
filmLogerThan180.AllColumns(),
|
||||
Language.AllColumns,
|
||||
categoriesNotAction.AllColumns(),
|
||||
).FROM(
|
||||
Actor.
|
||||
INNER_JOIN(FilmActor, Actor.ActorID.EQ(FilmActor.ActorID)).
|
||||
INNER_JOIN(filmLogerThan180, filmID.EQ(FilmActor.FilmID)).
|
||||
INNER_JOIN(Language, Language.LanguageID.EQ(filmLanguageID)).
|
||||
INNER_JOIN(FilmCategory, FilmCategory.FilmID.EQ(filmID)).
|
||||
INNER_JOIN(categoriesNotAction, categoryID.EQ(FilmCategory.CategoryID)),
|
||||
).ORDER_BY(
|
||||
Actor.ActorID.ASC(),
|
||||
filmID.ASC(),
|
||||
)
|
||||
|
|
@ -2860,8 +2860,10 @@ func TestSelectQuickStartWithSubQueries(t *testing.T) {
|
|||
Actors []model.Actor
|
||||
}
|
||||
|
||||
err = stmt.Query(db, &dest2)
|
||||
require.NoError(t, err)
|
||||
allowUnusedColumns(func() {
|
||||
err = stmt.Query(db, &dest2)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
//jsonSave("./testdata/quick-start-dest2.json", dest2)
|
||||
testutils.AssertJSONFile(t, dest2, "./testdata/results/postgres/quick-start-dest2.json")
|
||||
|
|
@ -2892,9 +2894,10 @@ SELECT true,
|
|||
'date';
|
||||
`)
|
||||
|
||||
dest := []struct{}{}
|
||||
err := query.Query(db, &dest)
|
||||
require.NoError(t, err)
|
||||
allowUnusedColumns(func() {
|
||||
err := query.Query(db, &[]struct{}{})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSelectWindowFunction(t *testing.T) {
|
||||
|
|
@ -2928,45 +2931,52 @@ FROM dvds.payment
|
|||
WHERE payment.payment_id < $3
|
||||
GROUP BY payment.amount, payment.customer_id, payment.payment_date;
|
||||
`
|
||||
query := Payment.
|
||||
SELECT(
|
||||
AVG(Payment.Amount).OVER(),
|
||||
AVG(Payment.Amount).OVER(PARTITION_BY(Payment.CustomerID)),
|
||||
MAXf(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate.DESC())),
|
||||
MINf(Payment.Amount).OVER(PARTITION_BY(Payment.CustomerID).ORDER_BY(Payment.PaymentDate.DESC())),
|
||||
SUMf(Payment.Amount).OVER(PARTITION_BY(Payment.CustomerID).
|
||||
ORDER_BY(Payment.PaymentDate.DESC()).ROWS(PRECEDING(1), FOLLOWING(6))),
|
||||
SUMf(Payment.Amount).OVER(PARTITION_BY(Payment.CustomerID).
|
||||
ORDER_BY(Payment.PaymentDate.DESC()).RANGE(PRECEDING(UNBOUNDED), FOLLOWING(UNBOUNDED))),
|
||||
MAXi(Payment.CustomerID).OVER(ORDER_BY(Payment.PaymentDate.DESC()).ROWS(CURRENT_ROW, FOLLOWING(UNBOUNDED))),
|
||||
MINi(Payment.CustomerID).OVER(PARTITION_BY(Payment.CustomerID).ORDER_BY(Payment.PaymentDate.DESC())),
|
||||
SUMi(Payment.CustomerID).OVER(PARTITION_BY(Payment.CustomerID).ORDER_BY(Payment.PaymentDate.DESC())),
|
||||
ROW_NUMBER().OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
RANK().OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
DENSE_RANK().OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
CUME_DIST().OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
NTILE(11).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAG(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAG(Payment.Amount, 2).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAG(Payment.Amount, 2, Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAG(Payment.Amount, 2, 100).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LEAD(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LEAD(Payment.Amount, 2).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LEAD(Payment.Amount, 2, Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LEAD(Payment.Amount, 2, 100).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
FIRST_VALUE(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAST_VALUE(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
NTH_VALUE(Payment.Amount, 3).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
).GROUP_BY(Payment.Amount, Payment.CustomerID, Payment.PaymentDate).
|
||||
WHERE(Payment.PaymentID.LT(Int(10)))
|
||||
query := SELECT(
|
||||
AVG(Payment.Amount).OVER(),
|
||||
AVG(Payment.Amount).OVER(PARTITION_BY(Payment.CustomerID)),
|
||||
MAXf(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate.DESC())),
|
||||
MINf(Payment.Amount).OVER(PARTITION_BY(Payment.CustomerID).ORDER_BY(Payment.PaymentDate.DESC())),
|
||||
SUMf(Payment.Amount).OVER(PARTITION_BY(Payment.CustomerID).
|
||||
ORDER_BY(Payment.PaymentDate.DESC()).ROWS(PRECEDING(1), FOLLOWING(6))),
|
||||
SUMf(Payment.Amount).OVER(PARTITION_BY(Payment.CustomerID).
|
||||
ORDER_BY(Payment.PaymentDate.DESC()).RANGE(PRECEDING(UNBOUNDED), FOLLOWING(UNBOUNDED))),
|
||||
MAXi(Payment.CustomerID).OVER(ORDER_BY(Payment.PaymentDate.DESC()).ROWS(CURRENT_ROW, FOLLOWING(UNBOUNDED))),
|
||||
MINi(Payment.CustomerID).OVER(PARTITION_BY(Payment.CustomerID).ORDER_BY(Payment.PaymentDate.DESC())),
|
||||
SUMi(Payment.CustomerID).OVER(PARTITION_BY(Payment.CustomerID).ORDER_BY(Payment.PaymentDate.DESC())),
|
||||
ROW_NUMBER().OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
RANK().OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
DENSE_RANK().OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
CUME_DIST().OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
NTILE(11).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAG(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAG(Payment.Amount, 2).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAG(Payment.Amount, 2, Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAG(Payment.Amount, 2, 100).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LEAD(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LEAD(Payment.Amount, 2).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LEAD(Payment.Amount, 2, Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LEAD(Payment.Amount, 2, 100).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
FIRST_VALUE(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
LAST_VALUE(Payment.Amount).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
NTH_VALUE(Payment.Amount, 3).OVER(ORDER_BY(Payment.PaymentDate)),
|
||||
).FROM(
|
||||
Payment,
|
||||
).WHERE(
|
||||
Payment.PaymentID.LT(Int(10)),
|
||||
).GROUP_BY(
|
||||
Payment.Amount,
|
||||
Payment.CustomerID,
|
||||
Payment.PaymentDate,
|
||||
)
|
||||
|
||||
//fmt.Println(query.Sql())
|
||||
|
||||
testutils.AssertStatementSql(t, query, expectedSQL, 100, 100, int64(10))
|
||||
|
||||
dest := []struct{}{}
|
||||
err := query.Query(db, &dest)
|
||||
require.NoError(t, err)
|
||||
allowUnusedColumns(func() {
|
||||
err := query.Query(db, &[]struct{}{})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSelectWindowClause(t *testing.T) {
|
||||
|
|
@ -3001,10 +3011,11 @@ ORDER BY payment.customer_id;
|
|||
|
||||
testutils.AssertStatementSql(t, query, expectedSQL, int64(10))
|
||||
|
||||
dest := []struct{}{}
|
||||
err := query.Query(db, &dest)
|
||||
allowUnusedColumns(func() {
|
||||
err := query.Query(db, &[]struct{}{})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSelectSimpleView(t *testing.T) {
|
||||
|
|
@ -3050,12 +3061,14 @@ func TestSelectJoinViewWithTable(t *testing.T) {
|
|||
query := SELECT(
|
||||
view.CustomerList.AllColumns,
|
||||
Rental.AllColumns,
|
||||
).
|
||||
FROM(view.CustomerList.
|
||||
).FROM(
|
||||
view.CustomerList.
|
||||
INNER_JOIN(Rental, view.CustomerList.ID.EQ(Rental.CustomerID)),
|
||||
).
|
||||
ORDER_BY(view.CustomerList.ID).
|
||||
WHERE(view.CustomerList.ID.LT_EQ(Int(2)))
|
||||
).WHERE(
|
||||
view.CustomerList.ID.LT_EQ(Int(2)),
|
||||
).ORDER_BY(
|
||||
view.CustomerList.ID,
|
||||
)
|
||||
|
||||
var dest []struct {
|
||||
model.CustomerList `sql:"primary_key=ID"`
|
||||
|
|
@ -3162,7 +3175,7 @@ FROM dvds.customer
|
|||
WHERE ($1::boolean AND (customer.customer_id = $2)) AND (customer.activebool = $3::boolean);
|
||||
`, true, int64(1), true)
|
||||
|
||||
dest := []model.Customer{}
|
||||
var dest []model.Customer
|
||||
err := stmt.Query(db, &dest)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, dest, 1)
|
||||
|
|
@ -3710,8 +3723,10 @@ SELECT SUM((CASE WHEN staff.active IS TRUE THEN $1::smallint ELSE $2::integer EN
|
|||
FROM dvds.staff;
|
||||
`)
|
||||
|
||||
err := stmt.Query(db, &struct{}{})
|
||||
require.NoError(t, err)
|
||||
allowUnusedColumns(func() {
|
||||
err := stmt.Query(db, &struct{}{})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func GET_FILM_COUNT(lenFrom, lenTo IntegerExpression) IntegerExpression {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue