commit
7924d13875
62 changed files with 608 additions and 528067 deletions
|
|
@ -30,6 +30,14 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Submodule init
|
||||||
|
command: |
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
cd ./tests/testdata && git fetch && git checkout master
|
||||||
|
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Install dependencies
|
name: Install dependencies
|
||||||
command: |
|
command: |
|
||||||
|
|
@ -71,10 +79,10 @@ jobs:
|
||||||
sudo apt-get install default-mysql-client
|
sudo apt-get install default-mysql-client
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Init MySQL database
|
name: Create MySQL user and databases
|
||||||
command: |
|
command: |
|
||||||
mysql -h 127.0.0.1 -u root -pjet -e "grant all privileges on *.* to 'jet'@'%';"
|
mysql -h 127.0.0.1 -u root -pjet -e "grant all privileges on *.* to 'jet'@'%';"
|
||||||
mysql -h 127.0.0.1 -u root -pjet -e "set global sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';"
|
mysql -h 127.0.0.1 -u root -pjet -e "set global sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';"
|
||||||
mysql -h 127.0.0.1 -u jet -pjet -e "create database test_sample"
|
mysql -h 127.0.0.1 -u jet -pjet -e "create database test_sample"
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
|
|
@ -98,4 +106,75 @@ jobs:
|
||||||
|
|
||||||
- store_test_results: # Upload test results for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
|
- store_test_results: # Upload test results for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
|
||||||
path: /tmp/test-results
|
path: /tmp/test-results
|
||||||
|
build-mariadb:
|
||||||
|
docker:
|
||||||
|
# specify the version
|
||||||
|
- image: circleci/golang:1.11
|
||||||
|
|
||||||
|
- image: circleci/mariadb:10.3
|
||||||
|
command: [--default-authentication-plugin=mysql_native_password]
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: jet
|
||||||
|
MYSQL_DATABASE: dvds
|
||||||
|
MYSQL_USER: jet
|
||||||
|
MYSQL_PASSWORD: jet
|
||||||
|
|
||||||
|
working_directory: /go/src/github.com/go-jet/jet
|
||||||
|
|
||||||
|
environment: # environment variables for the build itself
|
||||||
|
TEST_RESULTS: /tmp/test-results # path to where test results will be saved
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Submodule init
|
||||||
|
command: |
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
cd ./tests/testdata && git fetch && git checkout master
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Install dependencies
|
||||||
|
command: |
|
||||||
|
go get github.com/google/uuid
|
||||||
|
go get github.com/lib/pq
|
||||||
|
go get github.com/go-sql-driver/mysql
|
||||||
|
|
||||||
|
go get github.com/pkg/profile
|
||||||
|
go get gotest.tools/assert
|
||||||
|
go get github.com/davecgh/go-spew/spew
|
||||||
|
go get github.com/jstemmer/go-junit-report
|
||||||
|
|
||||||
|
go install github.com/go-jet/jet/cmd/jet
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Install MySQL CLI;
|
||||||
|
command: |
|
||||||
|
sudo apt-get install default-mysql-client
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Init MariaDB database
|
||||||
|
command: |
|
||||||
|
mysql -h 127.0.0.1 -u root -pjet -e "grant all privileges on *.* to 'jet'@'%';"
|
||||||
|
mysql -h 127.0.0.1 -u root -pjet -e "set global sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';"
|
||||||
|
mysql -h 127.0.0.1 -u jet -pjet -e "create database test_sample"
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Init MariaDB database
|
||||||
|
command: |
|
||||||
|
cd tests
|
||||||
|
go run ./init/init.go -testsuite MariaDB
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Run MariaDB tests
|
||||||
|
command: |
|
||||||
|
go test -v ./tests/mysql/ -source=MariaDB
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
version: 2
|
||||||
|
build_and_test:
|
||||||
|
jobs:
|
||||||
|
- build
|
||||||
|
- build-mariadb
|
||||||
|
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -18,3 +18,4 @@
|
||||||
# Test files
|
# Test files
|
||||||
gen
|
gen
|
||||||
.gentestdata
|
.gentestdata
|
||||||
|
.tests/testdata/
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "tests/testdata"]
|
||||||
|
path = tests/testdata
|
||||||
|
url = https://github.com/go-jet/jet-test-data
|
||||||
|
|
@ -95,10 +95,10 @@ ORDER BY ordinal_position;
|
||||||
|
|
||||||
func (m *MySqlQuerySet) ListOfEnumsQuery() string {
|
func (m *MySqlQuerySet) ListOfEnumsQuery() string {
|
||||||
return `
|
return `
|
||||||
SELECT (CASE DATA_TYPE WHEN 'enum' then CONCAT(TABLE_NAME, '_', COLUMN_NAME) ELSE '' END ), SUBSTRING(COLUMN_TYPE,5)
|
SELECT (CASE c.DATA_TYPE WHEN 'enum' then CONCAT(c.TABLE_NAME, '_', c.COLUMN_NAME) ELSE '' END ), SUBSTRING(c.COLUMN_TYPE,5)
|
||||||
FROM information_schema.columns
|
FROM information_schema.columns as c
|
||||||
WHERE table_schema = ?
|
INNER JOIN information_schema.tables as t on (t.table_schema = c.table_schema AND t.table_name = c.table_name)
|
||||||
AND DATA_TYPE = 'enum';
|
WHERE c.table_schema = ? AND DATA_TYPE = 'enum' AND t.TABLE_TYPE = 'BASE TABLE';
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,10 @@ type binaryBoolExpression struct {
|
||||||
binaryOpExpression
|
binaryOpExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBinaryBoolOperator(lhs, rhs Expression, operator string) BoolExpression {
|
func newBinaryBoolOperator(lhs, rhs Expression, operator string, additionalParams ...Expression) BoolExpression {
|
||||||
binaryBoolExpression := binaryBoolExpression{}
|
binaryBoolExpression := binaryBoolExpression{}
|
||||||
|
|
||||||
binaryBoolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator)
|
binaryBoolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator, additionalParams...)
|
||||||
binaryBoolExpression.ExpressionInterfaceImpl.Parent = &binaryBoolExpression
|
binaryBoolExpression.ExpressionInterfaceImpl.Parent = &binaryBoolExpression
|
||||||
binaryBoolExpression.boolInterfaceImpl.parent = &binaryBoolExpression
|
binaryBoolExpression.boolInterfaceImpl.parent = &binaryBoolExpression
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ func (b *castExpression) serialize(statement StatementType, out *SqlBuilder, opt
|
||||||
expression := b.expression
|
expression := b.expression
|
||||||
castType := b.cast
|
castType := b.cast
|
||||||
|
|
||||||
if castOverride := out.Dialect.SerializeOverride("CAST"); castOverride != nil {
|
if castOverride := out.Dialect.OperatorSerializeOverride("CAST"); castOverride != nil {
|
||||||
castOverride(expression, String(castType))(statement, out, options...)
|
castOverride(expression, String(castType))(statement, out, options...)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -184,14 +184,6 @@ func (s *ClauseSetStmtOperator) Serialize(statementType StatementType, out *SqlB
|
||||||
panic("jet: UNION Statement must contain at least two SELECT statements")
|
panic("jet: UNION Statement must contain at least two SELECT statements")
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap := s.OrderBy.List != nil || s.Limit.Count >= 0 || s.Offset.Count >= 0
|
|
||||||
|
|
||||||
if wrap {
|
|
||||||
out.NewLine()
|
|
||||||
out.WriteString("(")
|
|
||||||
out.IncreaseIdent()
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, selectStmt := range s.Selects {
|
for i, selectStmt := range s.Selects {
|
||||||
out.NewLine()
|
out.NewLine()
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
|
|
@ -210,12 +202,6 @@ func (s *ClauseSetStmtOperator) Serialize(statementType StatementType, out *SqlB
|
||||||
selectStmt.serialize(statementType, out)
|
selectStmt.serialize(statementType, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
if wrap {
|
|
||||||
out.DecreaseIdent()
|
|
||||||
out.NewLine()
|
|
||||||
out.WriteString(")")
|
|
||||||
}
|
|
||||||
|
|
||||||
s.OrderBy.Serialize(statementType, out)
|
s.OrderBy.Serialize(statementType, out)
|
||||||
s.Limit.Serialize(statementType, out)
|
s.Limit.Serialize(statementType, out)
|
||||||
s.Offset.Serialize(statementType, out)
|
s.Offset.Serialize(statementType, out)
|
||||||
|
|
@ -391,26 +377,19 @@ func (d *ClauseStatementBegin) Serialize(statementType StatementType, out *SqlBu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClauseString struct {
|
|
||||||
Name string
|
|
||||||
Data string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *ClauseString) Serialize(statementType StatementType, out *SqlBuilder) {
|
|
||||||
out.NewLine()
|
|
||||||
out.WriteString(d.Name)
|
|
||||||
out.WriteString(d.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ClauseOptional struct {
|
type ClauseOptional struct {
|
||||||
Name string
|
Name string
|
||||||
Show bool
|
Show bool
|
||||||
|
InNewLine bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ClauseOptional) Serialize(statementType StatementType, out *SqlBuilder) {
|
func (d *ClauseOptional) Serialize(statementType StatementType, out *SqlBuilder) {
|
||||||
if !d.Show {
|
if !d.Show {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if d.InNewLine {
|
||||||
|
out.NewLine()
|
||||||
|
}
|
||||||
out.WriteString(d.Name)
|
out.WriteString(d.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ package jet
|
||||||
type Dialect interface {
|
type Dialect interface {
|
||||||
Name() string
|
Name() string
|
||||||
PackageName() string
|
PackageName() string
|
||||||
SerializeOverride(operator string) SerializeOverride
|
OperatorSerializeOverride(operator string) SerializeOverride
|
||||||
|
FunctionSerializeOverride(function string) SerializeOverride
|
||||||
AliasQuoteChar() byte
|
AliasQuoteChar() byte
|
||||||
IdentifierQuoteChar() byte
|
IdentifierQuoteChar() byte
|
||||||
ArgumentPlaceholder() QueryPlaceholderFunc
|
ArgumentPlaceholder() QueryPlaceholderFunc
|
||||||
|
|
@ -16,7 +17,8 @@ type QueryPlaceholderFunc func(ord int) string
|
||||||
type DialectParams struct {
|
type DialectParams struct {
|
||||||
Name string
|
Name string
|
||||||
PackageName string
|
PackageName string
|
||||||
SerializeOverrides map[string]SerializeOverride
|
OperatorSerializeOverrides map[string]SerializeOverride
|
||||||
|
FunctionSerializeOverrides map[string]SerializeOverride
|
||||||
AliasQuoteChar byte
|
AliasQuoteChar byte
|
||||||
IdentifierQuoteChar byte
|
IdentifierQuoteChar byte
|
||||||
ArgumentPlaceholder QueryPlaceholderFunc
|
ArgumentPlaceholder QueryPlaceholderFunc
|
||||||
|
|
@ -26,7 +28,8 @@ func NewDialect(params DialectParams) Dialect {
|
||||||
return &dialectImpl{
|
return &dialectImpl{
|
||||||
name: params.Name,
|
name: params.Name,
|
||||||
packageName: params.PackageName,
|
packageName: params.PackageName,
|
||||||
serializeOverrides: params.SerializeOverrides,
|
operatorSerializeOverrides: params.OperatorSerializeOverrides,
|
||||||
|
functionSerializeOverrides: params.FunctionSerializeOverrides,
|
||||||
aliasQuoteChar: params.AliasQuoteChar,
|
aliasQuoteChar: params.AliasQuoteChar,
|
||||||
identifierQuoteChar: params.IdentifierQuoteChar,
|
identifierQuoteChar: params.IdentifierQuoteChar,
|
||||||
argumentPlaceholder: params.ArgumentPlaceholder,
|
argumentPlaceholder: params.ArgumentPlaceholder,
|
||||||
|
|
@ -36,7 +39,8 @@ func NewDialect(params DialectParams) Dialect {
|
||||||
type dialectImpl struct {
|
type dialectImpl struct {
|
||||||
name string
|
name string
|
||||||
packageName string
|
packageName string
|
||||||
serializeOverrides map[string]SerializeOverride
|
operatorSerializeOverrides map[string]SerializeOverride
|
||||||
|
functionSerializeOverrides map[string]SerializeOverride
|
||||||
aliasQuoteChar byte
|
aliasQuoteChar byte
|
||||||
identifierQuoteChar byte
|
identifierQuoteChar byte
|
||||||
argumentPlaceholder QueryPlaceholderFunc
|
argumentPlaceholder QueryPlaceholderFunc
|
||||||
|
|
@ -52,8 +56,18 @@ func (d *dialectImpl) PackageName() string {
|
||||||
return d.packageName
|
return d.packageName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dialectImpl) SerializeOverride(operator string) SerializeOverride {
|
func (d *dialectImpl) OperatorSerializeOverride(operator string) SerializeOverride {
|
||||||
return d.serializeOverrides[operator]
|
if d.operatorSerializeOverrides == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return d.operatorSerializeOverrides[operator]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dialectImpl) FunctionSerializeOverride(function string) SerializeOverride {
|
||||||
|
if d.functionSerializeOverrides == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return d.functionSerializeOverrides[function]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dialectImpl) AliasQuoteChar() byte {
|
func (d *dialectImpl) AliasQuoteChar() byte {
|
||||||
|
|
|
||||||
|
|
@ -78,16 +78,21 @@ func (e *ExpressionInterfaceImpl) serializeForOrderBy(statement StatementType, o
|
||||||
// Representation of binary operations (e.g. comparisons, arithmetic)
|
// Representation of binary operations (e.g. comparisons, arithmetic)
|
||||||
type binaryOpExpression struct {
|
type binaryOpExpression struct {
|
||||||
lhs, rhs Expression
|
lhs, rhs Expression
|
||||||
|
additionalParam Expression
|
||||||
operator string
|
operator string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBinaryExpression(lhs, rhs Expression, operator string) binaryOpExpression {
|
func newBinaryExpression(lhs, rhs Expression, operator string, additionalParam ...Expression) binaryOpExpression {
|
||||||
binaryExpression := binaryOpExpression{
|
binaryExpression := binaryOpExpression{
|
||||||
lhs: lhs,
|
lhs: lhs,
|
||||||
rhs: rhs,
|
rhs: rhs,
|
||||||
operator: operator,
|
operator: operator,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(additionalParam) > 0 {
|
||||||
|
binaryExpression.additionalParam = additionalParam[0]
|
||||||
|
}
|
||||||
|
|
||||||
return binaryExpression
|
return binaryExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,8 +110,8 @@ func (c *binaryOpExpression) serialize(statement StatementType, out *SqlBuilder,
|
||||||
out.WriteString("(")
|
out.WriteString("(")
|
||||||
}
|
}
|
||||||
|
|
||||||
if serializeOverride := out.Dialect.SerializeOverride(c.operator); serializeOverride != nil {
|
if serializeOverride := out.Dialect.OperatorSerializeOverride(c.operator); serializeOverride != nil {
|
||||||
serializeOverrideFunc := serializeOverride(c.lhs, c.rhs)
|
serializeOverrideFunc := serializeOverride(c.lhs, c.rhs, c.additionalParam)
|
||||||
serializeOverrideFunc(statement, out, options...)
|
serializeOverrideFunc(statement, out, options...)
|
||||||
} else {
|
} else {
|
||||||
c.lhs.serialize(statement, out)
|
c.lhs.serialize(statement, out)
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,7 @@ func TO_HEX(number IntegerExpression) StringExpression {
|
||||||
// REGEXP_LIKE Returns 1 if the string expr matches the regular expression specified by the pattern pat, 0 otherwise.
|
// REGEXP_LIKE Returns 1 if the string expr matches the regular expression specified by the pattern pat, 0 otherwise.
|
||||||
func REGEXP_LIKE(stringExp StringExpression, pattern StringExpression, matchType ...string) BoolExpression {
|
func REGEXP_LIKE(stringExp StringExpression, pattern StringExpression, matchType ...string) BoolExpression {
|
||||||
if len(matchType) > 0 {
|
if len(matchType) > 0 {
|
||||||
return newBoolFunc("REGEXP_LIKE", stringExp, pattern, String(matchType[0], true))
|
return newBoolFunc("REGEXP_LIKE", stringExp, pattern, ConstLiteral(matchType[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
return newBoolFunc("REGEXP_LIKE", stringExp, pattern)
|
return newBoolFunc("REGEXP_LIKE", stringExp, pattern)
|
||||||
|
|
@ -391,7 +391,7 @@ func CURRENT_TIME(precision ...int) TimezExpression {
|
||||||
var timezFunc *timezFunc
|
var timezFunc *timezFunc
|
||||||
|
|
||||||
if len(precision) > 0 {
|
if len(precision) > 0 {
|
||||||
timezFunc = newTimezFunc("CURRENT_TIME", constLiteral(precision[0]))
|
timezFunc = newTimezFunc("CURRENT_TIME", ConstLiteral(precision[0]))
|
||||||
} else {
|
} else {
|
||||||
timezFunc = newTimezFunc("CURRENT_TIME")
|
timezFunc = newTimezFunc("CURRENT_TIME")
|
||||||
}
|
}
|
||||||
|
|
@ -406,7 +406,7 @@ func CURRENT_TIMESTAMP(precision ...int) TimestampzExpression {
|
||||||
var timestampzFunc *timestampzFunc
|
var timestampzFunc *timestampzFunc
|
||||||
|
|
||||||
if len(precision) > 0 {
|
if len(precision) > 0 {
|
||||||
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP", constLiteral(precision[0]))
|
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP", ConstLiteral(precision[0]))
|
||||||
} else {
|
} else {
|
||||||
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP")
|
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP")
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +421,7 @@ func LOCALTIME(precision ...int) TimeExpression {
|
||||||
var timeFunc *timeFunc
|
var timeFunc *timeFunc
|
||||||
|
|
||||||
if len(precision) > 0 {
|
if len(precision) > 0 {
|
||||||
timeFunc = newTimeFunc("LOCALTIME", constLiteral(precision[0]))
|
timeFunc = newTimeFunc("LOCALTIME", ConstLiteral(precision[0]))
|
||||||
} else {
|
} else {
|
||||||
timeFunc = newTimeFunc("LOCALTIME")
|
timeFunc = newTimeFunc("LOCALTIME")
|
||||||
}
|
}
|
||||||
|
|
@ -436,7 +436,7 @@ func LOCALTIMESTAMP(precision ...int) TimestampExpression {
|
||||||
var timestampFunc *timestampFunc
|
var timestampFunc *timestampFunc
|
||||||
|
|
||||||
if len(precision) > 0 {
|
if len(precision) > 0 {
|
||||||
timestampFunc = NewTimestampFunc("LOCALTIMESTAMP", constLiteral(precision[0]))
|
timestampFunc = NewTimestampFunc("LOCALTIMESTAMP", ConstLiteral(precision[0]))
|
||||||
} else {
|
} else {
|
||||||
timestampFunc = NewTimestampFunc("LOCALTIMESTAMP")
|
timestampFunc = NewTimestampFunc("LOCALTIMESTAMP")
|
||||||
}
|
}
|
||||||
|
|
@ -505,7 +505,7 @@ func newFunc(name string, expressions []Expression, parent Expression) *funcExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *funcExpressionImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) {
|
func (f *funcExpressionImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) {
|
||||||
if serializeOverride := out.Dialect.SerializeOverride(f.name); serializeOverride != nil {
|
if serializeOverride := out.Dialect.FunctionSerializeOverride(f.name); serializeOverride != nil {
|
||||||
serializeOverrideFunc := serializeOverride(f.expressions...)
|
serializeOverrideFunc := serializeOverride(f.expressions...)
|
||||||
serializeOverrideFunc(statement, out, options...)
|
serializeOverrideFunc(statement, out, options...)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ func TestIntExpressionPOW(t *testing.T) {
|
||||||
|
|
||||||
func TestIntExpressionBIT_NOT(t *testing.T) {
|
func TestIntExpressionBIT_NOT(t *testing.T) {
|
||||||
assertClauseSerialize(t, BIT_NOT(table2ColInt), "(~ table2.col_int)")
|
assertClauseSerialize(t, BIT_NOT(table2ColInt), "(~ table2.col_int)")
|
||||||
assertClauseSerialize(t, BIT_NOT(Int(11)), "(~ $1)", int64(11))
|
assertClauseSerialize(t, BIT_NOT(Int(11)), "(~ 11)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIntExpressionBIT_AND(t *testing.T) {
|
func TestIntExpressionBIT_AND(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ func literal(value interface{}, optionalConstant ...bool) *literalExpressionImpl
|
||||||
return &exp
|
return &exp
|
||||||
}
|
}
|
||||||
|
|
||||||
func constLiteral(value interface{}) *literalExpressionImpl {
|
func ConstLiteral(value interface{}) *literalExpressionImpl {
|
||||||
exp := literal(value)
|
exp := literal(value)
|
||||||
exp.constant = true
|
exp.constant = true
|
||||||
|
|
||||||
|
|
@ -61,13 +61,10 @@ type integerLiteralExpression struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int is constructor for integer expressions literals.
|
// Int is constructor for integer expressions literals.
|
||||||
func Int(value int64, constant ...bool) IntegerExpression {
|
func Int(value int64) IntegerExpression {
|
||||||
numLiteral := &integerLiteralExpression{}
|
numLiteral := &integerLiteralExpression{}
|
||||||
|
|
||||||
numLiteral.literalExpressionImpl = *literal(value)
|
numLiteral.literalExpressionImpl = *literal(value)
|
||||||
if len(constant) > 0 && constant[0] == true {
|
|
||||||
numLiteral.constant = true
|
|
||||||
}
|
|
||||||
|
|
||||||
numLiteral.literalExpressionImpl.Parent = numLiteral
|
numLiteral.literalExpressionImpl.Parent = numLiteral
|
||||||
numLiteral.integerInterfaceImpl.parent = numLiteral
|
numLiteral.integerInterfaceImpl.parent = numLiteral
|
||||||
|
|
@ -114,12 +111,9 @@ type stringLiteral struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// String creates new string literal expression
|
// String creates new string literal expression
|
||||||
func String(value string, constant ...bool) StringExpression {
|
func String(value string) StringExpression {
|
||||||
stringLiteral := stringLiteral{}
|
stringLiteral := stringLiteral{}
|
||||||
stringLiteral.literalExpressionImpl = *literal(value)
|
stringLiteral.literalExpressionImpl = *literal(value)
|
||||||
if len(constant) > 0 && constant[0] == true {
|
|
||||||
stringLiteral.constant = true
|
|
||||||
}
|
|
||||||
|
|
||||||
stringLiteral.stringInterfaceImpl.parent = &stringLiteral
|
stringLiteral.stringInterfaceImpl.parent = &stringLiteral
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package jet
|
||||||
|
|
||||||
const (
|
const (
|
||||||
StringConcatOperator = "||"
|
StringConcatOperator = "||"
|
||||||
|
StringRegexpLikeOperator = "REGEXP"
|
||||||
|
StringNotRegexpLikeOperator = "NOT REGEXP"
|
||||||
)
|
)
|
||||||
|
|
||||||
//----------- Logical operators ---------------//
|
//----------- Logical operators ---------------//
|
||||||
|
|
@ -13,6 +15,9 @@ func NOT(exp BoolExpression) BoolExpression {
|
||||||
|
|
||||||
// BIT_NOT inverts every bit in integer expression result
|
// BIT_NOT inverts every bit in integer expression result
|
||||||
func BIT_NOT(expr IntegerExpression) IntegerExpression {
|
func BIT_NOT(expr IntegerExpression) IntegerExpression {
|
||||||
|
if literalExp, ok := expr.(LiteralExpression); ok {
|
||||||
|
literalExp.SetConstant(true)
|
||||||
|
}
|
||||||
return newPrefixIntegerOperator(expr, "~")
|
return newPrefixIntegerOperator(expr, "~")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ type StringExpression interface {
|
||||||
LIKE(pattern StringExpression) BoolExpression
|
LIKE(pattern StringExpression) BoolExpression
|
||||||
NOT_LIKE(pattern StringExpression) BoolExpression
|
NOT_LIKE(pattern StringExpression) BoolExpression
|
||||||
|
|
||||||
REGEXP_LIKE(pattern StringExpression, matchType ...string) BoolExpression
|
REGEXP_LIKE(pattern StringExpression, caseSensitive ...bool) BoolExpression
|
||||||
|
NOT_REGEXP_LIKE(pattern StringExpression, caseSensitive ...bool) BoolExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
type stringInterfaceImpl struct {
|
type stringInterfaceImpl struct {
|
||||||
|
|
@ -70,11 +71,16 @@ func (s *stringInterfaceImpl) NOT_LIKE(pattern StringExpression) BoolExpression
|
||||||
return newBinaryBoolOperator(s.parent, pattern, "NOT LIKE")
|
return newBinaryBoolOperator(s.parent, pattern, "NOT LIKE")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stringInterfaceImpl) REGEXP_LIKE(pattern StringExpression, matchType ...string) BoolExpression {
|
func (s *stringInterfaceImpl) REGEXP_LIKE(pattern StringExpression, caseSensitive ...bool) BoolExpression {
|
||||||
return REGEXP_LIKE(s.parent, pattern, matchType...)
|
return newBinaryBoolOperator(s.parent, pattern, StringRegexpLikeOperator, Bool(len(caseSensitive) > 0 && caseSensitive[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stringInterfaceImpl) NOT_REGEXP_LIKE(pattern StringExpression, caseSensitive ...bool) BoolExpression {
|
||||||
|
return newBinaryBoolOperator(s.parent, pattern, StringNotRegexpLikeOperator, Bool(len(caseSensitive) > 0 && caseSensitive[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------//
|
//---------------------------------------------------//
|
||||||
|
|
||||||
type binaryStringExpression struct {
|
type binaryStringExpression struct {
|
||||||
ExpressionInterfaceImpl
|
ExpressionInterfaceImpl
|
||||||
stringInterfaceImpl
|
stringInterfaceImpl
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,13 @@ func TestStringNOT_LIKE(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringREGEXP_LIKE(t *testing.T) {
|
func TestStringREGEXP_LIKE(t *testing.T) {
|
||||||
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(table2ColStr), "REGEXP_LIKE(table3.col2, table2.col_str)")
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(table2ColStr), "(table3.col2 REGEXP table2.col_str)")
|
||||||
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN"), "c"), "REGEXP_LIKE(table3.col2, $1, 'c')", "JOHN")
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN"), true), "(table3.col2 REGEXP $1)", "JOHN")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStringNOT_REGEXP_LIKE(t *testing.T) {
|
||||||
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(table2ColStr), "(table3.col2 NOT REGEXP table2.col_str)")
|
||||||
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(String("JOHN"), true), "(table3.col2 NOT REGEXP $1)", "JOHN")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringExp(t *testing.T) {
|
func TestStringExp(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ type castImpl struct {
|
||||||
jet.Cast
|
jet.Cast
|
||||||
}
|
}
|
||||||
|
|
||||||
func CAST(expr jet.Expression) cast {
|
func CAST(expr Expression) cast {
|
||||||
castImpl := &castImpl{}
|
castImpl := &castImpl{}
|
||||||
|
|
||||||
castImpl.Cast = jet.NewCastImpl(expr)
|
castImpl.Cast = jet.NewCastImpl(expr)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package mysql
|
||||||
import "github.com/go-jet/jet/internal/jet"
|
import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
type DeleteStatement interface {
|
type DeleteStatement interface {
|
||||||
jet.Statement
|
Statement
|
||||||
|
|
||||||
WHERE(expression BoolExpression) DeleteStatement
|
WHERE(expression BoolExpression) DeleteStatement
|
||||||
ORDER_BY(orderByClauses ...jet.OrderByClause) DeleteStatement
|
ORDER_BY(orderByClauses ...jet.OrderByClause) DeleteStatement
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,19 @@ var Dialect = NewDialect()
|
||||||
|
|
||||||
func NewDialect() jet.Dialect {
|
func NewDialect() jet.Dialect {
|
||||||
|
|
||||||
serializeOverrides := map[string]jet.SerializeOverride{}
|
operatorSerializeOverrides := map[string]jet.SerializeOverride{}
|
||||||
serializeOverrides["IS DISTINCT FROM"] = mysql_IS_DISTINCT_FROM
|
operatorSerializeOverrides[jet.StringRegexpLikeOperator] = mysql_REGEXP_LIKE_operator
|
||||||
serializeOverrides["IS NOT DISTINCT FROM"] = mysql_IS_NOT_DISTINCT_FROM
|
operatorSerializeOverrides[jet.StringNotRegexpLikeOperator] = mysql_NOT_REGEXP_LIKE_operator
|
||||||
serializeOverrides["/"] = mysql_DIVISION
|
operatorSerializeOverrides["IS DISTINCT FROM"] = mysql_IS_DISTINCT_FROM
|
||||||
serializeOverrides["#"] = mysql_BIT_XOR
|
operatorSerializeOverrides["IS NOT DISTINCT FROM"] = mysql_IS_NOT_DISTINCT_FROM
|
||||||
serializeOverrides[jet.StringConcatOperator] = mysql_CONCAT_operator
|
operatorSerializeOverrides["/"] = mysql_DIVISION
|
||||||
|
operatorSerializeOverrides["#"] = mysql_BIT_XOR
|
||||||
|
operatorSerializeOverrides[jet.StringConcatOperator] = mysql_CONCAT_operator
|
||||||
|
|
||||||
mySQLDialectParams := jet.DialectParams{
|
mySQLDialectParams := jet.DialectParams{
|
||||||
Name: "MySQL",
|
Name: "MySQL",
|
||||||
PackageName: "mysql",
|
PackageName: "mysql",
|
||||||
SerializeOverrides: serializeOverrides,
|
OperatorSerializeOverrides: operatorSerializeOverrides,
|
||||||
AliasQuoteChar: '"',
|
AliasQuoteChar: '"',
|
||||||
IdentifierQuoteChar: '`',
|
IdentifierQuoteChar: '`',
|
||||||
ArgumentPlaceholder: func(int) string {
|
ArgumentPlaceholder: func(int) string {
|
||||||
|
|
@ -31,7 +33,7 @@ func NewDialect() jet.Dialect {
|
||||||
|
|
||||||
func mysql_BIT_XOR(expressions ...jet.Expression) jet.SerializeFunc {
|
func mysql_BIT_XOR(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
||||||
if len(expressions) != 2 {
|
if len(expressions) < 2 {
|
||||||
panic("jet: invalid number of expressions for operator XOR")
|
panic("jet: invalid number of expressions for operator XOR")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +50,7 @@ func mysql_BIT_XOR(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
|
|
||||||
func mysql_CONCAT_operator(expressions ...jet.Expression) jet.SerializeFunc {
|
func mysql_CONCAT_operator(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
||||||
if len(expressions) != 2 {
|
if len(expressions) < 2 {
|
||||||
panic("jet: invalid number of expressions for operator CONCAT")
|
panic("jet: invalid number of expressions for operator CONCAT")
|
||||||
}
|
}
|
||||||
out.WriteString("CONCAT(")
|
out.WriteString("CONCAT(")
|
||||||
|
|
@ -65,7 +67,7 @@ func mysql_CONCAT_operator(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
|
|
||||||
func mysql_DIVISION(expressions ...jet.Expression) jet.SerializeFunc {
|
func mysql_DIVISION(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
||||||
if len(expressions) != 2 {
|
if len(expressions) < 2 {
|
||||||
panic("jet: invalid number of expressions for operator DIV")
|
panic("jet: invalid number of expressions for operator DIV")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +91,7 @@ func mysql_DIVISION(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
|
|
||||||
func mysql_IS_NOT_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc {
|
func mysql_IS_NOT_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
||||||
if len(expressions) != 2 {
|
if len(expressions) < 2 {
|
||||||
panic("jet: invalid number of expressions for operator")
|
panic("jet: invalid number of expressions for operator")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,3 +108,55 @@ func mysql_IS_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
out.WriteString(")")
|
out.WriteString(")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mysql_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
|
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
||||||
|
if len(expressions) < 2 {
|
||||||
|
panic("jet: invalid number of expressions for operator")
|
||||||
|
}
|
||||||
|
|
||||||
|
jet.Serialize(expressions[0], statement, out, options...)
|
||||||
|
|
||||||
|
caseSensitive := false
|
||||||
|
|
||||||
|
if len(expressions) >= 3 {
|
||||||
|
if stringLiteral, ok := expressions[2].(jet.LiteralExpression); ok {
|
||||||
|
caseSensitive = stringLiteral.Value().(bool)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.WriteString("REGEXP")
|
||||||
|
|
||||||
|
if caseSensitive {
|
||||||
|
out.WriteString("BINARY")
|
||||||
|
}
|
||||||
|
|
||||||
|
jet.Serialize(expressions[1], statement, out, options...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mysql_NOT_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
|
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
||||||
|
if len(expressions) < 2 {
|
||||||
|
panic("jet: invalid number of expressions for operator")
|
||||||
|
}
|
||||||
|
|
||||||
|
jet.Serialize(expressions[0], statement, out, options...)
|
||||||
|
|
||||||
|
caseSensitive := false
|
||||||
|
|
||||||
|
if len(expressions) >= 3 {
|
||||||
|
if stringLiteral, ok := expressions[2].(jet.LiteralExpression); ok {
|
||||||
|
caseSensitive = stringLiteral.Value().(bool)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.WriteString("NOT REGEXP")
|
||||||
|
|
||||||
|
if caseSensitive {
|
||||||
|
out.WriteString("BINARY")
|
||||||
|
}
|
||||||
|
|
||||||
|
jet.Serialize(expressions[1], statement, out, options...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,17 @@ func TestExists(t *testing.T) {
|
||||||
WHERE table1.col1 = table2.col3
|
WHERE table1.col1 = table2.col3
|
||||||
))`, int64(1))
|
))`, int64(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestString_REGEXP_LIKE_operator(t *testing.T) {
|
||||||
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(table2ColStr), "(table3.col2 REGEXP table2.col_str)")
|
||||||
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN")), "(table3.col2 REGEXP ?)", "JOHN")
|
||||||
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN"), false), "(table3.col2 REGEXP ?)", "JOHN")
|
||||||
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN"), true), "(table3.col2 REGEXP BINARY ?)", "JOHN")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestString_NOT_REGEXP_LIKE_operator(t *testing.T) {
|
||||||
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(table2ColStr), "(table3.col2 NOT REGEXP table2.col_str)")
|
||||||
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(String("JOHN")), "(table3.col2 NOT REGEXP ?)", "JOHN")
|
||||||
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(String("JOHN"), false), "(table3.col2 NOT REGEXP ?)", "JOHN")
|
||||||
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(String("JOHN"), true), "(table3.col2 NOT REGEXP BINARY ?)", "JOHN")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,5 +32,3 @@ var TimestampExp = jet.TimestampExp
|
||||||
var Raw = jet.Raw
|
var Raw = jet.Raw
|
||||||
|
|
||||||
var NewEnumValue = jet.NewEnumValue
|
var NewEnumValue = jet.NewEnumValue
|
||||||
|
|
||||||
type Statement jet.Statement
|
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ func CURRENT_TIMESTAMP(precision ...int) TimestampExpression {
|
||||||
// NOW returns current datetime
|
// NOW returns current datetime
|
||||||
func NOW(fsp ...int) DateTimeExpression {
|
func NOW(fsp ...int) DateTimeExpression {
|
||||||
if len(fsp) > 0 {
|
if len(fsp) > 0 {
|
||||||
return jet.NewTimestampFunc("NOW", Int(int64(fsp[0]), true))
|
return jet.NewTimestampFunc("NOW", jet.ConstLiteral(int64(fsp[0])))
|
||||||
}
|
}
|
||||||
return jet.NewTimestampFunc("NOW")
|
return jet.NewTimestampFunc("NOW")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
// InsertStatement is interface for SQL INSERT statements
|
// InsertStatement is interface for SQL INSERT statements
|
||||||
type InsertStatement interface {
|
type InsertStatement interface {
|
||||||
jet.Statement
|
Statement
|
||||||
|
|
||||||
// Insert row of values
|
// Insert row of values
|
||||||
VALUES(value interface{}, values ...interface{}) InsertStatement
|
VALUES(value interface{}, values ...interface{}) InsertStatement
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type SelectStatement interface {
|
type SelectStatement interface {
|
||||||
jet.Statement
|
Statement
|
||||||
jet.HasProjections
|
jet.HasProjections
|
||||||
jet.Expression
|
Expression
|
||||||
|
|
||||||
DISTINCT() SelectStatement
|
DISTINCT() SelectStatement
|
||||||
FROM(table ReadableTable) SelectStatement
|
FROM(table ReadableTable) SelectStatement
|
||||||
|
|
@ -23,6 +23,7 @@ type SelectStatement interface {
|
||||||
LIMIT(limit int64) SelectStatement
|
LIMIT(limit int64) SelectStatement
|
||||||
OFFSET(offset int64) SelectStatement
|
OFFSET(offset int64) SelectStatement
|
||||||
FOR(lock SelectLock) SelectStatement
|
FOR(lock SelectLock) SelectStatement
|
||||||
|
LOCK_IN_SHARE_MODE() SelectStatement
|
||||||
|
|
||||||
UNION(rhs SelectStatement) SetStatement
|
UNION(rhs SelectStatement) SetStatement
|
||||||
UNION_ALL(rhs SelectStatement) SetStatement
|
UNION_ALL(rhs SelectStatement) SetStatement
|
||||||
|
|
@ -31,22 +32,24 @@ type SelectStatement interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
//SELECT creates new SelectStatement with list of projections
|
//SELECT creates new SelectStatement with list of projections
|
||||||
func SELECT(projection jet.Projection, projections ...jet.Projection) SelectStatement {
|
func SELECT(projection Projection, projections ...Projection) SelectStatement {
|
||||||
return newSelectStatement(nil, append([]jet.Projection{projection}, projections...))
|
return newSelectStatement(nil, append([]Projection{projection}, projections...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSelectStatement(table ReadableTable, projections []jet.Projection) SelectStatement {
|
func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement {
|
||||||
newSelect := &selectStatementImpl{}
|
newSelect := &selectStatementImpl{}
|
||||||
newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
||||||
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy,
|
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy,
|
||||||
&newSelect.Limit, &newSelect.Offset, &newSelect.For)
|
&newSelect.Limit, &newSelect.Offset, &newSelect.For, &newSelect.ShareLock)
|
||||||
|
|
||||||
newSelect.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSelect
|
newSelect.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSelect
|
||||||
|
|
||||||
newSelect.Select.Projections = projections
|
newSelect.Select.Projections = toJetProjectionList(projections)
|
||||||
newSelect.From.Table = table
|
newSelect.From.Table = table
|
||||||
newSelect.Limit.Count = -1
|
newSelect.Limit.Count = -1
|
||||||
newSelect.Offset.Count = -1
|
newSelect.Offset.Count = -1
|
||||||
|
newSelect.ShareLock.Name = "LOCK IN SHARE MODE"
|
||||||
|
newSelect.ShareLock.InNewLine = true
|
||||||
|
|
||||||
newSelect.setOperatorsImpl.parent = newSelect
|
newSelect.setOperatorsImpl.parent = newSelect
|
||||||
|
|
||||||
|
|
@ -66,6 +69,7 @@ type selectStatementImpl struct {
|
||||||
Limit jet.ClauseLimit
|
Limit jet.ClauseLimit
|
||||||
Offset jet.ClauseOffset
|
Offset jet.ClauseOffset
|
||||||
For jet.ClauseFor
|
For jet.ClauseFor
|
||||||
|
ShareLock jet.ClauseOptional
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *selectStatementImpl) DISTINCT() SelectStatement {
|
func (s *selectStatementImpl) DISTINCT() SelectStatement {
|
||||||
|
|
@ -113,6 +117,11 @@ func (s *selectStatementImpl) FOR(lock SelectLock) SelectStatement {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *selectStatementImpl) LOCK_IN_SHARE_MODE() SelectStatement {
|
||||||
|
s.ShareLock.Show = true
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
func (s *selectStatementImpl) AsTable(alias string) SelectTable {
|
func (s *selectStatementImpl) AsTable(alias string) SelectTable {
|
||||||
return newSelectTable(s, alias)
|
return newSelectTable(s, alias)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,3 +124,11 @@ FROM db.table1
|
||||||
FOR SHARE NOWAIT;
|
FOR SHARE NOWAIT;
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSelect_LOCK_IN_SHARE_MODE(t *testing.T) {
|
||||||
|
testutils.AssertStatementSql(t, SELECT(table1ColBool).FROM(table1).LOCK_IN_SHARE_MODE(), `
|
||||||
|
SELECT table1.col_bool AS "table1.col_bool"
|
||||||
|
FROM db.table1
|
||||||
|
LOCK IN SHARE MODE;
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ type Table interface {
|
||||||
|
|
||||||
type readableTable interface {
|
type readableTable interface {
|
||||||
// Generates a select query on the current tableName.
|
// Generates a select query on the current tableName.
|
||||||
SELECT(projection jet.Projection, projections ...jet.Projection) SelectStatement
|
SELECT(projection Projection, projections ...Projection) SelectStatement
|
||||||
|
|
||||||
// Creates a inner join tableName Expression using onCondition.
|
// Creates a inner join tableName Expression using onCondition.
|
||||||
INNER_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable
|
INNER_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable
|
||||||
|
|
@ -47,8 +47,8 @@ type readableTableInterfaceImpl struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates a select query on the current tableName.
|
// Generates a select query on the current tableName.
|
||||||
func (r *readableTableInterfaceImpl) SELECT(projection1 jet.Projection, projections ...jet.Projection) SelectStatement {
|
func (r *readableTableInterfaceImpl) SELECT(projection1 Projection, projections ...Projection) SelectStatement {
|
||||||
return newSelectStatement(r.parent, append([]jet.Projection{projection1}, projections...))
|
return newSelectStatement(r.parent, append([]Projection{projection1}, projections...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a inner join tableName Expression using onCondition.
|
// Creates a inner join tableName Expression using onCondition.
|
||||||
|
|
|
||||||
16
mysql/types.go
Normal file
16
mysql/types.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
|
type Statement jet.Statement
|
||||||
|
type Projection jet.Projection
|
||||||
|
|
||||||
|
func toJetProjectionList(projections []Projection) []jet.Projection {
|
||||||
|
ret := []jet.Projection{}
|
||||||
|
|
||||||
|
for _, projection := range projections {
|
||||||
|
ret = append(ret, projection)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
@ -3,21 +3,21 @@ package postgres
|
||||||
import (
|
import (
|
||||||
"github.com/go-jet/jet/internal/jet"
|
"github.com/go-jet/jet/internal/jet"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var Dialect = NewDialect()
|
var Dialect = NewDialect()
|
||||||
|
|
||||||
func NewDialect() jet.Dialect {
|
func NewDialect() jet.Dialect {
|
||||||
|
|
||||||
serializeOverrides := map[string]jet.SerializeOverride{}
|
operatorSerializeOverrides := map[string]jet.SerializeOverride{}
|
||||||
serializeOverrides["REGEXP_LIKE"] = postgres_REGEXP_LIKE_function
|
operatorSerializeOverrides[jet.StringRegexpLikeOperator] = postgres_REGEXP_LIKE_operator
|
||||||
serializeOverrides["CAST"] = postgresCAST
|
operatorSerializeOverrides[jet.StringNotRegexpLikeOperator] = postgres_NOT_REGEXP_LIKE_operator
|
||||||
|
operatorSerializeOverrides["CAST"] = postgresCAST
|
||||||
|
|
||||||
dialectParams := jet.DialectParams{
|
dialectParams := jet.DialectParams{
|
||||||
Name: "PostgreSQL",
|
Name: "PostgreSQL",
|
||||||
PackageName: "postgres",
|
PackageName: "postgres",
|
||||||
SerializeOverrides: serializeOverrides,
|
OperatorSerializeOverrides: operatorSerializeOverrides,
|
||||||
AliasQuoteChar: '"',
|
AliasQuoteChar: '"',
|
||||||
IdentifierQuoteChar: '"',
|
IdentifierQuoteChar: '"',
|
||||||
ArgumentPlaceholder: func(ord int) string {
|
ArgumentPlaceholder: func(ord int) string {
|
||||||
|
|
@ -53,7 +53,7 @@ func postgresCAST(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func postgres_REGEXP_LIKE_function(expressions ...jet.Expression) jet.SerializeFunc {
|
func postgres_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
||||||
if len(expressions) < 2 {
|
if len(expressions) < 2 {
|
||||||
panic("jet: invalid number of expressions for operator")
|
panic("jet: invalid number of expressions for operator")
|
||||||
|
|
@ -65,9 +65,7 @@ func postgres_REGEXP_LIKE_function(expressions ...jet.Expression) jet.SerializeF
|
||||||
|
|
||||||
if len(expressions) >= 3 {
|
if len(expressions) >= 3 {
|
||||||
if stringLiteral, ok := expressions[2].(jet.LiteralExpression); ok {
|
if stringLiteral, ok := expressions[2].(jet.LiteralExpression); ok {
|
||||||
matchType := stringLiteral.Value().(string)
|
caseSensitive = stringLiteral.Value().(bool)
|
||||||
|
|
||||||
caseSensitive = !strings.Contains(matchType, "i")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,3 +78,29 @@ func postgres_REGEXP_LIKE_function(expressions ...jet.Expression) jet.SerializeF
|
||||||
jet.Serialize(expressions[1], statement, out, options...)
|
jet.Serialize(expressions[1], statement, out, options...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func postgres_NOT_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeFunc {
|
||||||
|
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) {
|
||||||
|
if len(expressions) < 2 {
|
||||||
|
panic("jet: invalid number of expressions for operator")
|
||||||
|
}
|
||||||
|
|
||||||
|
jet.Serialize(expressions[0], statement, out, options...)
|
||||||
|
|
||||||
|
caseSensitive := false
|
||||||
|
|
||||||
|
if len(expressions) >= 3 {
|
||||||
|
if stringLiteral, ok := expressions[2].(jet.LiteralExpression); ok {
|
||||||
|
caseSensitive = stringLiteral.Value().(bool)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if caseSensitive {
|
||||||
|
out.WriteString("!~")
|
||||||
|
} else {
|
||||||
|
out.WriteString("!~*")
|
||||||
|
}
|
||||||
|
|
||||||
|
jet.Serialize(expressions[1], statement, out, options...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,17 @@ package postgres
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestString_REGEXP_LIKE_operator(t *testing.T) {
|
func TestString_REGEXP_LIKE_operator(t *testing.T) {
|
||||||
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(table2ColStr), "table3.col2 ~* table2.col_str")
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(table2ColStr), "(table3.col2 ~* table2.col_str)")
|
||||||
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN"), "c"), "table3.col2 ~ $1", "JOHN")
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN")), "(table3.col2 ~* $1)", "JOHN")
|
||||||
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN"), "i"), "table3.col2 ~* $1", "JOHN")
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN"), false), "(table3.col2 ~* $1)", "JOHN")
|
||||||
|
assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN"), true), "(table3.col2 ~ $1)", "JOHN")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestString_REGEXP_LIKE_function(t *testing.T) {
|
func TestString_NOT_REGEXP_LIKE_operator(t *testing.T) {
|
||||||
assertClauseSerialize(t, REGEXP_LIKE(table3StrCol, table2ColStr), "table3.col2 ~* table2.col_str")
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(table2ColStr), "(table3.col2 !~* table2.col_str)")
|
||||||
assertClauseSerialize(t, REGEXP_LIKE(table3StrCol, String("JOHN"), "c"), "table3.col2 ~ $1", "JOHN")
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(String("JOHN")), "(table3.col2 !~* $1)", "JOHN")
|
||||||
assertClauseSerialize(t, REGEXP_LIKE(table3StrCol, String("JOHN"), "i"), "table3.col2 ~* $1", "JOHN")
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(String("JOHN"), false), "(table3.col2 !~* $1)", "JOHN")
|
||||||
|
assertClauseSerialize(t, table3StrCol.NOT_REGEXP_LIKE(String("JOHN"), true), "(table3.col2 !~ $1)", "JOHN")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExists(t *testing.T) {
|
func TestExists(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ var SUMi = jet.SUMi
|
||||||
|
|
||||||
//--------------------- String functions ------------------//
|
//--------------------- String functions ------------------//
|
||||||
|
|
||||||
var REGEXP_LIKE = jet.REGEXP_LIKE
|
|
||||||
var BIT_LENGTH = jet.BIT_LENGTH
|
var BIT_LENGTH = jet.BIT_LENGTH
|
||||||
var CHAR_LENGTH = jet.CHAR_LENGTH
|
var CHAR_LENGTH = jet.CHAR_LENGTH
|
||||||
var OCTET_LENGTH = jet.OCTET_LENGTH
|
var OCTET_LENGTH = jet.OCTET_LENGTH
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,11 @@ type SelectStatement interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
//SELECT creates new SelectStatement with list of projections
|
//SELECT creates new SelectStatement with list of projections
|
||||||
func SELECT(projection jet.Projection, projections ...jet.Projection) SelectStatement {
|
func SELECT(projection Projection, projections ...Projection) SelectStatement {
|
||||||
return newSelectStatement(nil, append([]jet.Projection{projection}, projections...))
|
return newSelectStatement(nil, append([]Projection{projection}, projections...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSelectStatement(table ReadableTable, projections []jet.Projection) SelectStatement {
|
func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement {
|
||||||
newSelect := &selectStatementImpl{}
|
newSelect := &selectStatementImpl{}
|
||||||
newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
||||||
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy,
|
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy,
|
||||||
|
|
@ -49,7 +49,7 @@ func newSelectStatement(table ReadableTable, projections []jet.Projection) Selec
|
||||||
|
|
||||||
newSelect.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSelect
|
newSelect.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSelect
|
||||||
|
|
||||||
newSelect.Select.Projections = projections
|
newSelect.Select.Projections = toJetProjectionList(projections)
|
||||||
newSelect.From.Table = table
|
newSelect.From.Table = table
|
||||||
newSelect.Limit.Count = -1
|
newSelect.Limit.Count = -1
|
||||||
newSelect.Offset.Count = -1
|
newSelect.Offset.Count = -1
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
type readableTable interface {
|
type readableTable interface {
|
||||||
// Generates a select query on the current tableName.
|
// Generates a select query on the current tableName.
|
||||||
SELECT(projection jet.Projection, projections ...jet.Projection) SelectStatement
|
SELECT(projection Projection, projections ...Projection) SelectStatement
|
||||||
|
|
||||||
// Creates a inner join tableName Expression using onCondition.
|
// Creates a inner join tableName Expression using onCondition.
|
||||||
INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
|
INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
|
||||||
|
|
@ -52,8 +52,8 @@ type readableTableInterfaceImpl struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates a select query on the current tableName.
|
// Generates a select query on the current tableName.
|
||||||
func (r *readableTableInterfaceImpl) SELECT(projection1 jet.Projection, projections ...jet.Projection) SelectStatement {
|
func (r *readableTableInterfaceImpl) SELECT(projection1 Projection, projections ...Projection) SelectStatement {
|
||||||
return newSelectStatement(r.parent, append([]jet.Projection{projection1}, projections...))
|
return newSelectStatement(r.parent, append([]Projection{projection1}, projections...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a inner join tableName Expression using onCondition.
|
// Creates a inner join tableName Expression using onCondition.
|
||||||
|
|
|
||||||
16
postgres/types.go
Normal file
16
postgres/types.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package postgres
|
||||||
|
|
||||||
|
import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
|
type Statement jet.Statement
|
||||||
|
type Projection jet.Projection
|
||||||
|
|
||||||
|
func toJetProjectionList(projections []Projection) []jet.Projection {
|
||||||
|
ret := []jet.Projection{}
|
||||||
|
|
||||||
|
for _, projection := range projections {
|
||||||
|
ret = append(ret, projection)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,159 +0,0 @@
|
||||||
-- MySQL dump 10.13 Distrib 8.0.16, for Linux (x86_64)
|
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `all_types8`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `all_types`;
|
|
||||||
|
|
||||||
CREATE TABLE `all_types` (
|
|
||||||
`boolean` BOOLEAN NOT NULL,
|
|
||||||
`boolean_ptr` BOOLEAN,
|
|
||||||
|
|
||||||
`tiny_int` TINYINT NOT NULL,
|
|
||||||
`u_tiny_int` TINYINT unsigned NOT NULL,
|
|
||||||
|
|
||||||
`small_int` SMALLINT NOT NULL,
|
|
||||||
`u_small_int` SMALLINT unsigned NOT NULL,
|
|
||||||
|
|
||||||
`medium_int` MEDIUMINT NOT NULL,
|
|
||||||
`u_medium_int` MEDIUMINT unsigned NOT NULL,
|
|
||||||
|
|
||||||
`integer` INT NOT NULL,
|
|
||||||
`u_integer` INT unsigned NOT NULL,
|
|
||||||
|
|
||||||
`big_int` bigint(20) NOT NULL,
|
|
||||||
`u_big_int` bigint(20) unsigned NOT NULL,
|
|
||||||
|
|
||||||
-- ptr
|
|
||||||
|
|
||||||
`tiny_int_ptr` TINYINT,
|
|
||||||
`u_tiny_int_ptr` TINYINT unsigned,
|
|
||||||
|
|
||||||
`small_int_ptr` SMALLINT,
|
|
||||||
`u_small_int_ptr` SMALLINT unsigned,
|
|
||||||
|
|
||||||
`medium_int_ptr` MEDIUMINT,
|
|
||||||
`u_medium_int_ptr` MEDIUMINT unsigned,
|
|
||||||
|
|
||||||
`integer_ptr` INT,
|
|
||||||
`u_integer_ptr` INT unsigned,
|
|
||||||
|
|
||||||
`big_int_ptr` bigint(20),
|
|
||||||
`u_big_int_ptr` bigint(20) unsigned,
|
|
||||||
|
|
||||||
|
|
||||||
-- floats
|
|
||||||
`decimal` decimal(5, 2) unsigned NOT NULL,
|
|
||||||
`decimal_ptr` decimal(5,2),
|
|
||||||
|
|
||||||
`numeric` numeric(5,2) NOT NULL,
|
|
||||||
`numeric_ptr` numeric(5, 2),
|
|
||||||
|
|
||||||
`float` float NOT NULL,
|
|
||||||
`float_ptr` float,
|
|
||||||
|
|
||||||
`double` double NOT NULL,
|
|
||||||
`double_ptr` double,
|
|
||||||
|
|
||||||
`real` real NOT NULL,
|
|
||||||
`real_ptr` real,
|
|
||||||
|
|
||||||
-- bit values
|
|
||||||
|
|
||||||
`bit` bit(10) NOT NULL,
|
|
||||||
`bit_ptr` bit(10),
|
|
||||||
|
|
||||||
-- date and time
|
|
||||||
`time` time NOT NULL,
|
|
||||||
`time_ptr` time,
|
|
||||||
|
|
||||||
`date` date NOT NULL,
|
|
||||||
`date_ptr` date,
|
|
||||||
|
|
||||||
`date_time` datetime NOT NULL,
|
|
||||||
`date_time_ptr` datetime,
|
|
||||||
|
|
||||||
`timestamp` timestamp NOT NULL,
|
|
||||||
`timestamp_ptr` timestamp,
|
|
||||||
|
|
||||||
`year` year NOT NULL,
|
|
||||||
`year_ptr` year,
|
|
||||||
|
|
||||||
-- strings
|
|
||||||
|
|
||||||
`char` char(20) NOT NULL,
|
|
||||||
`char_ptr` char(20),
|
|
||||||
|
|
||||||
`var_char` varchar(20) NOT NULL,
|
|
||||||
`var_char_ptr` varchar(20),
|
|
||||||
|
|
||||||
`binary` binary(20) NOT NULL,
|
|
||||||
`binary_ptr` binary(20),
|
|
||||||
|
|
||||||
`var_binary` varbinary(20) NOT NULL,
|
|
||||||
`var_binary_ptr` varbinary(20),
|
|
||||||
|
|
||||||
`blob` blob NOT NULL,
|
|
||||||
`blob_ptr` blob,
|
|
||||||
|
|
||||||
`text` text NOT NULL,
|
|
||||||
`text_ptr` text,
|
|
||||||
|
|
||||||
`enum` enum('value1', 'value2', 'value3') NOT NULL,
|
|
||||||
`enum_ptr` enum('value1', 'value2', 'value3'),
|
|
||||||
|
|
||||||
`set` set('s1', 's2', 's3') NOT NULL,
|
|
||||||
`set_ptr` set('s1', 's2', 's3'),
|
|
||||||
|
|
||||||
-- json
|
|
||||||
|
|
||||||
`json` json NOT NULL,
|
|
||||||
`json_ptr` json
|
|
||||||
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
||||||
|
|
||||||
INSERT INTO `all_types` VALUES
|
|
||||||
(false, true,
|
|
||||||
-3,3,14,14,-150,150,-1600,1600,5000,50000,
|
|
||||||
-3,3,14,14,-150,150,-1600,1600,50000,50000,
|
|
||||||
1.11,1.11,2.22,2.22,3.33,3.33,4.44,4.44,5.55,5.55,
|
|
||||||
_binary '\0',_binary '\0',
|
|
||||||
'10:11:12.33', '10:11:12.33', '2008-07-04','2008-07-04','2011-12-18 13:17:17','2011-12-18 13:17:17','2007-12-31 23:00:01','2007-12-31 23:00:01',2004,2004,'char','char','varchar','varchar',_binary 'binary\0\0\0\0\0\0\0\0\0\0\0\0\0\0',_binary 'binary\0\0\0\0\0\0\0\0\0\0\0\0\0\0',_binary 'varbinary',_binary 'varbinary',_binary 'blob',_binary 'blob','text','text','value1','value1','s1','s2','{\"key1\": \"value1\", \"key2\": \"value2\"}','{\"key1\": \"value1\", \"key2\": \"value2\"}'),
|
|
||||||
(false, NULL,
|
|
||||||
-3,3,14,14,-150,150,-1600,1600,5000,50000,
|
|
||||||
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
|
||||||
1.11,NULL,2.22,NULL,3.33,NULL,4.44,NULL,5.55,NULL,
|
|
||||||
_binary '\0',NULL,
|
|
||||||
'10:11:12.33', NULL, '2008-07-04',NULL,'2011-12-18 13:17:17',NULL,'2007-12-31 23:00:01',NULL,2004,NULL,'char',NULL,'varchar',NULL,_binary 'binary\0\0\0\0\0\0\0\0\0\0\0\0\0\0',NULL,_binary 'varbinary',NULL,_binary 'blob',NULL,'text',NULL,'value1',NULL,'s1',NULL,'{\"key1\": \"value1\", \"key2\": \"value2\"}',NULL);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Link table --------------------
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS test_sample.link;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS test_sample.link (
|
|
||||||
id int PRIMARY KEY AUTO_INCREMENT,
|
|
||||||
url VARCHAR (255) NOT NULL,
|
|
||||||
name VARCHAR (255) NOT NULL,
|
|
||||||
description VARCHAR (255)
|
|
||||||
);
|
|
||||||
|
|
||||||
INSERT INTO test_sample.link (ID, url, name, description) VALUES
|
|
||||||
(0, 'http://www.youtube.com', 'Youtube' , '');
|
|
||||||
|
|
||||||
-- Link2 table --------------------
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS test_sample.link2;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS test_sample.link2 (
|
|
||||||
id int PRIMARY KEY AUTO_INCREMENT,
|
|
||||||
url VARCHAR (255) NOT NULL,
|
|
||||||
name VARCHAR (255) NOT NULL,
|
|
||||||
description VARCHAR (255)
|
|
||||||
);
|
|
||||||
|
|
||||||
INSERT INTO test_sample.link2 (ID, url, name, description) VALUES
|
|
||||||
(0, 'http://www.youtube.com', 'Youtube' , '');
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,239 +0,0 @@
|
||||||
|
|
||||||
-- AllTypes table -----------------------------
|
|
||||||
|
|
||||||
create schema IF NOT EXISTS test_sample;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS test_sample.all_types;
|
|
||||||
|
|
||||||
CREATE TABLE test_sample.ALL_TYPES
|
|
||||||
(
|
|
||||||
-- numeric
|
|
||||||
small_int_ptr smallint,
|
|
||||||
small_int smallint NOT NULL,
|
|
||||||
integer_ptr integer,
|
|
||||||
integer integer NOT NULL,
|
|
||||||
big_int_ptr bigint,
|
|
||||||
big_int bigint NOT NULL,
|
|
||||||
decimal_ptr decimal(10, 2),
|
|
||||||
decimal decimal(10, 2) NOT NULL,
|
|
||||||
numeric_ptr numeric(20, 3),
|
|
||||||
numeric numeric(20,3) NOT NULL,
|
|
||||||
real_ptr real,
|
|
||||||
real real NOT NULL,
|
|
||||||
double_precision_ptr double precision,
|
|
||||||
double_precision double precision NOT NULL,
|
|
||||||
smallserial smallserial NOT NULL,
|
|
||||||
serial serial NOT NULL,
|
|
||||||
bigserial bigserial NOT NULL,
|
|
||||||
|
|
||||||
--monetary
|
|
||||||
-- money_ptr money,
|
|
||||||
-- money money NOT NULL,
|
|
||||||
|
|
||||||
var_char_ptr character varying(100),
|
|
||||||
var_char character varying(200) NOT NULL,
|
|
||||||
char_ptr character(80),
|
|
||||||
char character(80) NOT NULL,
|
|
||||||
text_ptr text,
|
|
||||||
text text NOT NULL,
|
|
||||||
|
|
||||||
--binary
|
|
||||||
bytea_ptr bytea,
|
|
||||||
bytea bytea NOT NULL,
|
|
||||||
|
|
||||||
--datetime
|
|
||||||
timestampz_ptr timestamp with time zone,
|
|
||||||
timestampz timestamp with time zone NOT NULL,
|
|
||||||
timestamp_ptr timestamp without time zone,
|
|
||||||
timestamp timestamp without time zone NOT NULL,
|
|
||||||
date_ptr date,
|
|
||||||
date date NOT NULL,
|
|
||||||
timez_ptr time with time zone,
|
|
||||||
timez time with time zone NOT NULL,
|
|
||||||
time_ptr time without time zone,
|
|
||||||
time time without time zone NOT NULL,
|
|
||||||
interval_ptr interval,
|
|
||||||
interval interval NOT NULL,
|
|
||||||
|
|
||||||
--boolean
|
|
||||||
boolean_ptr boolean,
|
|
||||||
boolean boolean NOT NULL,
|
|
||||||
|
|
||||||
--geometry
|
|
||||||
point_ptr point,
|
|
||||||
|
|
||||||
--bitstrings
|
|
||||||
bit_ptr bit(3),
|
|
||||||
bit bit(3) NOT NULL,
|
|
||||||
bit_varying_ptr bit varying(20),
|
|
||||||
bit_varying bit varying(40) NOT NULL,
|
|
||||||
|
|
||||||
--textsearch
|
|
||||||
tsvector_ptr tsvector,
|
|
||||||
tsvector tsvector NOT NULL,
|
|
||||||
|
|
||||||
--uuid
|
|
||||||
uuid_ptr uuid,
|
|
||||||
uuid uuid NOT NULL,
|
|
||||||
|
|
||||||
--xml
|
|
||||||
xml_ptr xml,
|
|
||||||
xml xml NOT NULL,
|
|
||||||
|
|
||||||
--json
|
|
||||||
json_ptr json,
|
|
||||||
json json NOT NULL,
|
|
||||||
jsonb_ptr jsonb,
|
|
||||||
jsonb jsonb NOT NULL,
|
|
||||||
|
|
||||||
--array
|
|
||||||
integer_array_ptr integer[],
|
|
||||||
integer_array integer[] NOT NULL,
|
|
||||||
text_array_ptr text[],
|
|
||||||
text_array text[] NOT NULL,
|
|
||||||
jsonb_array jsonb[] NOT NULL,
|
|
||||||
text_multi_dim_array_ptr text[][],
|
|
||||||
text_multi_dim_array text[][] NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
INSERT INTO test_sample.ALL_types(
|
|
||||||
small_int_ptr, "small_int", integer_ptr, "integer", big_int_ptr, "big_int", decimal_ptr, "decimal", numeric_ptr, "numeric", real_ptr, "real", double_precision_ptr, double_precision, smallserial, serial, bigserial,
|
|
||||||
-- money_ptr, money,
|
|
||||||
var_char_ptr, var_char, char_ptr, char, text_ptr, text,
|
|
||||||
bytea_ptr, bytea,
|
|
||||||
timestampz_ptr, timestampz, timestamp_ptr, "timestamp", date_ptr, date, timez_ptr, timez, time_ptr, "time", interval_ptr, "interval",
|
|
||||||
boolean_ptr, "boolean",
|
|
||||||
point_ptr,
|
|
||||||
bit_ptr, "bit", bit_varying_ptr, bit_varying,
|
|
||||||
tsvector_ptr, tsvector,
|
|
||||||
uuid_ptr, uuid,
|
|
||||||
xml_ptr, xml,
|
|
||||||
json_ptr, json, jsonb_ptr, jsonb,
|
|
||||||
integer_array_ptr, integer_array, text_array_ptr, text_array, jsonb_array, text_multi_dim_array_ptr, text_multi_dim_array)
|
|
||||||
VALUES (14, 14, 300, 300, 50000, 5000, 1.11, 1.11, 2.22, 2.22, 5.55, 5.55, 11111111.22, 11111111.22, DEFAULT, DEFAULT, DEFAULT,
|
|
||||||
-- 100000, 100000,
|
|
||||||
'ABBA', 'ABBA', 'JOHN', 'JOHN', 'Some text', 'Some text',
|
|
||||||
'bytea', 'bytea',
|
|
||||||
'January 8 04:05:06 1999 PST', 'January 8 04:05:06 1999 PST', '1999-01-08 04:05:06', '1999-01-08 04:05:06', '1999-01-08', '1999-01-08', '04:05:06 -8:00', '04:05:06 -8:00', '04:05:06', '04:05:06', '3 4:05:06', '3 4:05:06',
|
|
||||||
TRUE, FALSE,
|
|
||||||
'(2,3)',
|
|
||||||
B'101', B'101', B'101111', B'101111',
|
|
||||||
to_tsvector('supernovae'), to_tsvector('supernovae'),
|
|
||||||
'A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11', 'A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11',
|
|
||||||
'<Sub>abc</Sub>', '<Sub>abc</Sub>',
|
|
||||||
'{"a": 1, "b": 3}', '{"a": 1, "b": 3}', '{"a": 1, "b": 3}', '{"a": 1, "b": 3}',
|
|
||||||
'{1, 2, 3}', '{1, 2, 3}', '{"breakfast", "consulting"}', '{"breakfast", "consulting"}', ARRAY['{"a": 1, "b": 2}'::jsonb, '{"a":3, "b": 4}'::jsonb], '{{"meeting", "lunch"}, {"training", "presentation"}}', '{{"meeting", "lunch"}, {"training", "presentation"}}')
|
|
||||||
,
|
|
||||||
(NULL, 14, NULL, 300, NULL, 5000, NULL, 1.11, NULL, 2.22, NULL, 5.55, NULL, 11111111.22, DEFAULT, DEFAULT, DEFAULT,
|
|
||||||
-- NULL, 100000,
|
|
||||||
NULL, 'ABBA', NULL, 'JOHN', NULL, 'Some text',
|
|
||||||
NULL, 'bytea',
|
|
||||||
NULL, 'January 8 04:05:06 1999 PST', NULL, '1999-01-08 04:05:06', NULL, '1999-01-08', NULL, '04:05:06 -8:00', NULL, '04:05:06', NULL, '3 4:05:06',
|
|
||||||
NULL, FALSE,
|
|
||||||
NULL,
|
|
||||||
NULL, B'101', NULL, B'101111',
|
|
||||||
NULL, to_tsvector('supernovae'),
|
|
||||||
NULL, 'A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11',
|
|
||||||
NULL, '<Sub>abc</Sub>',
|
|
||||||
NULL, '{"a": 1, "b": 3}', NULL, '{"a": 1, "b": 3}',
|
|
||||||
NULL, '{1, 2, 3}', NULL, '{"breakfast", "consulting"}', ARRAY['{"a": 1, "b": 2}'::jsonb, '{"a":3, "b": 4}'::jsonb], NULL, '{{"meeting", "lunch"}, {"training", "presentation"}}')
|
|
||||||
;
|
|
||||||
|
|
||||||
-- Link table --------------------
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS test_sample.link;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS test_sample.link (
|
|
||||||
id serial PRIMARY KEY,
|
|
||||||
url VARCHAR (255) NOT NULL,
|
|
||||||
name VARCHAR (255) NOT NULL,
|
|
||||||
description VARCHAR (255)
|
|
||||||
);
|
|
||||||
|
|
||||||
INSERT INTO test_sample.link (ID, url, name, description) VALUES
|
|
||||||
(0, 'http://www.youtube.com', 'Youtube' , '');
|
|
||||||
|
|
||||||
|
|
||||||
-- Employee table ---------------
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS test_sample.employee;
|
|
||||||
|
|
||||||
CREATE TABLE test_sample.employee (
|
|
||||||
employee_id INT PRIMARY KEY,
|
|
||||||
first_name VARCHAR (255) NOT NULL,
|
|
||||||
last_name VARCHAR (255) NOT NULL,
|
|
||||||
employment_date timestamp with time zone,
|
|
||||||
manager_id INT,
|
|
||||||
FOREIGN KEY (manager_id)
|
|
||||||
REFERENCES test_sample.employee (employee_id)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
);
|
|
||||||
INSERT INTO test_sample.employee (
|
|
||||||
employee_id,
|
|
||||||
first_name,
|
|
||||||
last_name,
|
|
||||||
employment_date,
|
|
||||||
manager_id
|
|
||||||
)
|
|
||||||
VALUES
|
|
||||||
(1, 'Windy', 'Hays', '1999-01-08 04:05:06.100 +1:00', NULL),
|
|
||||||
(2, 'Ava', 'Christensen', '1999-01-08 04:05:06 +1:00', 1),
|
|
||||||
(3, 'Hassan', 'Conner', '1999-01-08 04:05:06 +1:00', 1),
|
|
||||||
(4, 'Anna', 'Reeves', '1999-01-08 04:05:06 +1:00', 2),
|
|
||||||
(5, 'Sau', 'Norman', '1999-01-08 04:05:06 +1:00', 2),
|
|
||||||
(6, 'Kelsie', 'Hays', '1999-01-08 04:05:06 +1:00', 3),
|
|
||||||
(7, 'Tory', 'Goff', '1999-01-08 04:05:06 +1:00', 3),
|
|
||||||
(8, 'Salley', 'Lester', '1999-01-08 04:05:06 +1:00', 3);
|
|
||||||
|
|
||||||
|
|
||||||
-- Person table ------------------
|
|
||||||
|
|
||||||
DROP TYPE IF EXISTS test_sample.MOOD CASCADE;
|
|
||||||
|
|
||||||
CREATE TYPE test_sample.MOOD AS ENUM ('sad', 'ok', 'happy');
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS test_sample.person;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE test_sample.person(
|
|
||||||
person_id uuid NOT NULL PRIMARY KEY,
|
|
||||||
first_name varchar(100),
|
|
||||||
last_name varchar(100),
|
|
||||||
"Mood" test_sample.mood
|
|
||||||
);
|
|
||||||
|
|
||||||
INSERT INTO test_sample.person(person_id, first_name, last_name, "Mood") VALUES
|
|
||||||
('b68dbff4-a87d-11e9-a7f2-98ded00c39c6', 'Sad', 'John', 'sad'),
|
|
||||||
('b68dbff5-a87d-11e9-a7f2-98ded00c39c7', 'Ok', 'John', 'ok'),
|
|
||||||
('b68dbff6-a87d-11e9-a7f2-98ded00c39c8', 'Ok', 'John', 'ok');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- WEIRD TABLE NAMES --------------
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS test_sample."WEIRD NAMES TABLE";
|
|
||||||
|
|
||||||
CREATE TABLE test_sample."WEIRD NAMES TABLE"(
|
|
||||||
"weird_column_name1" varchar(100) NOT NULL,
|
|
||||||
"Weird_Column_Name2" varchar(100) NOT NULL,
|
|
||||||
"wEiRd_cOluMn_nAmE3" varchar(100) NOT NULL,
|
|
||||||
"WeIrd_CoLuMN_Name4" varchar(100) NOT NULL,
|
|
||||||
"WEIRD_COLUMN_NAME5" varchar(100) NOT NULL,
|
|
||||||
|
|
||||||
"WeirdColumnName6" varchar(100) NOT NULL,
|
|
||||||
"weirdColumnName7" varchar(100) NOT NULL,
|
|
||||||
"weirdcolumnname8" varchar(100),
|
|
||||||
|
|
||||||
"weird col name9" varchar(100) NOT NULL,
|
|
||||||
"wEiRd cOlu nAmE10" varchar(100) NOT NULL,
|
|
||||||
"WEIRD COLU NAME11" varchar(100) NOT NULL,
|
|
||||||
"Weird Colu Name12" varchar(100) NOT NULL,
|
|
||||||
|
|
||||||
"weird-col-name13" varchar(100) NOT NULL,
|
|
||||||
"wEiRd-cOlu-nAmE14" varchar(100) NOT NULL,
|
|
||||||
"WEIRD-COLU-NAME15" varchar(100) NOT NULL,
|
|
||||||
"Weird-Colu-Name16" varchar(100) NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
INSERT INTO test_sample."WEIRD NAMES TABLE"
|
|
||||||
VALUES ('Doe', 'Doe', 'Doe', 'Doe','Doe', 'Doe', 'Doe', 'Doe','Doe', 'Doe', 'Doe', 'Doe','Doe', 'Doe', 'Doe', 'Doe');
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testSuite string
|
var testSuite string
|
||||||
|
|
@ -24,12 +25,14 @@ func init() {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
testSuite = strings.ToLower(testSuite)
|
||||||
|
|
||||||
if testSuite == "postgres" {
|
if testSuite == "postgres" {
|
||||||
initPostgresDB()
|
initPostgresDB()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if testSuite == "mysql" {
|
if testSuite == "mysql" || testSuite == "mariadb" {
|
||||||
initMySQLDB()
|
initMySQLDB()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +50,7 @@ func initMySQLDB() {
|
||||||
|
|
||||||
for _, dbName := range mySQLDBs {
|
for _, dbName := range mySQLDBs {
|
||||||
cmdLine := fmt.Sprintf("mysql -h 127.0.0.1 -u %s -p%s %s < %s",
|
cmdLine := fmt.Sprintf("mysql -h 127.0.0.1 -u %s -p%s %s < %s",
|
||||||
dbconfig.MySQLUser, dbconfig.MySQLPassword, dbName, "./init/data/mysql/"+dbName+".sql")
|
dbconfig.MySQLUser, dbconfig.MySQLPassword, dbName, "./testdata/init/mysql/"+dbName+".sql")
|
||||||
|
|
||||||
fmt.Println(cmdLine)
|
fmt.Println(cmdLine)
|
||||||
|
|
||||||
|
|
@ -71,7 +74,6 @@ func initMySQLDB() {
|
||||||
|
|
||||||
panicOnError(err)
|
panicOnError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func initPostgresDB() {
|
func initPostgresDB() {
|
||||||
|
|
@ -93,7 +95,7 @@ func initPostgresDB() {
|
||||||
|
|
||||||
for _, schemaName := range schemaNames {
|
for _, schemaName := range schemaNames {
|
||||||
|
|
||||||
execFile(db, "./init/data/postgres/"+schemaName+".sql")
|
execFile(db, "./testdata/init/postgres/"+schemaName+".sql")
|
||||||
|
|
||||||
err = postgres.Generate("./.gentestdata", postgres.DBConnection{
|
err = postgres.Generate("./.gentestdata", postgres.DBConnection{
|
||||||
Host: dbconfig.Host,
|
Host: dbconfig.Host,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"github.com/go-jet/jet/internal/testutils"
|
"github.com/go-jet/jet/internal/testutils"
|
||||||
"github.com/go-jet/jet/tests/.gentestdata/mysql/test_sample/model"
|
"github.com/go-jet/jet/tests/.gentestdata/mysql/test_sample/model"
|
||||||
. "github.com/go-jet/jet/tests/.gentestdata/mysql/test_sample/table"
|
. "github.com/go-jet/jet/tests/.gentestdata/mysql/test_sample/table"
|
||||||
"github.com/go-jet/jet/tests/testdata/common"
|
"github.com/go-jet/jet/tests/testdata/results/common"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -26,6 +26,12 @@ func TestAllTypes(t *testing.T) {
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, len(dest), 2)
|
||||||
|
|
||||||
|
if sourceIsMariaDB() { // MariaDB saves current timestamp in a case of NULL value insert
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
//testutils.PrintJson(dest)
|
//testutils.PrintJson(dest)
|
||||||
testutils.AssertJSON(t, dest, allTypesJson)
|
testutils.AssertJSON(t, dest, allTypesJson)
|
||||||
}
|
}
|
||||||
|
|
@ -187,7 +193,7 @@ FROM test_sample.all_types;
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
testutils.AssertJSONFile(t, dest, "./testdata/common/bool_operators.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/common/bool_operators.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatOperators(t *testing.T) {
|
func TestFloatOperators(t *testing.T) {
|
||||||
|
|
@ -284,7 +290,7 @@ LIMIT ?;
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
testutils.AssertJSONFile(t, dest, "./testdata/common/float_operators.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/common/float_operators.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIntegerOperators(t *testing.T) {
|
func TestIntegerOperators(t *testing.T) {
|
||||||
|
|
@ -423,11 +429,12 @@ LIMIT ?;
|
||||||
|
|
||||||
//testutils.PrintJson(dest)
|
//testutils.PrintJson(dest)
|
||||||
|
|
||||||
testutils.AssertJSONFile(t, dest, "./testdata/common/int_operators.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/common/int_operators.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringOperators(t *testing.T) {
|
func TestStringOperators(t *testing.T) {
|
||||||
query := AllTypes.SELECT(
|
|
||||||
|
var projectionList = []Projection{
|
||||||
AllTypes.Text.EQ(AllTypes.Char),
|
AllTypes.Text.EQ(AllTypes.Char),
|
||||||
AllTypes.Text.EQ(String("Text")),
|
AllTypes.Text.EQ(String("Text")),
|
||||||
AllTypes.Text.NOT_EQ(AllTypes.VarCharPtr),
|
AllTypes.Text.NOT_EQ(AllTypes.VarCharPtr),
|
||||||
|
|
@ -445,8 +452,11 @@ func TestStringOperators(t *testing.T) {
|
||||||
AllTypes.Text.LIKE(String("abc")),
|
AllTypes.Text.LIKE(String("abc")),
|
||||||
AllTypes.Text.NOT_LIKE(String("_b_")),
|
AllTypes.Text.NOT_LIKE(String("_b_")),
|
||||||
AllTypes.Text.REGEXP_LIKE(String("aba")),
|
AllTypes.Text.REGEXP_LIKE(String("aba")),
|
||||||
AllTypes.Text.REGEXP_LIKE(String("aba"), "c"),
|
AllTypes.Text.REGEXP_LIKE(String("aba"), false),
|
||||||
String("ABA").REGEXP_LIKE(String("aba"), "i"),
|
String("ABA").REGEXP_LIKE(String("aba"), true),
|
||||||
|
AllTypes.Text.NOT_REGEXP_LIKE(String("aba")),
|
||||||
|
AllTypes.Text.NOT_REGEXP_LIKE(String("aba"), false),
|
||||||
|
String("ABA").NOT_REGEXP_LIKE(String("aba"), true),
|
||||||
|
|
||||||
BIT_LENGTH(AllTypes.Text),
|
BIT_LENGTH(AllTypes.Text),
|
||||||
CHAR_LENGTH(AllTypes.Char),
|
CHAR_LENGTH(AllTypes.Char),
|
||||||
|
|
@ -469,17 +479,24 @@ func TestStringOperators(t *testing.T) {
|
||||||
REVERSE(AllTypes.VarCharPtr),
|
REVERSE(AllTypes.VarCharPtr),
|
||||||
SUBSTR(AllTypes.CharPtr, Int(3)),
|
SUBSTR(AllTypes.CharPtr, Int(3)),
|
||||||
SUBSTR(AllTypes.CharPtr, Int(3), Int(2)),
|
SUBSTR(AllTypes.CharPtr, Int(3), Int(2)),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !sourceIsMariaDB() {
|
||||||
|
projectionList = append(projectionList, []Projection{
|
||||||
REGEXP_LIKE(String("ABA"), String("aba")),
|
REGEXP_LIKE(String("ABA"), String("aba")),
|
||||||
REGEXP_LIKE(String("ABA"), String("aba"), "i"),
|
REGEXP_LIKE(String("ABA"), String("aba"), "i"),
|
||||||
REGEXP_LIKE(AllTypes.Text, String("aba"), "i"),
|
REGEXP_LIKE(AllTypes.Text, String("aba"), "i"),
|
||||||
)
|
}...)
|
||||||
|
}
|
||||||
//_, args, _ := query.Sql()
|
//_, args, _ := query.Sql()
|
||||||
|
|
||||||
//fmt.Println(query.Sql())
|
//fmt.Println(query.Sql())
|
||||||
//fmt.Println(args[15])
|
//fmt.Println(args[15])
|
||||||
|
|
||||||
// fmt.Println(query.Sql())
|
query := SELECT(projectionList[0], projectionList[1:]...).
|
||||||
|
FROM(AllTypes)
|
||||||
|
|
||||||
|
fmt.Println(query.DebugSql())
|
||||||
|
|
||||||
err := query.Query(db, &struct{}{})
|
err := query.Query(db, &struct{}{})
|
||||||
|
|
||||||
|
|
@ -756,7 +773,7 @@ func TestTimeLiterals(t *testing.T) {
|
||||||
TimestampT(timeT).AS("timestampT"),
|
TimestampT(timeT).AS("timestampT"),
|
||||||
).FROM(AllTypes).LIMIT(1)
|
).FROM(AllTypes).LIMIT(1)
|
||||||
|
|
||||||
fmt.Println(query.DebugSql())
|
//fmt.Println(query.DebugSql())
|
||||||
|
|
||||||
testutils.AssertStatementSql(t, query, `
|
testutils.AssertStatementSql(t, query, `
|
||||||
SELECT CAST(? AS DATE) AS "date",
|
SELECT CAST(? AS DATE) AS "date",
|
||||||
|
|
@ -785,6 +802,19 @@ LIMIT ?;
|
||||||
|
|
||||||
//testutils.PrintJson(dest)
|
//testutils.PrintJson(dest)
|
||||||
|
|
||||||
|
if sourceIsMariaDB() {
|
||||||
|
testutils.AssertJSON(t, dest, `
|
||||||
|
{
|
||||||
|
"Date": "2009-11-17T00:00:00Z",
|
||||||
|
"DateT": "2009-11-17T00:00:00Z",
|
||||||
|
"Time": "0000-01-01T20:34:58Z",
|
||||||
|
"TimeT": "0000-01-01T19:34:58Z",
|
||||||
|
"DateTime": "2009-11-17T19:34:58Z",
|
||||||
|
"Timestamp": "2019-08-06T10:10:30Z",
|
||||||
|
"TimestampT": "2009-11-17T19:34:58Z"
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
} else {
|
||||||
testutils.AssertJSON(t, dest, `
|
testutils.AssertJSON(t, dest, `
|
||||||
{
|
{
|
||||||
"Date": "2009-11-17T00:00:00Z",
|
"Date": "2009-11-17T00:00:00Z",
|
||||||
|
|
@ -796,6 +826,8 @@ LIMIT ?;
|
||||||
"TimestampT": "2009-11-17T19:34:58.351387Z"
|
"TimestampT": "2009-11-17T19:34:58.351387Z"
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var allTypesJson = `
|
var allTypesJson = `
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ func assertGeneratedFiles(t *testing.T) {
|
||||||
enumFiles, err := ioutil.ReadDir(genTestDir3 + "/dvds/enum")
|
enumFiles, err := ioutil.ReadDir(genTestDir3 + "/dvds/enum")
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
assertFileNameEqual(t, enumFiles, "film_list_rating.go", "film_rating.go", "nicer_but_slower_film_list_rating.go")
|
assertFileNameEqual(t, enumFiles, "film_rating.go")
|
||||||
assertFileContent(t, genTestDir3+"/dvds/enum/film_rating.go", "\npackage enum", mpaaRatingEnumFile)
|
assertFileContent(t, genTestDir3+"/dvds/enum/film_rating.go", "\npackage enum", mpaaRatingEnumFile)
|
||||||
|
|
||||||
// Model files
|
// Model files
|
||||||
|
|
@ -82,7 +82,7 @@ func assertGeneratedFiles(t *testing.T) {
|
||||||
|
|
||||||
assertFileNameEqual(t, modelFiles, "actor.go", "address.go", "category.go", "city.go", "country.go",
|
assertFileNameEqual(t, modelFiles, "actor.go", "address.go", "category.go", "city.go", "country.go",
|
||||||
"customer.go", "film.go", "film_actor.go", "film_category.go", "inventory.go", "language.go",
|
"customer.go", "film.go", "film_actor.go", "film_category.go", "inventory.go", "language.go",
|
||||||
"payment.go", "rental.go", "staff.go", "store.go", "film_list_rating.go", "film_rating.go", "nicer_but_slower_film_list_rating.go")
|
"payment.go", "rental.go", "staff.go", "store.go", "film_rating.go")
|
||||||
|
|
||||||
assertFileContent(t, genTestDir3+"/dvds/model/actor.go", "\npackage model", actorModelFile)
|
assertFileContent(t, genTestDir3+"/dvds/model/actor.go", "\npackage model", actorModelFile)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package mysql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"flag"
|
||||||
"github.com/go-jet/jet/tests/dbconfig"
|
"github.com/go-jet/jet/tests/dbconfig"
|
||||||
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
|
@ -13,6 +14,19 @@ import (
|
||||||
|
|
||||||
var db *sql.DB
|
var db *sql.DB
|
||||||
|
|
||||||
|
var source string
|
||||||
|
|
||||||
|
const MariaDB = "MariaDB"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.StringVar(&source, "source", "", "MySQL or MariaDB")
|
||||||
|
flag.Parse()
|
||||||
|
}
|
||||||
|
|
||||||
|
func sourceIsMariaDB() bool {
|
||||||
|
return source == MariaDB
|
||||||
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
defer profile.Start().Stop()
|
defer profile.Start().Stop()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,14 @@ ORDER BY actor.actor_id;
|
||||||
|
|
||||||
//testutils.PrintJson(dest)
|
//testutils.PrintJson(dest)
|
||||||
//testutils.SaveJsonFile(dest, "mysql/testdata/all_actors.json")
|
//testutils.SaveJsonFile(dest, "mysql/testdata/all_actors.json")
|
||||||
testutils.AssertJSONFile(t, dest, "mysql/testdata/all_actors.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/mysql/all_actors.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelectGroupByHaving(t *testing.T) {
|
func TestSelectGroupByHaving(t *testing.T) {
|
||||||
|
if sourceIsMariaDB() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
expectedSQL := `
|
expectedSQL := `
|
||||||
SELECT customer.customer_id AS "customer.customer_id",
|
SELECT customer.customer_id AS "customer.customer_id",
|
||||||
customer.store_id AS "customer.store_id",
|
customer.store_id AS "customer.store_id",
|
||||||
|
|
@ -134,7 +138,7 @@ ORDER BY payment.customer_id, SUM(payment.amount) ASC;
|
||||||
assert.Equal(t, len(dest), 174)
|
assert.Equal(t, len(dest), 174)
|
||||||
|
|
||||||
//testutils.SaveJsonFile(dest, "mysql/testdata/customer_payment_sum.json")
|
//testutils.SaveJsonFile(dest, "mysql/testdata/customer_payment_sum.json")
|
||||||
testutils.AssertJSONFile(t, dest, "mysql/testdata/customer_payment_sum.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/mysql/customer_payment_sum.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSubQuery(t *testing.T) {
|
func TestSubQuery(t *testing.T) {
|
||||||
|
|
@ -170,10 +174,14 @@ func TestSubQuery(t *testing.T) {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
//testutils.SaveJsonFile(dest, "mysql/testdata/r_rating_films.json")
|
//testutils.SaveJsonFile(dest, "mysql/testdata/r_rating_films.json")
|
||||||
testutils.AssertJSONFile(t, dest, "mysql/testdata/r_rating_films.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/mysql/r_rating_films.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelectAndUnionInProjection(t *testing.T) {
|
func TestSelectAndUnionInProjection(t *testing.T) {
|
||||||
|
if sourceIsMariaDB() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
expectedSQL := `
|
expectedSQL := `
|
||||||
SELECT payment.payment_id AS "payment.payment_id",
|
SELECT payment.payment_id AS "payment.payment_id",
|
||||||
(
|
(
|
||||||
|
|
@ -181,7 +189,6 @@ SELECT payment.payment_id AS "payment.payment_id",
|
||||||
FROM dvds.customer
|
FROM dvds.customer
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
),
|
),
|
||||||
(
|
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
SELECT payment.payment_id AS "payment.payment_id"
|
SELECT payment.payment_id AS "payment.payment_id"
|
||||||
|
|
@ -196,7 +203,6 @@ SELECT payment.payment_id AS "payment.payment_id",
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
OFFSET ?
|
OFFSET ?
|
||||||
)
|
)
|
||||||
)
|
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
)
|
)
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
|
|
@ -223,19 +229,17 @@ LIMIT ?;
|
||||||
func TestSelectUNION(t *testing.T) {
|
func TestSelectUNION(t *testing.T) {
|
||||||
expectedSQL := `
|
expectedSQL := `
|
||||||
(
|
(
|
||||||
(
|
|
||||||
SELECT payment.payment_id AS "payment.payment_id"
|
SELECT payment.payment_id AS "payment.payment_id"
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
OFFSET ?
|
OFFSET ?
|
||||||
)
|
)
|
||||||
UNION
|
UNION
|
||||||
(
|
(
|
||||||
SELECT payment.payment_id AS "payment.payment_id"
|
SELECT payment.payment_id AS "payment.payment_id"
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
OFFSET ?
|
OFFSET ?
|
||||||
)
|
|
||||||
)
|
)
|
||||||
LIMIT ?;
|
LIMIT ?;
|
||||||
`
|
`
|
||||||
|
|
@ -260,19 +264,17 @@ LIMIT ?;
|
||||||
func TestSelectUNION_ALL(t *testing.T) {
|
func TestSelectUNION_ALL(t *testing.T) {
|
||||||
expectedSQL := `
|
expectedSQL := `
|
||||||
(
|
(
|
||||||
(
|
|
||||||
SELECT payment.payment_id AS "payment.payment_id"
|
SELECT payment.payment_id AS "payment.payment_id"
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
OFFSET ?
|
OFFSET ?
|
||||||
)
|
)
|
||||||
UNION ALL
|
UNION ALL
|
||||||
(
|
(
|
||||||
SELECT payment.payment_id AS "payment.payment_id"
|
SELECT payment.payment_id AS "payment.payment_id"
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
OFFSET ?
|
OFFSET ?
|
||||||
)
|
|
||||||
)
|
)
|
||||||
ORDER BY "payment.payment_id"
|
ORDER BY "payment.payment_id"
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
|
|
@ -403,11 +405,16 @@ LIMIT ?;
|
||||||
|
|
||||||
//testutils.SaveJsonFile(dest, "./mysql/testdata/lang_film_actor_inventory_rental.json")
|
//testutils.SaveJsonFile(dest, "./mysql/testdata/lang_film_actor_inventory_rental.json")
|
||||||
|
|
||||||
testutils.AssertJSONFile(t, dest, "./mysql/testdata/lang_film_actor_inventory_rental.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/mysql/lang_film_actor_inventory_rental.json")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRowLockTestData() map[SelectLock]string {
|
func getRowLockTestData() map[SelectLock]string {
|
||||||
|
if sourceIsMariaDB() {
|
||||||
|
return map[SelectLock]string{
|
||||||
|
UPDATE(): "UPDATE",
|
||||||
|
}
|
||||||
|
}
|
||||||
return map[SelectLock]string{
|
return map[SelectLock]string{
|
||||||
UPDATE(): "UPDATE",
|
UPDATE(): "UPDATE",
|
||||||
SHARE(): "SHARE",
|
SHARE(): "SHARE",
|
||||||
|
|
@ -455,6 +462,10 @@ FOR`
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sourceIsMariaDB() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for lockType, lockTypeStr := range getRowLockTestData() {
|
for lockType, lockTypeStr := range getRowLockTestData() {
|
||||||
query.FOR(lockType.SKIP_LOCKED())
|
query.FOR(lockType.SKIP_LOCKED())
|
||||||
|
|
||||||
|
|
@ -496,3 +507,23 @@ SELECT true,
|
||||||
err := query.Query(db, &struct{}{})
|
err := query.Query(db, &struct{}{})
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLockInShareMode(t *testing.T) {
|
||||||
|
expectedSQL := `
|
||||||
|
SELECT *
|
||||||
|
FROM dvds.address
|
||||||
|
LIMIT 3
|
||||||
|
OFFSET 1
|
||||||
|
LOCK IN SHARE MODE;
|
||||||
|
`
|
||||||
|
query := Address.
|
||||||
|
SELECT(STAR).
|
||||||
|
LIMIT(3).
|
||||||
|
OFFSET(1).
|
||||||
|
LOCK_IN_SHARE_MODE()
|
||||||
|
|
||||||
|
testutils.AssertDebugStatementSql(t, query, expectedSQL)
|
||||||
|
|
||||||
|
err := query.Query(db, &struct{}{})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
}
|
||||||
|
|
|
||||||
1202
tests/mysql/testdata/all_actors.json
vendored
1202
tests/mysql/testdata/all_actors.json
vendored
File diff suppressed because it is too large
Load diff
3134
tests/mysql/testdata/customer_payment_sum.json
vendored
3134
tests/mysql/testdata/customer_payment_sum.json
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
9469
tests/mysql/testdata/r_rating_films.json
vendored
9469
tests/mysql/testdata/r_rating_films.json
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -139,6 +139,35 @@ WHERE link.id = 201;
|
||||||
testutils.AssertExec(t, stmt, db)
|
testutils.AssertExec(t, stmt, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdateWithModelDataAndMutableColumns(t *testing.T) {
|
||||||
|
|
||||||
|
setupLinkTableForUpdateTest(t)
|
||||||
|
|
||||||
|
link := model.Link{
|
||||||
|
ID: 201,
|
||||||
|
URL: "http://www.duckduckgo.com",
|
||||||
|
Name: "DuckDuckGo",
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt := Link.
|
||||||
|
UPDATE(Link.MutableColumns).
|
||||||
|
MODEL(link).
|
||||||
|
WHERE(Link.ID.EQ(Int(int64(link.ID))))
|
||||||
|
|
||||||
|
var expectedSQL = `
|
||||||
|
UPDATE test_sample.link
|
||||||
|
SET url = 'http://www.duckduckgo.com',
|
||||||
|
name = 'DuckDuckGo',
|
||||||
|
description = NULL
|
||||||
|
WHERE link.id = 201;
|
||||||
|
`
|
||||||
|
fmt.Println(stmt.DebugSql())
|
||||||
|
|
||||||
|
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, "http://www.duckduckgo.com", "DuckDuckGo", nil, int64(201))
|
||||||
|
|
||||||
|
testutils.AssertExec(t, stmt, db)
|
||||||
|
}
|
||||||
|
|
||||||
func TestUpdateWithInvalidModelData(t *testing.T) {
|
func TestUpdateWithInvalidModelData(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
r := recover()
|
r := recover()
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
||||||
. "github.com/go-jet/jet/postgres"
|
. "github.com/go-jet/jet/postgres"
|
||||||
"github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/model"
|
"github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/model"
|
||||||
. "github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/table"
|
. "github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/table"
|
||||||
"github.com/go-jet/jet/tests/testdata/common"
|
"github.com/go-jet/jet/tests/testdata/results/common"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -179,9 +179,10 @@ func TestStringOperators(t *testing.T) {
|
||||||
AllTypes.Text.CONCAT(Int(11)),
|
AllTypes.Text.CONCAT(Int(11)),
|
||||||
AllTypes.Text.LIKE(String("abc")),
|
AllTypes.Text.LIKE(String("abc")),
|
||||||
AllTypes.Text.NOT_LIKE(String("_b_")),
|
AllTypes.Text.NOT_LIKE(String("_b_")),
|
||||||
AllTypes.Text.REGEXP_LIKE(String("aba")),
|
AllTypes.Text.REGEXP_LIKE(String("^t")),
|
||||||
AllTypes.Text.REGEXP_LIKE(String("aba"), "c"),
|
AllTypes.Text.REGEXP_LIKE(String("^t"), true),
|
||||||
AllTypes.Text.REGEXP_LIKE(String("aba"), "i"),
|
AllTypes.Text.NOT_REGEXP_LIKE(String("^t")),
|
||||||
|
AllTypes.Text.NOT_REGEXP_LIKE(String("^t"), true),
|
||||||
|
|
||||||
BIT_LENGTH(String("length")),
|
BIT_LENGTH(String("length")),
|
||||||
CHAR_LENGTH(AllTypes.Char),
|
CHAR_LENGTH(AllTypes.Char),
|
||||||
|
|
@ -232,7 +233,7 @@ func TestStringOperators(t *testing.T) {
|
||||||
TO_HEX(AllTypes.IntegerPtr),
|
TO_HEX(AllTypes.IntegerPtr),
|
||||||
)
|
)
|
||||||
|
|
||||||
//fmt.Println(query.Sql())
|
//fmt.Println(query.DebugSql())
|
||||||
|
|
||||||
err := query.Query(db, &struct{}{})
|
err := query.Query(db, &struct{}{})
|
||||||
|
|
||||||
|
|
@ -307,7 +308,7 @@ LIMIT $5;
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
testutils.AssertJSONFile(t, dest, "./testdata/common/bool_operators.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/common/bool_operators.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatOperators(t *testing.T) {
|
func TestFloatOperators(t *testing.T) {
|
||||||
|
|
@ -405,7 +406,7 @@ LIMIT $35;
|
||||||
|
|
||||||
//testutils.PrintJson(dest)
|
//testutils.PrintJson(dest)
|
||||||
|
|
||||||
testutils.AssertJSONFile(t, dest, "./testdata/common/float_operators.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/common/float_operators.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIntegerOperators(t *testing.T) {
|
func TestIntegerOperators(t *testing.T) {
|
||||||
|
|
@ -467,7 +468,7 @@ func TestIntegerOperators(t *testing.T) {
|
||||||
AllTypes.SmallInt.BIT_XOR(Int(11)).AS("bit xor 2"),
|
AllTypes.SmallInt.BIT_XOR(Int(11)).AS("bit xor 2"),
|
||||||
|
|
||||||
BIT_NOT(Int(-1).MUL(AllTypes.SmallInt)).AS("bit_not_1"),
|
BIT_NOT(Int(-1).MUL(AllTypes.SmallInt)).AS("bit_not_1"),
|
||||||
BIT_NOT(Int(-11, true)).AS("bit_not_2"),
|
BIT_NOT(Int(-11)).AS("bit_not_2"),
|
||||||
|
|
||||||
AllTypes.SmallInt.BIT_SHIFT_LEFT(AllTypes.SmallInt.DIV(Int(2))).AS("bit shift left 1"),
|
AllTypes.SmallInt.BIT_SHIFT_LEFT(AllTypes.SmallInt.DIV(Int(2))).AS("bit shift left 1"),
|
||||||
AllTypes.SmallInt.BIT_SHIFT_LEFT(Int(4)).AS("bit shift left 2"),
|
AllTypes.SmallInt.BIT_SHIFT_LEFT(Int(4)).AS("bit shift left 2"),
|
||||||
|
|
@ -544,7 +545,7 @@ LIMIT $23;
|
||||||
|
|
||||||
//testutils.SaveJsonFile("./testdata/common/int_operators.json", dest)
|
//testutils.SaveJsonFile("./testdata/common/int_operators.json", dest)
|
||||||
//testutils.PrintJson(dest)
|
//testutils.PrintJson(dest)
|
||||||
testutils.AssertJSONFile(t, dest, "./testdata/common/int_operators.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/common/int_operators.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpression(t *testing.T) {
|
func TestTimeExpression(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ func TestJoinEverything(t *testing.T) {
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, len(dest), 275)
|
assert.Equal(t, len(dest), 275)
|
||||||
testutils.AssertJSONFile(t, dest, "./postgres/testdata/joined_everything.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/postgres/joined_everything.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelfJoin(t *testing.T) {
|
func TestSelfJoin(t *testing.T) {
|
||||||
|
|
@ -215,21 +215,19 @@ func TestUnionForQuotedNames(t *testing.T) {
|
||||||
//fmt.Println(stmt.DebugSql())
|
//fmt.Println(stmt.DebugSql())
|
||||||
testutils.AssertDebugStatementSql(t, stmt, `
|
testutils.AssertDebugStatementSql(t, stmt, `
|
||||||
(
|
(
|
||||||
(
|
|
||||||
SELECT "Album"."AlbumId" AS "Album.AlbumId",
|
SELECT "Album"."AlbumId" AS "Album.AlbumId",
|
||||||
"Album"."Title" AS "Album.Title",
|
"Album"."Title" AS "Album.Title",
|
||||||
"Album"."ArtistId" AS "Album.ArtistId"
|
"Album"."ArtistId" AS "Album.ArtistId"
|
||||||
FROM chinook."Album"
|
FROM chinook."Album"
|
||||||
WHERE "Album"."AlbumId" = 1
|
WHERE "Album"."AlbumId" = 1
|
||||||
)
|
)
|
||||||
UNION ALL
|
UNION ALL
|
||||||
(
|
(
|
||||||
SELECT "Album"."AlbumId" AS "Album.AlbumId",
|
SELECT "Album"."AlbumId" AS "Album.AlbumId",
|
||||||
"Album"."Title" AS "Album.Title",
|
"Album"."Title" AS "Album.Title",
|
||||||
"Album"."ArtistId" AS "Album.ArtistId"
|
"Album"."ArtistId" AS "Album.ArtistId"
|
||||||
FROM chinook."Album"
|
FROM chinook."Album"
|
||||||
WHERE "Album"."AlbumId" = 2
|
WHERE "Album"."AlbumId" = 2
|
||||||
)
|
|
||||||
)
|
)
|
||||||
ORDER BY "Album.AlbumId";
|
ORDER BY "Album.AlbumId";
|
||||||
`, int64(1), int64(2))
|
`, int64(1), int64(2))
|
||||||
|
|
|
||||||
|
|
@ -62,5 +62,5 @@ func TestNorthwindJoinEverything(t *testing.T) {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
//jsonSave("./testdata/northwind-all.json", dest)
|
//jsonSave("./testdata/northwind-all.json", dest)
|
||||||
testutils.AssertJSONFile(t, dest, "./postgres/testdata/northwind-all.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/postgres/northwind-all.json")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,6 @@ SELECT payment.payment_id AS "payment.payment_id",
|
||||||
FROM dvds.customer
|
FROM dvds.customer
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
),
|
),
|
||||||
(
|
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
SELECT payment.payment_id AS "payment.payment_id"
|
SELECT payment.payment_id AS "payment.payment_id"
|
||||||
|
|
@ -141,7 +140,6 @@ SELECT payment.payment_id AS "payment.payment_id",
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
OFFSET 2
|
OFFSET 2
|
||||||
)
|
)
|
||||||
)
|
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
)
|
)
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
|
|
@ -1063,7 +1061,7 @@ ORDER BY customer.customer_id, SUM(payment.amount) ASC;
|
||||||
assert.Equal(t, len(dest), 104)
|
assert.Equal(t, len(dest), 104)
|
||||||
|
|
||||||
//testutils.SaveJsonFile(dest, "postgres/testdata/customer_payment_sum.json")
|
//testutils.SaveJsonFile(dest, "postgres/testdata/customer_payment_sum.json")
|
||||||
testutils.AssertJSONFile(t, dest, "postgres/testdata/customer_payment_sum.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/postgres/customer_payment_sum.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelectGroupBy2(t *testing.T) {
|
func TestSelectGroupBy2(t *testing.T) {
|
||||||
|
|
@ -1217,19 +1215,17 @@ ORDER BY payment.payment_date ASC;
|
||||||
func TestUnion(t *testing.T) {
|
func TestUnion(t *testing.T) {
|
||||||
expectedQuery := `
|
expectedQuery := `
|
||||||
(
|
(
|
||||||
(
|
|
||||||
SELECT payment.payment_id AS "payment.payment_id",
|
SELECT payment.payment_id AS "payment.payment_id",
|
||||||
payment.amount AS "payment.amount"
|
payment.amount AS "payment.amount"
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
WHERE payment.amount <= 100
|
WHERE payment.amount <= 100
|
||||||
)
|
)
|
||||||
UNION ALL
|
UNION ALL
|
||||||
(
|
(
|
||||||
SELECT payment.payment_id AS "payment.payment_id",
|
SELECT payment.payment_id AS "payment.payment_id",
|
||||||
payment.amount AS "payment.amount"
|
payment.amount AS "payment.amount"
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
WHERE payment.amount >= 200
|
WHERE payment.amount >= 200
|
||||||
)
|
|
||||||
)
|
)
|
||||||
ORDER BY "payment.payment_id" ASC, "payment.amount" DESC
|
ORDER BY "payment.payment_id" ASC, "payment.amount" DESC
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
|
|
@ -1510,7 +1506,7 @@ ORDER BY actor.actor_id ASC, film.film_id ASC;
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
//jsonSave("./testdata/quick-start-dest.json", dest)
|
//jsonSave("./testdata/quick-start-dest.json", dest)
|
||||||
testutils.AssertJSONFile(t, dest, "./postgres/testdata/quick-start-dest.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/postgres/quick-start-dest.json")
|
||||||
|
|
||||||
var dest2 []struct {
|
var dest2 []struct {
|
||||||
model.Category
|
model.Category
|
||||||
|
|
@ -1523,7 +1519,7 @@ ORDER BY actor.actor_id ASC, film.film_id ASC;
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
//jsonSave("./testdata/quick-start-dest2.json", dest2)
|
//jsonSave("./testdata/quick-start-dest2.json", dest2)
|
||||||
testutils.AssertJSONFile(t, dest2, "./postgres/testdata/quick-start-dest2.json")
|
testutils.AssertJSONFile(t, dest2, "./testdata/results/postgres/quick-start-dest2.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQuickStartWithSubQueries(t *testing.T) {
|
func TestQuickStartWithSubQueries(t *testing.T) {
|
||||||
|
|
@ -1575,7 +1571,7 @@ func TestQuickStartWithSubQueries(t *testing.T) {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
//jsonSave("./testdata/quick-start-dest.json", dest)
|
//jsonSave("./testdata/quick-start-dest.json", dest)
|
||||||
testutils.AssertJSONFile(t, dest, "./postgres/testdata/quick-start-dest.json")
|
testutils.AssertJSONFile(t, dest, "./testdata/results/postgres/quick-start-dest.json")
|
||||||
|
|
||||||
var dest2 []struct {
|
var dest2 []struct {
|
||||||
model.Category
|
model.Category
|
||||||
|
|
@ -1588,7 +1584,7 @@ func TestQuickStartWithSubQueries(t *testing.T) {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
//jsonSave("./testdata/quick-start-dest2.json", dest2)
|
//jsonSave("./testdata/quick-start-dest2.json", dest2)
|
||||||
testutils.AssertJSONFile(t, dest2, "./postgres/testdata/quick-start-dest2.json")
|
testutils.AssertJSONFile(t, dest2, "./testdata/results/postgres/quick-start-dest2.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExpressionWrappers(t *testing.T) {
|
func TestExpressionWrappers(t *testing.T) {
|
||||||
|
|
|
||||||
1978
tests/postgres/testdata/customer_payment_sum.json
vendored
1978
tests/postgres/testdata/customer_payment_sum.json
vendored
File diff suppressed because it is too large
Load diff
252320
tests/postgres/testdata/joined_everything.json
vendored
252320
tests/postgres/testdata/joined_everything.json
vendored
File diff suppressed because it is too large
Load diff
135339
tests/postgres/testdata/northwind-all.json
vendored
135339
tests/postgres/testdata/northwind-all.json
vendored
File diff suppressed because it is too large
Load diff
6067
tests/postgres/testdata/quick-start-dest.json
vendored
6067
tests/postgres/testdata/quick-start-dest.json
vendored
File diff suppressed because it is too large
Load diff
1769
tests/postgres/testdata/quick-start-dest2.json
vendored
1769
tests/postgres/testdata/quick-start-dest2.json
vendored
File diff suppressed because it is too large
Load diff
1
tests/testdata
Submodule
1
tests/testdata
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 7f3f3cc26ce34324f3699d6b422376671b827490
|
||||||
38
tests/testdata/common/bool_operators.json
vendored
38
tests/testdata/common/bool_operators.json
vendored
|
|
@ -1,38 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"Eq1": false,
|
|
||||||
"Eq2": false,
|
|
||||||
"NEq1": true,
|
|
||||||
"NEq2": false,
|
|
||||||
"Distinct1": true,
|
|
||||||
"Distinct2": true,
|
|
||||||
"NotDistinct1": false,
|
|
||||||
"NotDistinct2": false,
|
|
||||||
"IsTrue": false,
|
|
||||||
"IsNotTrue": true,
|
|
||||||
"IsFalse": true,
|
|
||||||
"IsNotFalse": false,
|
|
||||||
"IsUnknown": false,
|
|
||||||
"IsNotUnknown": true,
|
|
||||||
"Complex1": true,
|
|
||||||
"Complex2": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Eq1": null,
|
|
||||||
"Eq2": false,
|
|
||||||
"NEq1": null,
|
|
||||||
"NEq2": false,
|
|
||||||
"Distinct1": true,
|
|
||||||
"Distinct2": true,
|
|
||||||
"NotDistinct1": false,
|
|
||||||
"NotDistinct2": false,
|
|
||||||
"IsTrue": false,
|
|
||||||
"IsNotTrue": true,
|
|
||||||
"IsFalse": true,
|
|
||||||
"IsNotFalse": false,
|
|
||||||
"IsUnknown": false,
|
|
||||||
"IsNotUnknown": true,
|
|
||||||
"Complex1": true,
|
|
||||||
"Complex2": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
93
tests/testdata/common/common.go
vendored
93
tests/testdata/common/common.go
vendored
|
|
@ -1,93 +0,0 @@
|
||||||
package common
|
|
||||||
|
|
||||||
type ExpressionTestResult struct {
|
|
||||||
IsNull *bool
|
|
||||||
IsNotNull *bool
|
|
||||||
In *bool
|
|
||||||
InSelect *bool
|
|
||||||
NotIn *bool
|
|
||||||
NotInSelect *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type EqualityExpResult struct {
|
|
||||||
Eq1 *bool
|
|
||||||
Eq2 *bool
|
|
||||||
Distinct1 *bool
|
|
||||||
Distinct2 *bool
|
|
||||||
NotDistinct1 *bool
|
|
||||||
NotDistinct2 *bool
|
|
||||||
Lt1 *bool
|
|
||||||
Lt2 *bool
|
|
||||||
Lte1 *bool
|
|
||||||
Lte2 *bool
|
|
||||||
Gt1 *bool
|
|
||||||
Gt2 *bool
|
|
||||||
Gte1 *bool
|
|
||||||
Gte2 *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type AllTypesIntegerExpResult struct {
|
|
||||||
EqualityExpResult `alias:"."`
|
|
||||||
|
|
||||||
Add1 *int64
|
|
||||||
Add2 *int64
|
|
||||||
Sub1 *int64
|
|
||||||
Sub2 *int64
|
|
||||||
Mul1 *int64
|
|
||||||
Mul2 *int64
|
|
||||||
Div1 *int64
|
|
||||||
Div2 *int64
|
|
||||||
Mod1 *int64
|
|
||||||
Mod2 *int64
|
|
||||||
Pow1 *int64
|
|
||||||
Pow2 *int64
|
|
||||||
BitAnd1 *int64
|
|
||||||
BitAnd2 *int64
|
|
||||||
BitOr1 *int64
|
|
||||||
BitOr2 *int64
|
|
||||||
BitXor1 *int64
|
|
||||||
BitXor2 *int64
|
|
||||||
BitShiftLeft1 *int64
|
|
||||||
BitShiftLeft2 *int64
|
|
||||||
BitShiftRight1 *int64
|
|
||||||
BitShiftRight2 *int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type FloatExpressionTestResult struct {
|
|
||||||
Eq1 *bool
|
|
||||||
Eq2 *bool
|
|
||||||
Eq3 *bool
|
|
||||||
Distinct1 *bool
|
|
||||||
Distinct2 *bool
|
|
||||||
Distinct3 *bool
|
|
||||||
NotDistinct1 *bool
|
|
||||||
NotDistinct2 *bool
|
|
||||||
NotDistinct3 *bool
|
|
||||||
Lt1 *bool
|
|
||||||
Lt2 *bool
|
|
||||||
Gt1 *bool
|
|
||||||
Gt2 *bool
|
|
||||||
Add1 *float64
|
|
||||||
Add2 *float64
|
|
||||||
Sub1 *float64
|
|
||||||
Sub2 *float64
|
|
||||||
Mul1 *float64
|
|
||||||
Mul2 *float64
|
|
||||||
Div1 *float64
|
|
||||||
Div2 *float64
|
|
||||||
Mod1 *float64
|
|
||||||
Mod2 *float64
|
|
||||||
Pow1 *float64
|
|
||||||
Pow2 *float64
|
|
||||||
|
|
||||||
Abs *float64
|
|
||||||
Power *float64
|
|
||||||
Sqrt *float64
|
|
||||||
Cbrt *float64
|
|
||||||
Ceil *float64
|
|
||||||
Floor *float64
|
|
||||||
Round1 *float64
|
|
||||||
Round2 *float64
|
|
||||||
Sign *float64
|
|
||||||
Trunc *float64
|
|
||||||
}
|
|
||||||
76
tests/testdata/common/float_operators.json
vendored
76
tests/testdata/common/float_operators.json
vendored
|
|
@ -1,76 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"Eq1": true,
|
|
||||||
"Eq2": false,
|
|
||||||
"Eq3": false,
|
|
||||||
"Distinct1": false,
|
|
||||||
"Distinct2": true,
|
|
||||||
"Distinct3": true,
|
|
||||||
"NotDistinct1": true,
|
|
||||||
"NotDistinct2": false,
|
|
||||||
"NotDistinct3": false,
|
|
||||||
"Lt1": true,
|
|
||||||
"Lt2": true,
|
|
||||||
"Gt1": false,
|
|
||||||
"Gt2": false,
|
|
||||||
"Add1": 2.22,
|
|
||||||
"Add2": 12.33,
|
|
||||||
"Sub1": 0,
|
|
||||||
"Sub2": -10.11,
|
|
||||||
"Mul1": 1.23,
|
|
||||||
"Mul2": 12.45,
|
|
||||||
"Div1": 1,
|
|
||||||
"Div2": 0.09,
|
|
||||||
"Mod1": 0,
|
|
||||||
"Mod2": 1.11,
|
|
||||||
"Pow1": 1.12,
|
|
||||||
"Pow2": 1.24,
|
|
||||||
"Abs": 1.11,
|
|
||||||
"Power": 1.24,
|
|
||||||
"Sqrt": 1.05,
|
|
||||||
"Cbrt": 1.03,
|
|
||||||
"Ceil": 6,
|
|
||||||
"Floor": 5,
|
|
||||||
"Round1": 1,
|
|
||||||
"Round2": 1.11,
|
|
||||||
"Sign": 1,
|
|
||||||
"Trunc": 1.1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Eq1": true,
|
|
||||||
"Eq2": false,
|
|
||||||
"Eq3": false,
|
|
||||||
"Distinct1": false,
|
|
||||||
"Distinct2": true,
|
|
||||||
"Distinct3": true,
|
|
||||||
"NotDistinct1": true,
|
|
||||||
"NotDistinct2": false,
|
|
||||||
"NotDistinct3": false,
|
|
||||||
"Lt1": true,
|
|
||||||
"Lt2": true,
|
|
||||||
"Gt1": false,
|
|
||||||
"Gt2": false,
|
|
||||||
"Add1": 2.22,
|
|
||||||
"Add2": 12.33,
|
|
||||||
"Sub1": null,
|
|
||||||
"Sub2": -10.11,
|
|
||||||
"Mul1": null,
|
|
||||||
"Mul2": 12.45,
|
|
||||||
"Div1": null,
|
|
||||||
"Div2": 0.09,
|
|
||||||
"Mod1": null,
|
|
||||||
"Mod2": 1.11,
|
|
||||||
"Pow1": null,
|
|
||||||
"Pow2": 1.24,
|
|
||||||
"Abs": 1.11,
|
|
||||||
"Power": 1.24,
|
|
||||||
"Sqrt": 1.05,
|
|
||||||
"Cbrt": 1.03,
|
|
||||||
"Ceil": 6,
|
|
||||||
"Floor": 5,
|
|
||||||
"Round1": 1,
|
|
||||||
"Round2": 1.11,
|
|
||||||
"Sign": 1,
|
|
||||||
"Trunc": 1.1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
78
tests/testdata/common/int_operators.json
vendored
78
tests/testdata/common/int_operators.json
vendored
|
|
@ -1,78 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"Eq1": true,
|
|
||||||
"Eq2": false,
|
|
||||||
"Distinct1": false,
|
|
||||||
"Distinct2": true,
|
|
||||||
"NotDistinct1": true,
|
|
||||||
"NotDistinct2": false,
|
|
||||||
"Lt1": true,
|
|
||||||
"Lt2": false,
|
|
||||||
"Lte1": true,
|
|
||||||
"Lte2": false,
|
|
||||||
"Gt1": false,
|
|
||||||
"Gt2": true,
|
|
||||||
"Gte1": false,
|
|
||||||
"Gte2": true,
|
|
||||||
"Add1": 10000,
|
|
||||||
"Add2": 5011,
|
|
||||||
"Sub1": 0,
|
|
||||||
"Sub2": 4989,
|
|
||||||
"Mul1": 25000000,
|
|
||||||
"Mul2": 55000,
|
|
||||||
"Div1": 1,
|
|
||||||
"Div2": 454,
|
|
||||||
"Mod1": 0,
|
|
||||||
"Mod2": 6,
|
|
||||||
"Pow1": 38416,
|
|
||||||
"Pow2": 7529536,
|
|
||||||
"BitAnd1": 14,
|
|
||||||
"BitAnd2": 14,
|
|
||||||
"BitOr1": 14,
|
|
||||||
"BitOr2": 30,
|
|
||||||
"BitXor1": 0,
|
|
||||||
"BitXor2": 5,
|
|
||||||
"BitShiftLeft1": 1792,
|
|
||||||
"BitShiftLeft2": 224,
|
|
||||||
"BitShiftRight1": 3,
|
|
||||||
"BitShiftRight2": 7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Eq1": true,
|
|
||||||
"Eq2": false,
|
|
||||||
"Distinct1": false,
|
|
||||||
"Distinct2": true,
|
|
||||||
"NotDistinct1": true,
|
|
||||||
"NotDistinct2": false,
|
|
||||||
"Lt1": null,
|
|
||||||
"Lt2": false,
|
|
||||||
"Lte1": null,
|
|
||||||
"Lte2": false,
|
|
||||||
"Gt1": null,
|
|
||||||
"Gt2": true,
|
|
||||||
"Gte1": null,
|
|
||||||
"Gte2": true,
|
|
||||||
"Add1": 10000,
|
|
||||||
"Add2": 5011,
|
|
||||||
"Sub1": 0,
|
|
||||||
"Sub2": 4989,
|
|
||||||
"Mul1": 25000000,
|
|
||||||
"Mul2": 55000,
|
|
||||||
"Div1": 1,
|
|
||||||
"Div2": 454,
|
|
||||||
"Mod1": 0,
|
|
||||||
"Mod2": 6,
|
|
||||||
"Pow1": 38416,
|
|
||||||
"Pow2": 7529536,
|
|
||||||
"BitAnd1": 14,
|
|
||||||
"BitAnd2": 14,
|
|
||||||
"BitOr1": 14,
|
|
||||||
"BitOr2": 30,
|
|
||||||
"BitXor1": 0,
|
|
||||||
"BitXor2": 5,
|
|
||||||
"BitShiftLeft1": 1792,
|
|
||||||
"BitShiftLeft2": 224,
|
|
||||||
"BitShiftRight1": 3,
|
|
||||||
"BitShiftRight2": 7
|
|
||||||
}
|
|
||||||
]
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue