Merge pull request #8 from go-jet/mariadb

Add MariaDB support.
This commit is contained in:
go-jet 2019-08-16 13:02:31 +02:00 committed by GitHub
commit 7924d13875
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 608 additions and 528067 deletions

View file

@ -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

3
.gitignore vendored
View file

@ -17,4 +17,5 @@
# Test files # Test files
gen gen
.gentestdata .gentestdata
.tests/testdata/

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "tests/testdata"]
path = tests/testdata
url = https://github.com/go-jet/jet-test-data

View file

@ -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';
` `
} }

View file

@ -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

View file

@ -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
} }

View file

@ -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)
} }

View file

@ -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
@ -14,32 +15,35 @@ type SerializeOverride func(expressions ...Expression) SerializeFunc
type QueryPlaceholderFunc func(ord int) string 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
AliasQuoteChar byte FunctionSerializeOverrides map[string]SerializeOverride
IdentifierQuoteChar byte AliasQuoteChar byte
ArgumentPlaceholder QueryPlaceholderFunc IdentifierQuoteChar byte
ArgumentPlaceholder QueryPlaceholderFunc
} }
func NewDialect(params DialectParams) Dialect { 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,
aliasQuoteChar: params.AliasQuoteChar, functionSerializeOverrides: params.FunctionSerializeOverrides,
identifierQuoteChar: params.IdentifierQuoteChar, aliasQuoteChar: params.AliasQuoteChar,
argumentPlaceholder: params.ArgumentPlaceholder, identifierQuoteChar: params.IdentifierQuoteChar,
argumentPlaceholder: params.ArgumentPlaceholder,
} }
} }
type dialectImpl struct { type dialectImpl struct {
name string name string
packageName string packageName string
serializeOverrides map[string]SerializeOverride operatorSerializeOverrides map[string]SerializeOverride
aliasQuoteChar byte functionSerializeOverrides map[string]SerializeOverride
identifierQuoteChar byte aliasQuoteChar byte
argumentPlaceholder QueryPlaceholderFunc identifierQuoteChar byte
argumentPlaceholder QueryPlaceholderFunc
supportsReturning bool supportsReturning bool
} }
@ -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 {

View file

@ -77,17 +77,22 @@ 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
operator string additionalParam Expression
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)

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -1,7 +1,9 @@
package jet 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, "~")
} }

View file

@ -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

View file

@ -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) {

View file

@ -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)

View file

@ -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

View file

@ -8,19 +8,21 @@ 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 {
return "?" return "?"
}, },
@ -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...)
}
}

View file

@ -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")
}

View file

@ -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

View file

@ -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")
} }

View file

@ -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

View file

@ -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
@ -57,15 +60,16 @@ type selectStatementImpl struct {
jet.ExpressionStatementImpl jet.ExpressionStatementImpl
setOperatorsImpl setOperatorsImpl
Select jet.ClauseSelect Select jet.ClauseSelect
From jet.ClauseFrom From jet.ClauseFrom
Where jet.ClauseWhere Where jet.ClauseWhere
GroupBy jet.ClauseGroupBy GroupBy jet.ClauseGroupBy
Having jet.ClauseHaving Having jet.ClauseHaving
OrderBy jet.ClauseOrderBy OrderBy jet.ClauseOrderBy
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)
} }

View file

@ -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;
`)
}

View file

@ -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
View 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
}

View file

@ -3,23 +3,23 @@ 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 {
return "$" + strconv.Itoa(ord) return "$" + strconv.Itoa(ord)
}, },
@ -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...)
}
}

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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
View 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

View file

@ -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

View file

@ -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');

View file

@ -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,

View file

@ -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)),
REGEXP_LIKE(String("ABA"), String("aba")), }
REGEXP_LIKE(String("ABA"), String("aba"), "i"),
REGEXP_LIKE(AllTypes.Text, String("aba"), "i"),
)
if !sourceIsMariaDB() {
projectionList = append(projectionList, []Projection{
REGEXP_LIKE(String("ABA"), String("aba")),
REGEXP_LIKE(String("ABA"), 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,7 +802,20 @@ LIMIT ?;
//testutils.PrintJson(dest) //testutils.PrintJson(dest)
testutils.AssertJSON(t, 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, `
{ {
"Date": "2009-11-17T00:00:00Z", "Date": "2009-11-17T00:00:00Z",
"DateT": "2009-11-17T00:00:00Z", "DateT": "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 = `

View file

@ -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)
} }

View file

@ -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()

View file

@ -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",
( (
@ -183,19 +191,17 @@ SELECT payment.payment_id AS "payment.payment_id",
), ),
( (
( (
( 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 ?
) )
@ -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)
}

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

File diff suppressed because it is too large Load diff

View file

@ -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()

View file

@ -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) {

View file

@ -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))

View file

@ -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")
} }

View file

@ -128,19 +128,17 @@ SELECT payment.payment_id AS "payment.payment_id",
), ),
( (
( (
( SELECT payment.payment_id AS "payment.payment_id"
SELECT payment.payment_id AS "payment.payment_id" FROM dvds.payment
FROM dvds.payment LIMIT 1
LIMIT 1 OFFSET 10
OFFSET 10 )
) 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 1
LIMIT 1 OFFSET 2
OFFSET 2
)
) )
LIMIT 1 LIMIT 1
) )
@ -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) {

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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1
tests/testdata Submodule

@ -0,0 +1 @@
Subproject commit 7f3f3cc26ce34324f3699d6b422376671b827490

View file

@ -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
}
]

View file

@ -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
}

View file

@ -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
}
]

View file

@ -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
}
]