Avoid unnecessary double wrapping of SELECT statement when used as single function parameter.
This commit is contained in:
parent
22b2901336
commit
d197956271
16 changed files with 97 additions and 77 deletions
|
|
@ -375,9 +375,14 @@ type wrap struct {
|
||||||
expressions []Expression
|
expressions []Expression
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *wrap) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
|
func (n *wrap) serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||||
out.WriteString("(")
|
out.WriteString("(")
|
||||||
serializeExpressionList(statement, n.expressions, ", ", out)
|
|
||||||
|
if len(n.expressions) == 1 {
|
||||||
|
options = append(options, NoWrap, Ident)
|
||||||
|
}
|
||||||
|
serializeExpressionList(statementType, n.expressions, ", ", out, options...)
|
||||||
|
|
||||||
out.WriteString(")")
|
out.WriteString(")")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,10 @@ type SerializeOption int
|
||||||
const (
|
const (
|
||||||
NoWrap SerializeOption = iota
|
NoWrap SerializeOption = iota
|
||||||
SkipNewLine
|
SkipNewLine
|
||||||
|
Ident
|
||||||
|
|
||||||
fallTroughOptions // fall trough options
|
fallTroughOptions // fall trough options
|
||||||
|
|
||||||
ShortName
|
ShortName
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,10 +195,19 @@ func (s *statementImpl) serialize(statement StatementType, out *SQLBuilder, opti
|
||||||
out.IncreaseIdent()
|
out.IncreaseIdent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if contains(options, Ident) {
|
||||||
|
out.IncreaseIdent()
|
||||||
|
}
|
||||||
|
|
||||||
for _, clause := range s.Clauses {
|
for _, clause := range s.Clauses {
|
||||||
clause.Serialize(statement, out, FallTrough(options)...)
|
clause.Serialize(statement, out, FallTrough(options)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if contains(options, Ident) {
|
||||||
|
out.DecreaseIdent()
|
||||||
|
out.NewLine()
|
||||||
|
}
|
||||||
|
|
||||||
if !contains(options, NoWrap) {
|
if !contains(options, NoWrap) {
|
||||||
out.DecreaseIdent()
|
out.DecreaseIdent()
|
||||||
out.NewLine()
|
out.NewLine()
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,19 @@ func SerializeClauseList(statement StatementType, clauses []Serializer, out *SQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func serializeExpressionList(statement StatementType, expressions []Expression, separator string, out *SQLBuilder) {
|
func serializeExpressionList(
|
||||||
|
statement StatementType,
|
||||||
|
expressions []Expression,
|
||||||
|
separator string,
|
||||||
|
out *SQLBuilder,
|
||||||
|
options ...SerializeOption) {
|
||||||
|
|
||||||
for i, value := range expressions {
|
for i, expression := range expressions {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
out.WriteString(separator)
|
out.WriteString(separator)
|
||||||
}
|
}
|
||||||
|
|
||||||
value.serialize(statement, out)
|
expression.serialize(statement, out, options...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInvalidInsert(t *testing.T) {
|
func TestInvalidInsert(t *testing.T) {
|
||||||
assertStatementSqlErr(t, table1.INSERT(table1Col1), "jet: VALUES or QUERY has to be specified for INSERT statement")
|
|
||||||
assertStatementSqlErr(t, table1.INSERT(nil).VALUES(1), "jet: nil column in columns list")
|
assertStatementSqlErr(t, table1.INSERT(nil).VALUES(1), "jet: nil column in columns list")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,33 +46,33 @@ func TestExists(t *testing.T) {
|
||||||
func TestIN(t *testing.T) {
|
func TestIN(t *testing.T) {
|
||||||
|
|
||||||
assertSerialize(t, Float(1.11).IN(table1.SELECT(table1Col1)),
|
assertSerialize(t, Float(1.11).IN(table1.SELECT(table1Col1)),
|
||||||
`($1 IN ((
|
`($1 IN (
|
||||||
SELECT table1.col1 AS "table1.col1"
|
SELECT table1.col1 AS "table1.col1"
|
||||||
FROM db.table1
|
FROM db.table1
|
||||||
)))`, float64(1.11))
|
))`, float64(1.11))
|
||||||
|
|
||||||
assertSerialize(t, ROW(Int(12), table1Col1).IN(table2.SELECT(table2Col3, table3Col1)),
|
assertSerialize(t, ROW(Int(12), table1Col1).IN(table2.SELECT(table2Col3, table3Col1)),
|
||||||
`(ROW($1, table1.col1) IN ((
|
`(ROW($1, table1.col1) IN (
|
||||||
SELECT table2.col3 AS "table2.col3",
|
SELECT table2.col3 AS "table2.col3",
|
||||||
table3.col1 AS "table3.col1"
|
table3.col1 AS "table3.col1"
|
||||||
FROM db.table2
|
FROM db.table2
|
||||||
)))`, int64(12))
|
))`, int64(12))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNOT_IN(t *testing.T) {
|
func TestNOT_IN(t *testing.T) {
|
||||||
|
|
||||||
assertSerialize(t, Float(1.11).NOT_IN(table1.SELECT(table1Col1)),
|
assertSerialize(t, Float(1.11).NOT_IN(table1.SELECT(table1Col1)),
|
||||||
`($1 NOT IN ((
|
`($1 NOT IN (
|
||||||
SELECT table1.col1 AS "table1.col1"
|
SELECT table1.col1 AS "table1.col1"
|
||||||
FROM db.table1
|
FROM db.table1
|
||||||
)))`, float64(1.11))
|
))`, float64(1.11))
|
||||||
|
|
||||||
assertSerialize(t, ROW(Int(12), table1Col1).NOT_IN(table2.SELECT(table2Col3, table3Col1)),
|
assertSerialize(t, ROW(Int(12), table1Col1).NOT_IN(table2.SELECT(table2Col3, table3Col1)),
|
||||||
`(ROW($1, table1.col1) NOT IN ((
|
`(ROW($1, table1.col1) NOT IN (
|
||||||
SELECT table2.col3 AS "table2.col3",
|
SELECT table2.col3 AS "table2.col3",
|
||||||
table3.col1 AS "table3.col1"
|
table3.col1 AS "table3.col1"
|
||||||
FROM db.table2
|
FROM db.table2
|
||||||
)))`, int64(12))
|
))`, int64(12))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReservedWordEscaped(t *testing.T) {
|
func TestReservedWordEscaped(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -104,18 +104,18 @@ func TestExpressionOperators(t *testing.T) {
|
||||||
SELECT all_types.'integer' IS NULL AS "result.is_null",
|
SELECT all_types.'integer' IS NULL AS "result.is_null",
|
||||||
all_types.date_ptr IS NOT NULL AS "result.is_not_null",
|
all_types.date_ptr IS NOT NULL AS "result.is_not_null",
|
||||||
(all_types.small_int_ptr IN (?, ?)) AS "result.in",
|
(all_types.small_int_ptr IN (?, ?)) AS "result.in",
|
||||||
(all_types.small_int_ptr IN ((
|
(all_types.small_int_ptr IN (
|
||||||
SELECT all_types.'integer' AS "all_types.integer"
|
SELECT all_types.'integer' AS "all_types.integer"
|
||||||
FROM test_sample.all_types
|
FROM test_sample.all_types
|
||||||
))) AS "result.in_select",
|
)) AS "result.in_select",
|
||||||
(CURRENT_USER()) AS "result.raw",
|
(CURRENT_USER()) AS "result.raw",
|
||||||
(? + COALESCE(all_types.small_int_ptr, 0) + ?) AS "result.raw_arg",
|
(? + COALESCE(all_types.small_int_ptr, 0) + ?) AS "result.raw_arg",
|
||||||
(? + all_types.integer + ? + ? + ? + ?) AS "result.raw_arg2",
|
(? + all_types.integer + ? + ? + ? + ?) AS "result.raw_arg2",
|
||||||
(all_types.small_int_ptr NOT IN (?, ?, NULL)) AS "result.not_in",
|
(all_types.small_int_ptr NOT IN (?, ?, NULL)) AS "result.not_in",
|
||||||
(all_types.small_int_ptr NOT IN ((
|
(all_types.small_int_ptr NOT IN (
|
||||||
SELECT all_types.'integer' AS "all_types.integer"
|
SELECT all_types.'integer' AS "all_types.integer"
|
||||||
FROM test_sample.all_types
|
FROM test_sample.all_types
|
||||||
))) AS "result.not_in_select"
|
)) AS "result.not_in_select"
|
||||||
FROM test_sample.all_types
|
FROM test_sample.all_types
|
||||||
LIMIT ?;
|
LIMIT ?;
|
||||||
`, "'", "`", -1), int64(11), int64(22), 78, 56, 11, 22, 11, 33, 44, int64(11), int64(22), int64(2))
|
`, "'", "`", -1), int64(11), int64(22), 78, 56, 11, 22, 11, 33, 44, int64(11), int64(22), int64(2))
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@ ON DUPLICATE KEY UPDATE id = (id + ?),
|
||||||
|
|
||||||
err := SELECT(Link.AllColumns).
|
err := SELECT(Link.AllColumns).
|
||||||
FROM(Link).
|
FROM(Link).
|
||||||
WHERE(Link.ID.EQ(Int(int64(randId)).ADD(Int(11)))).
|
WHERE(Link.ID.EQ(Int32(randId).ADD(Int(11)))).
|
||||||
Query(db, &newLinks)
|
Query(db, &newLinks)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ func TestUpdateWithModelData(t *testing.T) {
|
||||||
stmt := Link.
|
stmt := Link.
|
||||||
UPDATE(Link.AllColumns).
|
UPDATE(Link.AllColumns).
|
||||||
MODEL(link).
|
MODEL(link).
|
||||||
WHERE(Link.ID.EQ(Int(int64(link.ID))))
|
WHERE(Link.ID.EQ(Int32(link.ID)))
|
||||||
|
|
||||||
expectedSQL := `
|
expectedSQL := `
|
||||||
UPDATE test_sample.link
|
UPDATE test_sample.link
|
||||||
|
|
@ -131,7 +131,7 @@ SET id = ?,
|
||||||
description = ?
|
description = ?
|
||||||
WHERE link.id = ?;
|
WHERE link.id = ?;
|
||||||
`
|
`
|
||||||
testutils.AssertStatementSql(t, stmt, expectedSQL, int32(201), "http://www.duckduckgo.com", "DuckDuckGo", nil, int64(201))
|
testutils.AssertStatementSql(t, stmt, expectedSQL, int32(201), "http://www.duckduckgo.com", "DuckDuckGo", nil, int32(201))
|
||||||
|
|
||||||
testutils.AssertExec(t, stmt, db)
|
testutils.AssertExec(t, stmt, db)
|
||||||
requireLogged(t, stmt)
|
requireLogged(t, stmt)
|
||||||
|
|
@ -152,7 +152,7 @@ func TestUpdateWithModelDataAndPredefinedColumnList(t *testing.T) {
|
||||||
stmt := Link.
|
stmt := Link.
|
||||||
UPDATE(updateColumnList).
|
UPDATE(updateColumnList).
|
||||||
MODEL(link).
|
MODEL(link).
|
||||||
WHERE(Link.ID.EQ(Int(int64(link.ID))))
|
WHERE(Link.ID.EQ(Int32(link.ID)))
|
||||||
|
|
||||||
var expectedSQL = `
|
var expectedSQL = `
|
||||||
UPDATE test_sample.link
|
UPDATE test_sample.link
|
||||||
|
|
@ -161,9 +161,8 @@ SET description = NULL,
|
||||||
url = 'http://www.duckduckgo.com'
|
url = 'http://www.duckduckgo.com'
|
||||||
WHERE link.id = 201;
|
WHERE link.id = 201;
|
||||||
`
|
`
|
||||||
//fmt.Println(stmt.DebugSql())
|
|
||||||
|
|
||||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, nil, "DuckDuckGo", "http://www.duckduckgo.com", int64(201))
|
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, nil, "DuckDuckGo", "http://www.duckduckgo.com", int32(201))
|
||||||
|
|
||||||
testutils.AssertExec(t, stmt, db)
|
testutils.AssertExec(t, stmt, db)
|
||||||
requireLogged(t, stmt)
|
requireLogged(t, stmt)
|
||||||
|
|
@ -181,7 +180,7 @@ func TestUpdateWithModelDataAndMutableColumns(t *testing.T) {
|
||||||
stmt := Link.
|
stmt := Link.
|
||||||
UPDATE(Link.MutableColumns).
|
UPDATE(Link.MutableColumns).
|
||||||
MODEL(link).
|
MODEL(link).
|
||||||
WHERE(Link.ID.EQ(Int(int64(link.ID))))
|
WHERE(Link.ID.EQ(Int32(link.ID)))
|
||||||
|
|
||||||
var expectedSQL = `
|
var expectedSQL = `
|
||||||
UPDATE test_sample.link
|
UPDATE test_sample.link
|
||||||
|
|
@ -192,7 +191,7 @@ WHERE link.id = 201;
|
||||||
`
|
`
|
||||||
//fmt.Println(stmt.DebugSql())
|
//fmt.Println(stmt.DebugSql())
|
||||||
|
|
||||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, "http://www.duckduckgo.com", "DuckDuckGo", nil, int64(201))
|
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, "http://www.duckduckgo.com", "DuckDuckGo", nil, int32(201))
|
||||||
testutils.AssertExec(t, stmt, db)
|
testutils.AssertExec(t, stmt, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -241,18 +241,18 @@ func TestExpressionOperators(t *testing.T) {
|
||||||
SELECT all_types.integer IS NULL AS "result.is_null",
|
SELECT all_types.integer IS NULL AS "result.is_null",
|
||||||
all_types.date_ptr IS NOT NULL AS "result.is_not_null",
|
all_types.date_ptr IS NOT NULL AS "result.is_not_null",
|
||||||
(all_types.small_int_ptr IN ($1, $2)) AS "result.in",
|
(all_types.small_int_ptr IN ($1, $2)) AS "result.in",
|
||||||
(all_types.small_int_ptr IN ((
|
(all_types.small_int_ptr IN (
|
||||||
SELECT all_types.integer AS "all_types.integer"
|
SELECT all_types.integer AS "all_types.integer"
|
||||||
FROM test_sample.all_types
|
FROM test_sample.all_types
|
||||||
))) AS "result.in_select",
|
)) AS "result.in_select",
|
||||||
(CURRENT_USER) AS "result.raw",
|
(CURRENT_USER) AS "result.raw",
|
||||||
($3 + COALESCE(all_types.small_int_ptr, 0) + $4) AS "result.raw_arg",
|
($3 + COALESCE(all_types.small_int_ptr, 0) + $4) AS "result.raw_arg",
|
||||||
($5 + all_types.integer + $6 + $5 + $7 + $8) AS "result.raw_arg2",
|
($5 + all_types.integer + $6 + $5 + $7 + $8) AS "result.raw_arg2",
|
||||||
(all_types.small_int_ptr NOT IN ($9, $10, NULL)) AS "result.not_in",
|
(all_types.small_int_ptr NOT IN ($9, $10, NULL)) AS "result.not_in",
|
||||||
(all_types.small_int_ptr NOT IN ((
|
(all_types.small_int_ptr NOT IN (
|
||||||
SELECT all_types.integer AS "all_types.integer"
|
SELECT all_types.integer AS "all_types.integer"
|
||||||
FROM test_sample.all_types
|
FROM test_sample.all_types
|
||||||
))) AS "result.not_in_select"
|
)) AS "result.not_in_select"
|
||||||
FROM test_sample.all_types
|
FROM test_sample.all_types
|
||||||
LIMIT $11;
|
LIMIT $11;
|
||||||
`, int64(11), int64(22), 78, 56, 11, 22, 33, 44, int64(11), int64(22), int64(2))
|
`, int64(11), int64(22), 78, 56, 11, 22, 33, 44, int64(11), int64(22), int64(2))
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
|
@ -368,16 +369,16 @@ func newActorInfoTableImpl(schemaName, tableName, alias string) actorInfoTable {
|
||||||
`
|
`
|
||||||
|
|
||||||
func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
|
func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
|
||||||
enumDir := testRoot + ".gentestdata/jetdb/test_sample/enum/"
|
enumDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/enum/")
|
||||||
modelDir := testRoot + ".gentestdata/jetdb/test_sample/model/"
|
modelDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/model/")
|
||||||
tableDir := testRoot + ".gentestdata/jetdb/test_sample/table/"
|
tableDir := filepath.Join(testRoot, "/.gentestdata/jetdb/test_sample/table/")
|
||||||
|
|
||||||
enumFiles, err := ioutil.ReadDir(enumDir)
|
enumFiles, err := ioutil.ReadDir(enumDir)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
testutils.AssertFileNamesEqual(t, enumFiles, "mood.go", "level.go")
|
testutils.AssertFileNamesEqual(t, enumFiles, "mood.go", "level.go")
|
||||||
testutils.AssertFileContent(t, enumDir+"mood.go", moodEnumContent)
|
testutils.AssertFileContent(t, enumDir+"/mood.go", moodEnumContent)
|
||||||
testutils.AssertFileContent(t, enumDir+"level.go", levelEnumContent)
|
testutils.AssertFileContent(t, enumDir+"/level.go", levelEnumContent)
|
||||||
|
|
||||||
modelFiles, err := ioutil.ReadDir(modelDir)
|
modelFiles, err := ioutil.ReadDir(modelDir)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
@ -385,7 +386,7 @@ func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
|
||||||
testutils.AssertFileNamesEqual(t, modelFiles, "all_types.go", "all_types_view.go", "employee.go", "link.go",
|
testutils.AssertFileNamesEqual(t, modelFiles, "all_types.go", "all_types_view.go", "employee.go", "link.go",
|
||||||
"mood.go", "person.go", "person_phone.go", "weird_names_table.go", "level.go", "user.go", "floats.go")
|
"mood.go", "person.go", "person_phone.go", "weird_names_table.go", "level.go", "user.go", "floats.go")
|
||||||
|
|
||||||
testutils.AssertFileContent(t, modelDir+"all_types.go", allTypesModelContent)
|
testutils.AssertFileContent(t, modelDir+"/all_types.go", allTypesModelContent)
|
||||||
|
|
||||||
tableFiles, err := ioutil.ReadDir(tableDir)
|
tableFiles, err := ioutil.ReadDir(tableDir)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
@ -393,7 +394,7 @@ func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
|
||||||
testutils.AssertFileNamesEqual(t, tableFiles, "all_types.go", "employee.go", "link.go",
|
testutils.AssertFileNamesEqual(t, tableFiles, "all_types.go", "employee.go", "link.go",
|
||||||
"person.go", "person_phone.go", "weird_names_table.go", "user.go", "floats.go")
|
"person.go", "person_phone.go", "weird_names_table.go", "user.go", "floats.go")
|
||||||
|
|
||||||
testutils.AssertFileContent(t, tableDir+"all_types.go", allTypesTableContent)
|
testutils.AssertFileContent(t, tableDir+"/all_types.go", allTypesTableContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
var moodEnumContent = `
|
var moodEnumContent = `
|
||||||
|
|
|
||||||
|
|
@ -140,8 +140,7 @@ ON CONFLICT ON CONSTRAINT employee_pkey DO NOTHING;
|
||||||
Link.ID.SET(Link.EXCLUDED.ID),
|
Link.ID.SET(Link.EXCLUDED.ID),
|
||||||
Link.URL.SET(String("http://www.postgresqltutorial2.com")),
|
Link.URL.SET(String("http://www.postgresqltutorial2.com")),
|
||||||
),
|
),
|
||||||
).
|
).RETURNING(Link.AllColumns)
|
||||||
RETURNING(Link.AllColumns)
|
|
||||||
|
|
||||||
testutils.AssertStatementSql(t, stmt, `
|
testutils.AssertStatementSql(t, stmt, `
|
||||||
INSERT INTO test_sample.link (id, url, name, description)
|
INSERT INTO test_sample.link (id, url, name, description)
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,9 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/go-jet/jet/v2/tests/internal/utils/repo"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -53,13 +52,7 @@ func TestMain(m *testing.M) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setTestRoot() {
|
func setTestRoot() {
|
||||||
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
|
testRoot = repo.GetTestsDirPath()
|
||||||
byteArr, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
testRoot = strings.TrimSpace(string(byteArr)) + "/tests/"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var loggedSQL string
|
var loggedSQL string
|
||||||
|
|
|
||||||
|
|
@ -75,11 +75,12 @@ LIMIT 30;
|
||||||
query := SELECT(
|
query := SELECT(
|
||||||
Payment.AllColumns,
|
Payment.AllColumns,
|
||||||
Customer.AllColumns,
|
Customer.AllColumns,
|
||||||
).
|
).FROM(
|
||||||
FROM(Payment.
|
Payment.
|
||||||
INNER_JOIN(Customer, Payment.CustomerID.EQ(Customer.CustomerID))).
|
INNER_JOIN(Customer, Payment.CustomerID.EQ(Customer.CustomerID)),
|
||||||
ORDER_BY(Payment.PaymentID.ASC()).
|
).ORDER_BY(
|
||||||
LIMIT(30)
|
Payment.PaymentID.ASC(),
|
||||||
|
).LIMIT(30)
|
||||||
|
|
||||||
testutils.AssertDebugStatementSql(t, query, expectedSQL, int64(30))
|
testutils.AssertDebugStatementSql(t, query, expectedSQL, int64(30))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -259,14 +259,14 @@ func TestUpdateWithModelData(t *testing.T) {
|
||||||
stmt := Link.
|
stmt := Link.
|
||||||
UPDATE(Link.AllColumns).
|
UPDATE(Link.AllColumns).
|
||||||
MODEL(link).
|
MODEL(link).
|
||||||
WHERE(Link.ID.EQ(Int(int64(link.ID))))
|
WHERE(Link.ID.EQ(Int32(link.ID)))
|
||||||
|
|
||||||
expectedSQL := `
|
expectedSQL := `
|
||||||
UPDATE test_sample.link
|
UPDATE test_sample.link
|
||||||
SET (id, url, name, description) = (201, 'http://www.duckduckgo.com', 'DuckDuckGo', NULL)
|
SET (id, url, name, description) = (201, 'http://www.duckduckgo.com', 'DuckDuckGo', NULL)
|
||||||
WHERE link.id = 201;
|
WHERE link.id = 201;
|
||||||
`
|
`
|
||||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, int32(201), "http://www.duckduckgo.com", "DuckDuckGo", nil, int64(201))
|
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, int32(201), "http://www.duckduckgo.com", "DuckDuckGo", nil, int32(201))
|
||||||
|
|
||||||
AssertExec(t, stmt, 1)
|
AssertExec(t, stmt, 1)
|
||||||
}
|
}
|
||||||
|
|
@ -286,14 +286,14 @@ func TestUpdateWithModelDataAndPredefinedColumnList(t *testing.T) {
|
||||||
stmt := Link.
|
stmt := Link.
|
||||||
UPDATE(updateColumnList).
|
UPDATE(updateColumnList).
|
||||||
MODEL(link).
|
MODEL(link).
|
||||||
WHERE(Link.ID.EQ(Int(int64(link.ID))))
|
WHERE(Link.ID.EQ(Int32(link.ID)))
|
||||||
|
|
||||||
var expectedSQL = `
|
var expectedSQL = `
|
||||||
UPDATE test_sample.link
|
UPDATE test_sample.link
|
||||||
SET (description, name, url) = (NULL, 'DuckDuckGo', 'http://www.duckduckgo.com')
|
SET (description, name, url) = (NULL, 'DuckDuckGo', 'http://www.duckduckgo.com')
|
||||||
WHERE link.id = 201;
|
WHERE link.id = 201;
|
||||||
`
|
`
|
||||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, nil, "DuckDuckGo", "http://www.duckduckgo.com", int64(201))
|
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, nil, "DuckDuckGo", "http://www.duckduckgo.com", int32(201))
|
||||||
|
|
||||||
AssertExec(t, stmt, 1)
|
AssertExec(t, stmt, 1)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,20 +22,23 @@ func TestWithRegionalSales(t *testing.T) {
|
||||||
SELECT(
|
SELECT(
|
||||||
Orders.ShipRegion,
|
Orders.ShipRegion,
|
||||||
SUM(OrderDetails.Quantity).AS(regionalSalesTotalSales.Name()),
|
SUM(OrderDetails.Quantity).AS(regionalSalesTotalSales.Name()),
|
||||||
).
|
).FROM(
|
||||||
FROM(Orders.INNER_JOIN(OrderDetails, OrderDetails.OrderID.EQ(Orders.OrderID))).
|
Orders.INNER_JOIN(OrderDetails, OrderDetails.OrderID.EQ(Orders.OrderID)),
|
||||||
GROUP_BY(Orders.ShipRegion),
|
).GROUP_BY(Orders.ShipRegion),
|
||||||
),
|
),
|
||||||
topRegion.AS(
|
topRegion.AS(
|
||||||
SELECT(regionalSalesShipRegion).
|
SELECT(
|
||||||
FROM(regionalSales).
|
regionalSalesShipRegion,
|
||||||
WHERE(regionalSalesTotalSales.GT(
|
).FROM(
|
||||||
|
regionalSales,
|
||||||
|
).WHERE(
|
||||||
|
regionalSalesTotalSales.GT(
|
||||||
IntExp(
|
IntExp(
|
||||||
SELECT(SUM(regionalSalesTotalSales)).
|
SELECT(SUM(regionalSalesTotalSales)).
|
||||||
FROM(regionalSales),
|
FROM(regionalSales),
|
||||||
).DIV(Int(50)),
|
).DIV(Int(50)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)(
|
)(
|
||||||
SELECT(
|
SELECT(
|
||||||
|
|
@ -43,13 +46,17 @@ func TestWithRegionalSales(t *testing.T) {
|
||||||
OrderDetails.ProductID,
|
OrderDetails.ProductID,
|
||||||
COUNT(STAR).AS("product_units"),
|
COUNT(STAR).AS("product_units"),
|
||||||
SUM(OrderDetails.Quantity).AS("product_sales"),
|
SUM(OrderDetails.Quantity).AS("product_sales"),
|
||||||
).
|
).FROM(
|
||||||
FROM(Orders.INNER_JOIN(OrderDetails, Orders.OrderID.EQ(OrderDetails.OrderID))).
|
Orders.
|
||||||
WHERE(Orders.ShipRegion.IN(
|
INNER_JOIN(OrderDetails, Orders.OrderID.EQ(OrderDetails.OrderID)),
|
||||||
topRegion.SELECT(topRegionShipRegion)),
|
).WHERE(
|
||||||
).
|
Orders.ShipRegion.IN(topRegion.SELECT(topRegionShipRegion)),
|
||||||
GROUP_BY(Orders.ShipRegion, OrderDetails.ProductID).
|
).GROUP_BY(
|
||||||
ORDER_BY(SUM(OrderDetails.Quantity).DESC()),
|
Orders.ShipRegion,
|
||||||
|
OrderDetails.ProductID,
|
||||||
|
).ORDER_BY(
|
||||||
|
SUM(OrderDetails.Quantity).DESC(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
//fmt.Println(stmt.DebugSql())
|
//fmt.Println(stmt.DebugSql())
|
||||||
|
|
@ -75,10 +82,10 @@ SELECT orders.ship_region AS "orders.ship_region",
|
||||||
SUM(order_details.quantity) AS "product_sales"
|
SUM(order_details.quantity) AS "product_sales"
|
||||||
FROM northwind.orders
|
FROM northwind.orders
|
||||||
INNER JOIN northwind.order_details ON (orders.order_id = order_details.order_id)
|
INNER JOIN northwind.order_details ON (orders.order_id = order_details.order_id)
|
||||||
WHERE orders.ship_region IN ((
|
WHERE orders.ship_region IN (
|
||||||
SELECT top_region."orders.ship_region" AS "orders.ship_region"
|
SELECT top_region."orders.ship_region" AS "orders.ship_region"
|
||||||
FROM top_region
|
FROM top_region
|
||||||
))
|
)
|
||||||
GROUP BY orders.ship_region, order_details.product_id
|
GROUP BY orders.ship_region, order_details.product_id
|
||||||
ORDER BY SUM(order_details.quantity) DESC;
|
ORDER BY SUM(order_details.quantity) DESC;
|
||||||
`)
|
`)
|
||||||
|
|
@ -141,19 +148,19 @@ func TestWithStatementDeleteAndInsert(t *testing.T) {
|
||||||
testutils.AssertStatementSql(t, stmt, `
|
testutils.AssertStatementSql(t, stmt, `
|
||||||
WITH remove_discontinued_orders AS (
|
WITH remove_discontinued_orders AS (
|
||||||
DELETE FROM northwind.order_details
|
DELETE FROM northwind.order_details
|
||||||
WHERE order_details.product_id IN ((
|
WHERE order_details.product_id IN (
|
||||||
SELECT products.product_id AS "products.product_id"
|
SELECT products.product_id AS "products.product_id"
|
||||||
FROM northwind.products
|
FROM northwind.products
|
||||||
WHERE products.discontinued = $1
|
WHERE products.discontinued = $1
|
||||||
))
|
)
|
||||||
RETURNING order_details.product_id AS "order_details.product_id"
|
RETURNING order_details.product_id AS "order_details.product_id"
|
||||||
),update_discontinued_price AS (
|
),update_discontinued_price AS (
|
||||||
UPDATE northwind.products
|
UPDATE northwind.products
|
||||||
SET unit_price = $2
|
SET unit_price = $2
|
||||||
WHERE products.product_id IN ((
|
WHERE products.product_id IN (
|
||||||
SELECT remove_discontinued_orders."order_details.product_id" AS "order_details.product_id"
|
SELECT remove_discontinued_orders."order_details.product_id" AS "order_details.product_id"
|
||||||
FROM remove_discontinued_orders
|
FROM remove_discontinued_orders
|
||||||
))
|
)
|
||||||
RETURNING products.product_id AS "products.product_id",
|
RETURNING products.product_id AS "products.product_id",
|
||||||
products.product_name AS "products.product_name",
|
products.product_name AS "products.product_name",
|
||||||
products.supplier_id AS "products.supplier_id",
|
products.supplier_id AS "products.supplier_id",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue