Add reserved words for MySQL.

This commit is contained in:
go-jet 2020-05-02 22:15:38 +02:00
parent 241ea0d6d6
commit 926b88ed40
12 changed files with 573 additions and 178 deletions

View file

@ -1,6 +1,9 @@
package mysql
import (
"fmt"
"github.com/stretchr/testify/require"
"strings"
"testing"
"time"
@ -95,23 +98,23 @@ func TestExpressionOperators(t *testing.T) {
//fmt.Println(query.Sql())
testutils.AssertStatementSql(t, query, `
SELECT all_types.integer IS NULL AS "result.is_null",
testutils.AssertStatementSql(t, query, strings.Replace(`
SELECT all_types.'integer' IS NULL AS "result.is_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 ((
SELECT all_types.integer AS "all_types.integer"
SELECT all_types.'integer' AS "all_types.integer"
FROM test_sample.all_types
))) AS "result.in_select",
(all_types.small_int_ptr NOT IN (?, ?, NULL)) AS "result.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
))) AS "result.not_in_select",
DATABASE()
FROM test_sample.all_types
LIMIT ?;
`, int64(11), int64(22), int64(11), int64(22), int64(2))
`, "'", "`", -1), int64(11), int64(22), int64(11), int64(22), int64(2))
var dest []struct {
common.ExpressionTestResult `alias:"result.*"`
@ -261,45 +264,47 @@ func TestFloatOperators(t *testing.T) {
queryStr, _ := query.Sql()
assert.Equal(t, queryStr, `
SELECT (all_types.numeric = all_types.numeric) AS "eq1",
(all_types.decimal = ?) AS "eq2",
(all_types.real = ?) AS "eq3",
(NOT(all_types.numeric <=> all_types.numeric)) AS "distinct1",
(NOT(all_types.decimal <=> ?)) AS "distinct2",
(NOT(all_types.real <=> ?)) AS "distinct3",
(all_types.numeric <=> all_types.numeric) AS "not_distinct1",
(all_types.decimal <=> ?) AS "not_distinct2",
(all_types.real <=> ?) AS "not_distinct3",
(all_types.numeric < ?) AS "lt1",
(all_types.numeric < ?) AS "lt2",
(all_types.numeric > ?) AS "gt1",
(all_types.numeric > ?) AS "gt2",
TRUNCATE((all_types.decimal + all_types.decimal), ?) AS "add1",
TRUNCATE((all_types.decimal + ?), ?) AS "add2",
TRUNCATE((all_types.decimal - all_types.decimal_ptr), ?) AS "sub1",
TRUNCATE((all_types.decimal - ?), ?) AS "sub2",
TRUNCATE((all_types.decimal * all_types.decimal_ptr), ?) AS "mul1",
TRUNCATE((all_types.decimal * ?), ?) AS "mul2",
TRUNCATE((all_types.decimal / all_types.decimal_ptr), ?) AS "div1",
TRUNCATE((all_types.decimal / ?), ?) AS "div2",
TRUNCATE((all_types.decimal % all_types.decimal_ptr), ?) AS "mod1",
TRUNCATE((all_types.decimal % ?), ?) AS "mod2",
TRUNCATE(POW(all_types.decimal, all_types.decimal_ptr), ?) AS "pow1",
TRUNCATE(POW(all_types.decimal, ?), ?) AS "pow2",
TRUNCATE(ABS(all_types.decimal), ?) AS "abs",
TRUNCATE(POWER(all_types.decimal, ?), ?) AS "power",
TRUNCATE(SQRT(all_types.decimal), ?) AS "sqrt",
TRUNCATE(POWER(all_types.decimal, (? / ?)), ?) AS "cbrt",
CEIL(all_types.real) AS "ceil",
FLOOR(all_types.real) AS "floor",
ROUND(all_types.decimal) AS "round1",
ROUND(all_types.decimal, ?) AS "round2",
SIGN(all_types.real) AS "sign",
TRUNCATE(all_types.decimal, ?) AS "trunc"
//fmt.Println(queryStr)
assert.Equal(t, queryStr, strings.Replace(`
SELECT (all_types.'numeric' = all_types.'numeric') AS "eq1",
(all_types.'decimal' = ?) AS "eq2",
(all_types.'real' = ?) AS "eq3",
(NOT(all_types.'numeric' <=> all_types.'numeric')) AS "distinct1",
(NOT(all_types.'decimal' <=> ?)) AS "distinct2",
(NOT(all_types.'real' <=> ?)) AS "distinct3",
(all_types.'numeric' <=> all_types.'numeric') AS "not_distinct1",
(all_types.'decimal' <=> ?) AS "not_distinct2",
(all_types.'real' <=> ?) AS "not_distinct3",
(all_types.'numeric' < ?) AS "lt1",
(all_types.'numeric' < ?) AS "lt2",
(all_types.'numeric' > ?) AS "gt1",
(all_types.'numeric' > ?) AS "gt2",
TRUNCATE((all_types.'decimal' + all_types.'decimal'), ?) AS "add1",
TRUNCATE((all_types.'decimal' + ?), ?) AS "add2",
TRUNCATE((all_types.'decimal' - all_types.decimal_ptr), ?) AS "sub1",
TRUNCATE((all_types.'decimal' - ?), ?) AS "sub2",
TRUNCATE((all_types.'decimal' * all_types.decimal_ptr), ?) AS "mul1",
TRUNCATE((all_types.'decimal' * ?), ?) AS "mul2",
TRUNCATE((all_types.'decimal' / all_types.decimal_ptr), ?) AS "div1",
TRUNCATE((all_types.'decimal' / ?), ?) AS "div2",
TRUNCATE((all_types.'decimal' % all_types.decimal_ptr), ?) AS "mod1",
TRUNCATE((all_types.'decimal' % ?), ?) AS "mod2",
TRUNCATE(POW(all_types.'decimal', all_types.decimal_ptr), ?) AS "pow1",
TRUNCATE(POW(all_types.'decimal', ?), ?) AS "pow2",
TRUNCATE(ABS(all_types.'decimal'), ?) AS "abs",
TRUNCATE(POWER(all_types.'decimal', ?), ?) AS "power",
TRUNCATE(SQRT(all_types.'decimal'), ?) AS "sqrt",
TRUNCATE(POWER(all_types.'decimal', (? / ?)), ?) AS "cbrt",
CEIL(all_types.'real') AS "ceil",
FLOOR(all_types.'real') AS "floor",
ROUND(all_types.'decimal') AS "round1",
ROUND(all_types.'decimal', ?) AS "round2",
SIGN(all_types.'real') AS "sign",
TRUNCATE(all_types.'decimal', ?) AS "trunc"
FROM test_sample.all_types
LIMIT ?;
`)
`, "'", "`", -1))
var dest []struct {
common.FloatExpressionTestResult `alias:"."`
@ -568,7 +573,7 @@ func TestTimeExpressions(t *testing.T) {
//fmt.Println(query.DebugSql())
testutils.AssertDebugStatementSql(t, query, `
testutils.AssertDebugStatementSql(t, query, strings.Replace(`
SELECT CAST('20:34:58' AS TIME),
all_types.time = all_types.time,
all_types.time = CAST('23:06:06' AS TIME),
@ -589,7 +594,7 @@ SELECT CAST('20:34:58' AS TIME),
all_types.time >= all_types.time,
all_types.time >= CAST('14:26:36' AS TIME),
all_types.time + INTERVAL 10 MINUTE,
all_types.time + INTERVAL all_types.integer MINUTE,
all_types.time + INTERVAL all_types.''integer'' MINUTE,
all_types.time + INTERVAL 3 HOUR,
all_types.time - INTERVAL 20 MINUTE,
all_types.time - INTERVAL all_types.small_int MINUTE,
@ -598,7 +603,7 @@ SELECT CAST('20:34:58' AS TIME),
CURRENT_TIME,
CURRENT_TIME(3)
FROM test_sample.all_types;
`, "20:34:58", "23:06:06", "22:06:06.011", "21:06:06.011111", "20:16:06",
`, "''", "`", -1), "20:34:58", "23:06:06", "22:06:06.011", "21:06:06.011111", "20:16:06",
"19:26:06", "18:36:06", "17:46:06", "16:56:56", "15:16:46", "14:26:36")
dest := []struct{}{}
@ -648,25 +653,25 @@ func TestDateExpressions(t *testing.T) {
//fmt.Println(query.DebugSql())
testutils.AssertStatementSql(t, query, `
SELECT CAST(? AS DATE),
testutils.AssertDebugStatementSql(t, query, `
SELECT CAST('2009-11-17' AS DATE),
all_types.date = all_types.date,
all_types.date = CAST(? AS DATE),
all_types.date = CAST('2019-06-06' AS DATE),
all_types.date_ptr != all_types.date,
all_types.date_ptr != CAST(? AS DATE),
all_types.date_ptr != CAST('2019-01-06' AS DATE),
NOT(all_types.date <=> all_types.date),
NOT(all_types.date <=> CAST(? AS DATE)),
NOT(all_types.date <=> CAST('2019-02-06' AS DATE)),
all_types.date <=> all_types.date,
all_types.date <=> CAST(? AS DATE),
all_types.date <=> CAST('2019-03-06' AS DATE),
all_types.date < all_types.date,
all_types.date < CAST(? AS DATE),
all_types.date < CAST('2019-04-06' AS DATE),
all_types.date <= all_types.date,
all_types.date <= CAST(? AS DATE),
all_types.date <= CAST('2019-05-05' AS DATE),
all_types.date > all_types.date,
all_types.date > CAST(? AS DATE),
all_types.date > CAST('2019-01-04' AS DATE),
all_types.date >= all_types.date,
all_types.date >= CAST(? AS DATE),
all_types.date + INTERVAL ? MINUTE_MICROSECOND,
all_types.date >= CAST('2019-02-03' AS DATE),
all_types.date + INTERVAL '10:20.000100' MINUTE_MICROSECOND,
all_types.date + INTERVAL all_types.big_int MINUTE,
all_types.date + INTERVAL 15 HOUR,
all_types.date - INTERVAL 20 MINUTE,
@ -963,6 +968,91 @@ func TestINTERVAL(t *testing.T) {
assert.NoError(t, err)
}
func TestAllTypesInsert(t *testing.T) {
tx, err := db.Begin()
require.NoError(t, err)
stmt := AllTypes.INSERT(AllTypes.AllColumns).
MODEL(toInsert)
fmt.Println(stmt.DebugSql())
testutils.AssertExec(t, stmt, tx, 1)
var dest model.AllTypes
err = AllTypes.SELECT(AllTypes.AllColumns).
WHERE(AllTypes.BigInt.EQ(Int(toInsert.BigInt))).
Query(tx, &dest)
require.NoError(t, err)
require.Equal(t, toInsert.TinyInt, dest.TinyInt)
err = tx.Rollback()
require.NoError(t, err)
}
var toInsert = model.AllTypes{
Boolean: false,
BooleanPtr: testutils.BoolPtr(true),
TinyInt: 1,
UTinyInt: 2,
SmallInt: 3,
USmallInt: 4,
MediumInt: 5,
UMediumInt: 6,
Integer: 7,
UInteger: 8,
BigInt: 9,
UBigInt: 1122334455,
TinyIntPtr: testutils.Int8Ptr(11),
UTinyIntPtr: testutils.UInt8Ptr(22),
SmallIntPtr: testutils.Int16Ptr(33),
USmallIntPtr: testutils.UInt16Ptr(44),
MediumIntPtr: testutils.Int32Ptr(55),
UMediumIntPtr: testutils.UInt32Ptr(66),
IntegerPtr: testutils.Int32Ptr(77),
UIntegerPtr: testutils.UInt32Ptr(88),
BigIntPtr: testutils.Int64Ptr(99),
UBigIntPtr: testutils.UInt64Ptr(111),
Decimal: 11.22,
DecimalPtr: testutils.Float64Ptr(33.44),
Numeric: 55.66,
NumericPtr: testutils.Float64Ptr(77.88),
Float: 99.00,
FloatPtr: testutils.Float64Ptr(11.22),
Double: 33.44,
DoublePtr: testutils.Float64Ptr(55.66),
Real: 77.88,
RealPtr: testutils.Float64Ptr(99.00),
Bit: "1",
BitPtr: testutils.StringPtr("0"),
Time: time.Date(0, 0, 0, 10, 11, 12, 100, &time.Location{}),
TimePtr: testutils.TimePtr(time.Date(0, 0, 0, 10, 11, 12, 100, time.UTC)),
Date: time.Now(),
DatePtr: testutils.TimePtr(time.Now()),
DateTime: time.Now(),
DateTimePtr: testutils.TimePtr(time.Now()),
Timestamp: time.Now(),
TimestampPtr: testutils.TimePtr(time.Now()),
Year: 2000,
YearPtr: testutils.Int16Ptr(2001),
Char: "abcd",
CharPtr: testutils.StringPtr("absd"),
VarChar: "abcd",
VarCharPtr: testutils.StringPtr("absd"),
Binary: []byte("1010"),
BinaryPtr: testutils.ByteArrayPtr([]byte("100001")),
VarBinary: []byte("1010"),
VarBinaryPtr: testutils.ByteArrayPtr([]byte("100001")),
Blob: []byte("large file"),
BlobPtr: testutils.ByteArrayPtr([]byte("very large file")),
Text: "some text",
TextPtr: testutils.StringPtr("text"),
Enum: model.AllTypesEnum_Value1,
JSON: "{}",
JSONPtr: testutils.StringPtr(`{"a": 1}`),
}
var allTypesJson = `
[
{
@ -1100,24 +1190,22 @@ func TestReservedWord(t *testing.T) {
stmt := SELECT(User.AllColumns).
FROM(User)
// NOTE: A word that follows a period in a qualified name must be an identifier, so it
// need not be quoted even if it is reserved
testutils.AssertDebugStatementSql(t, stmt, `
SELECT user.column AS "user.column",
user.use AS "user.use",
testutils.AssertDebugStatementSql(t, stmt, strings.Replace(`
SELECT user.''column'' AS "user.column",
user.''use'' AS "user.use",
user.ceil AS "user.ceil",
user.commit AS "user.commit",
user.create AS "user.create",
user.default AS "user.default",
user.desc AS "user.desc",
user.empty AS "user.empty",
user.float AS "user.float",
user.join AS "user.join",
user.like AS "user.like",
user.''create'' AS "user.create",
user.''default'' AS "user.default",
user.''desc'' AS "user.desc",
user.''empty'' AS "user.empty",
user.''float'' AS "user.float",
user.''join'' AS "user.join",
user.''like'' AS "user.like",
user.max AS "user.max",
user.rank AS "user.rank"
user.''rank'' AS "user.rank"
FROM test_sample.user;
`)
`, "''", "`", -1))
var dest []model.User
err := stmt.Query(db, &dest)