Dialect refactor improvements and clean up.

This commit is contained in:
go-jet 2019-08-06 10:29:04 +02:00
parent 23fd973699
commit 647ef21aaf
52 changed files with 1097 additions and 671 deletions

View file

@ -31,7 +31,8 @@ func (c ColumnInfo) SqlBuilderColumnType() string {
return "Timestamp" return "Timestamp"
case "timestamp with time zone": case "timestamp with time zone":
return "Timestampz" return "Timestampz"
case "time without time zone": case "time without time zone",
"time": //MySQL
return "Time" return "Time"
case "time with time zone": case "time with time zone":
return "Timez" return "Timez"
@ -67,7 +68,7 @@ func (c ColumnInfo) GoBaseType() string {
case "bigint": case "bigint":
return "int64" return "int64"
case "date", "timestamp without time zone", "timestamp with time zone", "time with time zone", "time without time zone", case "date", "timestamp without time zone", "timestamp with time zone", "time with time zone", "time without time zone",
"timestamp", "datetime": // MySQL "timestamp", "datetime", "time": // MySQL
return "time.Time" return "time.Time"
case "bytea", case "bytea",
"binary", "varbinary", "tinyblob", "blob", "mediumblob", "longblob": //MySQL "binary", "varbinary", "tinyblob", "blob", "mediumblob", "longblob": //MySQL

View file

@ -11,25 +11,25 @@ func TestBoolExpressionEQ(t *testing.T) {
func TestBoolExpressionNOT_EQ(t *testing.T) { func TestBoolExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColBool.NOT_EQ(table2ColBool), "(table1.col_bool != table2.col_bool)") assertClauseSerialize(t, table1ColBool.NOT_EQ(table2ColBool), "(table1.col_bool != table2.col_bool)")
assertClauseSerialize(t, table1ColBool.NOT_EQ(Bool(true)), "(table1.col_bool != TRUE)") assertClauseSerialize(t, table1ColBool.NOT_EQ(Bool(true)), "(table1.col_bool != $1)", true)
} }
func TestBoolExpressionIS_DISTINCT_FROM(t *testing.T) { func TestBoolExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(table2ColBool), "(table1.col_bool IS DISTINCT FROM table2.col_bool)") assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(table2ColBool), "(table1.col_bool IS DISTINCT FROM table2.col_bool)")
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(Bool(false)), "(table1.col_bool IS DISTINCT FROM FALSE)") assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(Bool(false)), "(table1.col_bool IS DISTINCT FROM $1)", false)
} }
func TestBoolExpressionIS_NOT_DISTINCT_FROM(t *testing.T) { func TestBoolExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(table2ColBool), "(table1.col_bool IS NOT DISTINCT FROM table2.col_bool)") assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(table2ColBool), "(table1.col_bool IS NOT DISTINCT FROM table2.col_bool)")
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(Bool(false)), "(table1.col_bool IS NOT DISTINCT FROM FALSE)") assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(Bool(false)), "(table1.col_bool IS NOT DISTINCT FROM $1)", false)
} }
func TestBoolExpressionIS_TRUE(t *testing.T) { func TestBoolExpressionIS_TRUE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_TRUE(), "table1.col_bool IS TRUE") assertClauseSerialize(t, table1ColBool.IS_TRUE(), "table1.col_bool IS TRUE")
assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE(), assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE(),
`(2 = table1.col_int) IS TRUE`) `($1 = table1.col_int) IS TRUE`, int64(2))
assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE().AND(Int(4).EQ(table2ColInt)), assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE().AND(Int(4).EQ(table2ColInt)),
`((2 = table1.col_int) IS TRUE AND (4 = table2.col_int))`) `(($1 = table1.col_int) IS TRUE AND ($2 = table2.col_int))`, int64(2), int64(4))
} }
func TestBoolExpressionIS_NOT_TRUE(t *testing.T) { func TestBoolExpressionIS_NOT_TRUE(t *testing.T) {
@ -55,20 +55,20 @@ func TestBoolExpressionIS_NOT_UNKNOWN(t *testing.T) {
func TestBinaryBoolExpression(t *testing.T) { func TestBinaryBoolExpression(t *testing.T) {
boolExpression := Int(2).EQ(Int(3)) boolExpression := Int(2).EQ(Int(3))
assertClauseSerialize(t, boolExpression, "(2 = 3)") assertClauseSerialize(t, boolExpression, "($1 = $2)", int64(2), int64(3))
assertProjectionSerialize(t, boolExpression, "2 = 3") assertProjectionSerialize(t, boolExpression, "$1 = $2", int64(2), int64(3))
assertProjectionSerialize(t, boolExpression.AS("alias_eq_expression"), assertProjectionSerialize(t, boolExpression.AS("alias_eq_expression"),
`(2 = 3) AS "alias_eq_expression"`) `($1 = $2) AS "alias_eq_expression"`, int64(2), int64(3))
assertClauseSerialize(t, boolExpression.AND(Int(4).EQ(Int(5))), assertClauseSerialize(t, boolExpression.AND(Int(4).EQ(Int(5))),
"((2 = 3) AND (4 = 5))") "(($1 = $2) AND ($3 = $4))", int64(2), int64(3), int64(4), int64(5))
assertClauseSerialize(t, boolExpression.OR(Int(4).EQ(Int(5))), assertClauseSerialize(t, boolExpression.OR(Int(4).EQ(Int(5))),
"((2 = 3) OR (4 = 5))") "(($1 = $2) OR ($3 = $4))", int64(2), int64(3), int64(4), int64(5))
} }
func TestBoolLiteral(t *testing.T) { func TestBoolLiteral(t *testing.T) {
assertClauseSerialize(t, Bool(true), "TRUE", true) assertClauseSerialize(t, Bool(true), "$1", true)
assertClauseSerialize(t, Bool(false), "FALSE", false) assertClauseSerialize(t, Bool(false), "$1", false)
} }
func TestExists(t *testing.T) { func TestExists(t *testing.T) {
@ -78,13 +78,13 @@ func TestExists(t *testing.T) {
WHERE(table1Col1.EQ(table2Col3)), WHERE(table1Col1.EQ(table2Col3)),
), ),
`(EXISTS ( `(EXISTS (
SELECT 1 SELECT $1
FROM db.table2 FROM db.table2
WHERE table1.col1 = table2.col3 WHERE table1.col1 = table2.col3
))`) ))`, int64(1))
} }
func TestBoolExp(t *testing.T) { func TestBoolExp(t *testing.T) {
assertClauseSerialize(t, BoolExp(String("true")), "'true'") assertClauseSerialize(t, BoolExp(String("true")), "$1", "true")
assertClauseSerialize(t, BoolExp(String("true")).IS_TRUE(), "'true' IS TRUE") assertClauseSerialize(t, BoolExp(String("true")).IS_TRUE(), "$1 IS TRUE", "true")
} }

View file

@ -21,6 +21,7 @@ func TestArgToString(t *testing.T) {
assert.Equal(t, argToString(uint(32)), "32") assert.Equal(t, argToString(uint(32)), "32")
assert.Equal(t, argToString(uint32(32)), "32") assert.Equal(t, argToString(uint32(32)), "32")
assert.Equal(t, argToString(uint64(64)), "64") assert.Equal(t, argToString(uint64(64)), "64")
assert.Equal(t, argToString(float64(1.11)), "1.11")
assert.Equal(t, argToString("john"), "'john'") assert.Equal(t, argToString("john"), "'john'")
assert.Equal(t, argToString([]byte("john")), "'john'") assert.Equal(t, argToString([]byte("john")), "'john'")

View file

@ -1,10 +1,17 @@
package jet package jet
import (
"errors"
"strconv"
)
var ANSII = NewDialect(DialectParams{ // just for tests var ANSII = NewDialect(DialectParams{ // just for tests
AliasQuoteChar: '"', AliasQuoteChar: '"',
IdentifierQuoteChar: '"',
ArgumentPlaceholder: func(ord int) string { ArgumentPlaceholder: func(ord int) string {
return "#" return "$" + strconv.Itoa(ord)
}, },
SupportsReturning: true,
}) })
type Dialect interface { type Dialect interface {
@ -15,7 +22,7 @@ type Dialect interface {
AliasQuoteChar() byte AliasQuoteChar() byte
IdentifierQuoteChar() byte IdentifierQuoteChar() byte
ArgumentPlaceholder() QueryPlaceholderFunc ArgumentPlaceholder() QueryPlaceholderFunc
UpdateAssigment() func(columns []IColumn, values []Clause, out *SqlBuilder) (err error) SetClause() func(columns []IColumn, values []Clause, out *SqlBuilder) (err error)
SupportsReturning() bool SupportsReturning() bool
} }
@ -35,7 +42,7 @@ type DialectParams struct {
AliasQuoteChar byte AliasQuoteChar byte
IdentifierQuoteChar byte IdentifierQuoteChar byte
ArgumentPlaceholder QueryPlaceholderFunc ArgumentPlaceholder QueryPlaceholderFunc
UpdateAssigment func(columns []IColumn, values []Clause, out *SqlBuilder) (err error) SetClause func(columns []IColumn, values []Clause, out *SqlBuilder) (err error)
SupportsReturning bool SupportsReturning bool
} }
@ -49,7 +56,7 @@ func NewDialect(params DialectParams) Dialect {
aliasQuoteChar: params.AliasQuoteChar, aliasQuoteChar: params.AliasQuoteChar,
identifierQuoteChar: params.IdentifierQuoteChar, identifierQuoteChar: params.IdentifierQuoteChar,
argumentPlaceholder: params.ArgumentPlaceholder, argumentPlaceholder: params.ArgumentPlaceholder,
updateAssigment: params.UpdateAssigment, setClause: params.SetClause,
supportsReturning: params.SupportsReturning, supportsReturning: params.SupportsReturning,
} }
} }
@ -62,7 +69,7 @@ type dialectImpl struct {
aliasQuoteChar byte aliasQuoteChar byte
identifierQuoteChar byte identifierQuoteChar byte
argumentPlaceholder QueryPlaceholderFunc argumentPlaceholder QueryPlaceholderFunc
updateAssigment UpdateAssigmentFunc setClause UpdateAssigmentFunc
supportsReturning bool supportsReturning bool
} }
@ -95,10 +102,40 @@ func (d *dialectImpl) ArgumentPlaceholder() QueryPlaceholderFunc {
return d.argumentPlaceholder return d.argumentPlaceholder
} }
func (d *dialectImpl) UpdateAssigment() func(columns []IColumn, values []Clause, out *SqlBuilder) (err error) { func (d *dialectImpl) SetClause() func(columns []IColumn, values []Clause, out *SqlBuilder) (err error) {
return d.updateAssigment if d.setClause != nil {
return d.setClause
}
return setClause
} }
func (d *dialectImpl) SupportsReturning() bool { func (d *dialectImpl) SupportsReturning() bool {
return d.supportsReturning return d.supportsReturning
} }
func setClause(columns []IColumn, values []Clause, out *SqlBuilder) (err error) {
if len(columns) != len(values) {
return errors.New("jet: mismatch in numers of columns and values")
}
for i, column := range columns {
if i > 0 {
out.WriteString(", ")
}
if column == nil {
return errors.New("jet: nil column in columns list")
}
out.WriteString(column.Name())
out.WriteString(" = ")
if err = Serialize(values[i], UpdateStatementType, out); err != nil {
return err
}
}
return nil
}

View file

@ -204,14 +204,13 @@ func CHR(integerExpression IntegerExpression) StringExpression {
return newStringFunc("CHR", integerExpression) return newStringFunc("CHR", integerExpression)
} }
// func CONCAT(expressions ...Expression) StringExpression {
//func CONCAT(expressions ...Expression) StringExpression { return newStringFunc("CONCAT", expressions...)
// return newStringFunc("CONCAT", expressions...) }
//}
// func CONCAT_WS(expressions ...Expression) StringExpression {
//func CONCAT_WS(expressions ...Expression) StringExpression { return newStringFunc("CONCAT_WS", expressions...)
// return newStringFunc("CONCAT_WS", expressions...) }
//}
// CONVERT converts string to dest_encoding. The original encoding is // CONVERT converts string to dest_encoding. The original encoding is
// specified by src_encoding. The string must be valid in this encoding. // specified by src_encoding. The string must be valid in this encoding.
@ -243,11 +242,11 @@ func DECODE(data StringExpression, format StringExpression) StringExpression {
return newStringFunc("DECODE", data, format) return newStringFunc("DECODE", data, format)
} }
//func FORMAT(formatStr StringExpression, formatArgs ...expressions) StringExpression { func FORMAT(formatStr StringExpression, formatArgs ...Expression) StringExpression {
// args := []expressions{formatStr} args := []Expression{formatStr}
// args = append(args, formatArgs...) args = append(args, formatArgs...)
// return newStringFunc("FORMAT", args...) return newStringFunc("FORMAT", args...)
//} }
// INITCAP converts the first letter of each word to upper case // INITCAP converts the first letter of each word to upper case
// and the rest to lower case. Words are sequences of alphanumeric // and the rest to lower case. Words are sequences of alphanumeric
@ -344,6 +343,14 @@ func TO_HEX(number IntegerExpression) StringExpression {
return newStringFunc("TO_HEX", number) return newStringFunc("TO_HEX", number)
} }
func REGEXP_LIKE(stringExp StringExpression, pattern StringExpression, matchType ...string) BoolExpression {
if len(matchType) > 0 {
return newBoolFunc("REGEXP_LIKE", stringExp, pattern, String(matchType[0], true))
}
return newBoolFunc("REGEXP_LIKE", stringExp, pattern)
}
//----------Data Type Formatting Functions ----------------------// //----------Data Type Formatting Functions ----------------------//
// TO_CHAR converts expression to string with format // TO_CHAR converts expression to string with format
@ -425,9 +432,9 @@ 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")
} }
timestampFunc.noBrackets = true timestampFunc.noBrackets = true
@ -506,6 +513,12 @@ func (f *funcExpressionImpl) serialize(statement StatementType, out *SqlBuilder,
return errors.New("jet: Function expressions is nil. ") return errors.New("jet: Function expressions is nil. ")
} }
if serializeOverride := out.Dialect.SerializeOverride(f.name); serializeOverride != nil {
serializeOverrideFunc := serializeOverride(f.expressions...)
return serializeOverrideFunc(statement, out, options...)
}
addBrackets := !f.noBrackets || len(f.expressions) > 0 addBrackets := !f.noBrackets || len(f.expressions) > 0
if addBrackets { if addBrackets {
@ -629,7 +642,7 @@ type timestampFunc struct {
timestampInterfaceImpl timestampInterfaceImpl
} }
func newTimestampFunc(name string, expressions ...Expression) *timestampFunc { func NewTimestampFunc(name string, expressions ...Expression) *timestampFunc {
timestampFunc := &timestampFunc{} timestampFunc := &timestampFunc{}
timestampFunc.funcExpressionImpl = *newFunc(name, expressions, timestampFunc) timestampFunc.funcExpressionImpl = *newFunc(name, expressions, timestampFunc)

View file

@ -1,9 +1,20 @@
package jet package jet
import "fmt" import (
"fmt"
"strconv"
"time"
)
// Representation of an escaped literal // Representation of an escaped literal
type literalExpression struct { type LiteralExpression interface {
Expression
Value() interface{}
SetConstant(constant bool)
}
type literalExpressionImpl struct {
expressionInterfaceImpl expressionInterfaceImpl
noOpVisitorImpl noOpVisitorImpl
@ -11,8 +22,8 @@ type literalExpression struct {
constant bool constant bool
} }
func literal(value interface{}, optionalConstant ...bool) *literalExpression { func literal(value interface{}, optionalConstant ...bool) *literalExpressionImpl {
exp := literalExpression{value: value} exp := literalExpressionImpl{value: value}
if len(optionalConstant) > 0 { if len(optionalConstant) > 0 {
exp.constant = optionalConstant[0] exp.constant = optionalConstant[0]
@ -23,14 +34,14 @@ func literal(value interface{}, optionalConstant ...bool) *literalExpression {
return &exp return &exp
} }
func constLiteral(value interface{}) *literalExpression { func constLiteral(value interface{}) *literalExpressionImpl {
exp := literal(value) exp := literal(value)
exp.constant = true exp.constant = true
return exp return exp
} }
func (l literalExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error { func (l *literalExpressionImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if l.constant { if l.constant {
out.insertConstantArgument(l.value) out.insertConstantArgument(l.value)
} else { } else {
@ -40,29 +51,102 @@ func (l literalExpression) serialize(statement StatementType, out *SqlBuilder, o
return nil return nil
} }
func (l *literalExpressionImpl) Value() interface{} {
return l.value
}
func (l *literalExpressionImpl) SetConstant(constant bool) {
l.constant = constant
}
type integerLiteralExpression struct {
literalExpressionImpl
integerInterfaceImpl
}
// 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, constant ...bool) IntegerExpression {
return IntExp(literal(value, constant...)) numLiteral := &integerLiteralExpression{}
numLiteral.literalExpressionImpl = *literal(value)
if len(constant) > 0 && constant[0] == true {
numLiteral.constant = true
}
numLiteral.literalExpressionImpl.parent = numLiteral
numLiteral.integerInterfaceImpl.parent = numLiteral
return numLiteral
}
//---------------------------------------------------//
type boolLiteralExpression struct {
boolInterfaceImpl
literalExpressionImpl
} }
// Bool creates new bool literal expression // Bool creates new bool literal expression
func Bool(value bool) BoolExpression { func Bool(value bool) BoolExpression {
return BoolExp(literal(value)) boolLiteralExpression := boolLiteralExpression{}
boolLiteralExpression.literalExpressionImpl = *literal(value)
boolLiteralExpression.boolInterfaceImpl.parent = &boolLiteralExpression
return &boolLiteralExpression
}
//---------------------------------------------------//
type floatLiteral struct {
floatInterfaceImpl
literalExpressionImpl
} }
// Float creates new float literal expression // Float creates new float literal expression
func Float(value float64) FloatExpression { func Float(value float64) FloatExpression {
return FloatExp(literal(value)) floatLiteral := floatLiteral{}
floatLiteral.literalExpressionImpl = *literal(value)
floatLiteral.floatInterfaceImpl.parent = &floatLiteral
return &floatLiteral
}
//---------------------------------------------------//
type stringLiteral struct {
stringInterfaceImpl
literalExpressionImpl
} }
// String creates new string literal expression // String creates new string literal expression
func String(value string) StringExpression { func String(value string, constant ...bool) StringExpression {
return StringExp(literal(value)) stringLiteral := stringLiteral{}
stringLiteral.literalExpressionImpl = *literal(value)
if len(constant) > 0 && constant[0] == true {
stringLiteral.constant = true
}
stringLiteral.stringInterfaceImpl.parent = &stringLiteral
return &stringLiteral
}
func formatMilliseconds(milliseconds ...int) string {
if len(milliseconds) > 0 {
if milliseconds[0] < 1000 {
return fmt.Sprintf(".%03d", milliseconds[0])
} else {
return "." + strconv.Itoa(milliseconds[0])
}
}
return ""
} }
// Time creates new time literal expression // Time creates new time literal expression
func Time(hour, minute, second, milliseconds int) TimeExpression { func Time(hour, minute, second int, milliseconds ...int) TimeExpression {
timeStr := fmt.Sprintf("%02d:%02d:%02d.%03d", hour, minute, second, milliseconds) timeStr := fmt.Sprintf("%02d:%02d:%02d", hour, minute, second)
timeStr += formatMilliseconds(milliseconds...)
return TimeExp(literal(timeStr)) return TimeExp(literal(timeStr))
} }
@ -75,8 +159,10 @@ func Timez(hour, minute, second, milliseconds, timezone int) TimezExpression {
} }
// Timestamp creates new timestamp literal expression // Timestamp creates new timestamp literal expression
func Timestamp(year, month, day, hour, minute, second, milliseconds int) TimestampExpression { func Timestamp(year int, month time.Month, day, hour, minute, second int, milliseconds ...int) TimestampExpression {
timeStr := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, milliseconds) timeStr := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second)
timeStr += formatMilliseconds(milliseconds...)
return TimestampExp(literal(timeStr)) return TimestampExp(literal(timeStr))
} }
@ -90,7 +176,7 @@ func Timestampz(year, month, day, hour, minute, second, milliseconds, timezone i
} }
//Date creates new date expression //Date creates new date expression
func Date(year, month, day int) DateExpression { func Date(year int, month time.Month, day int) DateExpression {
timeStr := fmt.Sprintf("%04d-%02d-%02d", year, month, day) timeStr := fmt.Sprintf("%04d-%02d-%02d", year, month, day)
return DateExp(literal(timeStr)) return DateExp(literal(timeStr))

View file

@ -19,16 +19,17 @@ FROM db.table2;
func TestSelectLiterals(t *testing.T) { func TestSelectLiterals(t *testing.T) {
assertStatement(t, SELECT(Int(1), Float(2.2), Bool(false)).FROM(table1), ` assertStatement(t, SELECT(Int(1), Float(2.2), Bool(false)).FROM(table1), `
SELECT 1, SELECT $1,
2.2, $2,
FALSE $3
FROM db.table1; FROM db.table1;
`) `, int64(1), 2.2, false)
} }
func TestSelectDistinct(t *testing.T) { func TestSelectDistinct(t *testing.T) {
assertStatement(t, SELECT(table1ColBool).DISTINCT(), ` assertStatement(t, SELECT(table1ColBool).DISTINCT().FROM(table1), `
SELECT DISTINCT table1.col_bool AS "table1.col_bool"; SELECT DISTINCT table1.col_bool AS "table1.col_bool"
FROM db.table1;
`) `)
} }

View file

@ -1,5 +1,9 @@
package jet package jet
const (
StringConcatOperator = "||"
)
// StringExpression interface // StringExpression interface
type StringExpression interface { type StringExpression interface {
Expression Expression
@ -18,8 +22,8 @@ type StringExpression interface {
LIKE(pattern StringExpression) BoolExpression LIKE(pattern StringExpression) BoolExpression
NOT_LIKE(pattern StringExpression) BoolExpression NOT_LIKE(pattern StringExpression) BoolExpression
SIMILAR_TO(pattern StringExpression) BoolExpression
NOT_SIMILAR_TO(pattern StringExpression) BoolExpression REGEXP_LIKE(pattern StringExpression, matchType ...string) BoolExpression
} }
type stringInterfaceImpl struct { type stringInterfaceImpl struct {
@ -59,7 +63,7 @@ func (s *stringInterfaceImpl) LT_EQ(rhs StringExpression) BoolExpression {
} }
func (s *stringInterfaceImpl) CONCAT(rhs Expression) StringExpression { func (s *stringInterfaceImpl) CONCAT(rhs Expression) StringExpression {
return newBinaryStringExpression(s.parent, rhs, "||") return newBinaryStringExpression(s.parent, rhs, StringConcatOperator)
} }
func (s *stringInterfaceImpl) LIKE(pattern StringExpression) BoolExpression { func (s *stringInterfaceImpl) LIKE(pattern StringExpression) BoolExpression {
@ -70,12 +74,8 @@ 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) SIMILAR_TO(pattern StringExpression) BoolExpression { func (s *stringInterfaceImpl) REGEXP_LIKE(pattern StringExpression, matchType ...string) BoolExpression {
return newBinaryBoolOperator(s.parent, pattern, "SIMILAR TO") return REGEXP_LIKE(s.parent, pattern, matchType...)
}
func (s *stringInterfaceImpl) NOT_SIMILAR_TO(pattern StringExpression) BoolExpression {
return newBinaryBoolOperator(s.parent, pattern, "NOT SIMILAR TO")
} }
//---------------------------------------------------// //---------------------------------------------------//

View file

@ -66,14 +66,9 @@ func TestStringNOT_LIKE(t *testing.T) {
assertClauseSerialize(t, table3StrCol.NOT_LIKE(String("JOHN")), "(table3.col2 NOT LIKE $1)", "JOHN") assertClauseSerialize(t, table3StrCol.NOT_LIKE(String("JOHN")), "(table3.col2 NOT LIKE $1)", "JOHN")
} }
func TestStringSIMILAR_TO(t *testing.T) { func TestStringREGEXP_LIKE(t *testing.T) {
assertClauseSerialize(t, table3StrCol.SIMILAR_TO(table2ColStr), "(table3.col2 SIMILAR TO table2.col_str)") assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(table2ColStr), "REGEXP_LIKE(table3.col2, table2.col_str)")
assertClauseSerialize(t, table3StrCol.SIMILAR_TO(String("JOHN")), "(table3.col2 SIMILAR TO $1)", "JOHN") assertClauseSerialize(t, table3StrCol.REGEXP_LIKE(String("JOHN"), "c"), "REGEXP_LIKE(table3.col2, $1, 'c')", "JOHN")
}
func TestStringNOT_SIMILAR_TO(t *testing.T) {
assertClauseSerialize(t, table3StrCol.NOT_SIMILAR_TO(table2ColStr), "(table3.col2 NOT SIMILAR TO table2.col_str)")
assertClauseSerialize(t, table3StrCol.NOT_SIMILAR_TO(String("JOHN")), "(table3.col2 NOT SIMILAR TO $1)", "JOHN")
} }
func TestStringExp(t *testing.T) { func TestStringExp(t *testing.T) {

View file

@ -79,12 +79,8 @@ func assertClauseSerialize(t *testing.T, clause Clause, query string, args ...in
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, out.DebugSQL(), query) assert.DeepEqual(t, out.Buff.String(), query)
if len(args) > 0 {
assert.DeepEqual(t, out.Args, args) assert.DeepEqual(t, out.Args, args)
}
} }
func assertClauseSerializeErr(t *testing.T, clause Clause, errString string) { func assertClauseSerializeErr(t *testing.T, clause Clause, errString string) {
@ -102,22 +98,19 @@ func assertProjectionSerialize(t *testing.T, projection Projection, query string
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, out.DebugSQL(), query) assert.DeepEqual(t, out.Buff.String(), query)
if len(args) > 0 {
assert.DeepEqual(t, out.Args, args) assert.DeepEqual(t, out.Args, args)
}
} }
func assertStatement(t *testing.T, query Statement, expectedQuery string, expectedArgs ...interface{}) { func assertStatement(t *testing.T, query Statement, expectedQuery string, expectedArgs ...interface{}) {
queryStr, err := query.DebugSql() queryStr, args, err := query.Sql()
assert.NilError(t, err) assert.NilError(t, err)
fmt.Println(queryStr) fmt.Println(queryStr)
//fmt.Println(queryStr) //fmt.Println(queryStr)
assert.Equal(t, queryStr, expectedQuery) assert.Equal(t, queryStr, expectedQuery)
//assert.DeepEqual(t, args, expectedArgs) assert.DeepEqual(t, args, expectedArgs)
} }
func assertStatementErr(t *testing.T, stmt Statement, errorStr string) { func assertStatementErr(t *testing.T, stmt Statement, errorStr string) {

View file

@ -89,7 +89,7 @@ func (u *updateStatementImpl) Sql(dialect ...Dialect) (query string, args []inte
out.newLine() out.newLine()
out.WriteString("SET") out.WriteString("SET")
if err = out.Dialect.UpdateAssigment()(u.columns, u.values, out); err != nil { if err = out.Dialect.SetClause()(u.columns, u.values, out); err != nil {
return return
} }

View file

@ -20,7 +20,7 @@ WHERE table1.col_int >= $2;
func TestUpdateWithValues(t *testing.T) { func TestUpdateWithValues(t *testing.T) {
expectedSQL := ` expectedSQL := `
UPDATE db.table1 UPDATE db.table1
SET (col_int, col_float) = ($1, $2) SET col_int = $1, col_float = $2
WHERE table1.col_int >= $3; WHERE table1.col_int >= $3;
` `
stmt := table1.UPDATE(table1ColInt, table1ColFloat). stmt := table1.UPDATE(table1ColInt, table1ColFloat).
@ -51,26 +51,7 @@ RETURNING table1.col1 AS "table1.col1";
assertStatement(t, stmt, expectedSQL, int64(2)) assertStatement(t, stmt, expectedSQL, int64(2))
} }
func TestUpdateColumnsWithSelect(t *testing.T) {
expectedSQL := `
UPDATE db.table1
SET (col1, col_float) = (
SELECT table1.col_float AS "table1.col_float",
table2.col3 AS "table2.col3"
FROM db.table1
)
WHERE table1.col1 = $1
RETURNING table1.col1 AS "table1.col1";
`
stmt := table1.UPDATE(table1Col1, table1ColFloat).
SET(table1.SELECT(table1ColFloat, table2Col3)).
WHERE(table1Col1.EQ(Int(2))).
RETURNING(table1Col1)
assertStatement(t, stmt, expectedSQL, int64(2))
}
func TestInvalidInputs(t *testing.T) { func TestInvalidInputs(t *testing.T) {
assertStatementErr(t, table1.UPDATE(table1ColInt).SET(1, 2), "jet: WHERE clause not set") assertStatementErr(t, table1.UPDATE(table1ColInt).SET(1), "jet: WHERE clause not set")
assertStatementErr(t, table1.UPDATE(nil).SET(1, 2), "jet: nil column in columns list") assertStatementErr(t, table1.UPDATE(nil).SET(1), "jet: nil column in columns list")
} }

View file

@ -84,11 +84,14 @@ func AssertDebugStatementSql(t *testing.T, query jet.Statement, expectedQuery st
_, args, err := query.Sql() _, args, err := query.Sql()
assert.NilError(t, err) assert.NilError(t, err)
//assert.Equal(t, queryStr, expectedQuery) //assert.Equal(t, queryStr, expectedQuery)
if len(expectedArgs) > 0 {
assert.DeepEqual(t, args, expectedArgs) assert.DeepEqual(t, args, expectedArgs)
}
debuqSql, err := query.DebugSql() debuqSql, err := query.DebugSql()
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, debuqSql, expectedQuery) assert.Equal(t, debuqSql, expectedQuery)
} }

View file

@ -1,89 +0,0 @@
package mysql
import (
"testing"
)
func TestBoolExpressionEQ(t *testing.T) {
assertClauseSerializeErr(t, table1ColBool.EQ(nil), "jet: nil rhs")
assertClauseSerialize(t, table1ColBool.EQ(table2ColBool), "(table1.col_bool = table2.col_bool)")
assertClauseSerialize(t, table1ColBool.EQ(Bool(true)), "(table1.col_bool = ?)", true)
}
func TestBoolExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColBool.NOT_EQ(table2ColBool), "(table1.col_bool != table2.col_bool)")
assertClauseSerialize(t, table1ColBool.NOT_EQ(Bool(true)), "(table1.col_bool != ?)", true)
}
func TestBoolExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(table2ColBool), "(NOT table1.col_bool <=> table2.col_bool)")
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(Bool(false)), "(NOT table1.col_bool <=> ?)", false)
}
func TestBoolExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(table2ColBool), "(table1.col_bool <=> table2.col_bool)")
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(Bool(false)), "(table1.col_bool <=> ?)", false)
}
func TestBoolExpressionIS_TRUE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_TRUE(), "table1.col_bool IS TRUE")
assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE(),
`(? = table1.col_int) IS TRUE`, int64(2))
assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE().AND(Int(4).EQ(table2ColInt)),
`((? = table1.col_int) IS TRUE AND (? = table2.col_int))`, int64(2), int64(4))
}
func TestBoolExpressionIS_NOT_TRUE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_TRUE(), "table1.col_bool IS NOT TRUE")
}
func TestBoolExpressionIS_FALSE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_FALSE(), "table1.col_bool IS FALSE")
}
func TestBoolExpressionIS_NOT_FALSE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_FALSE(), "table1.col_bool IS NOT FALSE")
}
func TestBoolExpressionIS_UNKNOWN(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_UNKNOWN(), "table1.col_bool IS UNKNOWN")
}
func TestBoolExpressionIS_NOT_UNKNOWN(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_UNKNOWN(), "table1.col_bool IS NOT UNKNOWN")
}
func TestBinaryBoolExpressionAsProjection(t *testing.T) {
boolExpression := Int(2).EQ(Int(3))
assertProjectionSerialize(t, boolExpression, "? = ?", int64(2), int64(3))
assertProjectionSerialize(t, boolExpression.AS("alias_eq_expression"),
`(? = ?) AS "alias_eq_expression"`, int64(2), int64(3))
}
func TestBoolLiteral(t *testing.T) {
assertClauseSerialize(t, Bool(true), "?", true)
assertClauseSerialize(t, Bool(false), "?", false)
}
//
//func TestExists(t *testing.T) {
//
// assertClauseSerialize(t, EXISTS(
// table2.
// SELECT(Int(1)).
// WHERE(table1Col1.EQ(table2Col3)),
// ),
// `(EXISTS (
// SELECT ?
// FROM db.table2
// WHERE table1.col1 = table2.col3
//))`, int64(1))
//}
//
//func TestBoolExp(t *testing.T) {
// assertClauseSerialize(t, BoolExp(String("true")), "?", "true")
// assertClauseSerialize(t, BoolExp(String("true")).IS_TRUE(), "? IS TRUE", "true")
//}

View file

@ -1,9 +0,0 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
type Column jet.Column
type IColumnList jet.IColumnList
var ColumnList = jet.ColumnList

41
mysql/columns.go Normal file
View file

@ -0,0 +1,41 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
type Column jet.Column
type IColumnList jet.IColumnList
var ColumnList = jet.ColumnList
type ColumnBool jet.ColumnBool
var BoolColumn = jet.BoolColumn
type ColumnString jet.ColumnString
var StringColumn = jet.StringColumn
type ColumnInteger jet.ColumnInteger
var IntegerColumn = jet.IntegerColumn
type ColumnFloat jet.ColumnFloat
var FloatColumn = jet.FloatColumn
type ColumnTime jet.ColumnTime
var TimeColumn = jet.TimeColumn
type ColumnDate jet.ColumnDate
var DateColumn = jet.DateColumn
type ColumnDateTime jet.ColumnTimestamp
var DateTimeColumn = jet.TimestampColumn
type ColumnTimestamp jet.ColumnTimestamp
var TimestampColumn = jet.TimestampColumn

View file

@ -14,6 +14,7 @@ func NewDialect() jet.Dialect {
serializeOverrides["IS NOT DISTINCT FROM"] = mysql_IS_NOT_DISTINCT_FROM serializeOverrides["IS NOT DISTINCT FROM"] = mysql_IS_NOT_DISTINCT_FROM
serializeOverrides["/"] = mysql_DIVISION serializeOverrides["/"] = mysql_DIVISION
serializeOverrides["#"] = mysql_BIT_XOR serializeOverrides["#"] = mysql_BIT_XOR
serializeOverrides[jet.StringConcatOperator] = mysql_CONCAT_operator
mySQLDialectParams := jet.DialectParams{ mySQLDialectParams := jet.DialectParams{
Name: "MySQL", Name: "MySQL",
@ -24,36 +25,12 @@ func NewDialect() jet.Dialect {
ArgumentPlaceholder: func(int) string { ArgumentPlaceholder: func(int) string {
return "?" return "?"
}, },
UpdateAssigment: mysqlUpdateAssigment,
SupportsReturning: false, SupportsReturning: false,
} }
return jet.NewDialect(mySQLDialectParams) return jet.NewDialect(mySQLDialectParams)
} }
func mysqlUpdateAssigment(columns []jet.IColumn, values []jet.Clause, out *jet.SqlBuilder) (err error) {
if len(columns) != len(values) {
return errors.New("jet: mismatch in numers of columns and values")
}
for i, column := range columns {
if i > 0 {
out.WriteString(", ")
}
out.WriteString(column.Name())
out.WriteString(" = ")
if err = jet.Serialize(values[i], jet.UpdateStatementType, out); err != nil {
return err
}
}
return nil
}
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) error { return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error {
if len(expressions) != 2 { if len(expressions) != 2 {
@ -76,6 +53,30 @@ func mysql_BIT_XOR(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) error {
if len(expressions) != 2 {
return errors.New("jet: invalid number of expressions for operator")
}
out.WriteString("CONCAT(")
if err := jet.Serialize(expressions[0], statement, out, options...); err != nil {
return err
}
out.WriteString(", ")
if err := jet.Serialize(expressions[1], statement, out, options...); err != nil {
return err
}
out.WriteString(")")
return nil
}
}
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) error { return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error {
if len(expressions) != 2 { if len(expressions) != 2 {
@ -126,7 +127,7 @@ func mysql_IS_NOT_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc
func mysql_IS_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc { func mysql_IS_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc {
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error { return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error {
out.WriteString("NOT") out.WriteString("NOT(")
err := mysql_IS_NOT_DISTINCT_FROM(expressions...)(statement, out, options...) err := mysql_IS_NOT_DISTINCT_FROM(expressions...)(statement, out, options...)
@ -134,6 +135,8 @@ func mysql_IS_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc {
return err return err
} }
out.WriteString(")")
return nil return nil
} }
} }

35
mysql/dialect_test.go Normal file
View file

@ -0,0 +1,35 @@
package mysql
import (
"testing"
)
func TestBoolExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(table2ColBool), "(NOT(table1.col_bool <=> table2.col_bool))")
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(Bool(false)), "(NOT(table1.col_bool <=> ?))", false)
}
func TestBoolExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(table2ColBool), "(table1.col_bool <=> table2.col_bool)")
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(Bool(false)), "(table1.col_bool <=> ?)", false)
}
func TestBoolLiteral(t *testing.T) {
assertClauseSerialize(t, Bool(true), "?", true)
assertClauseSerialize(t, Bool(false), "?", false)
}
func TestIntegerExpressionDIV(t *testing.T) {
assertClauseSerialize(t, table1ColInt.DIV(table2ColInt), "(table1.col_int DIV table2.col_int)")
assertClauseSerialize(t, table1ColInt.DIV(Int(11)), "(table1.col_int DIV ?)", int64(11))
}
func TestIntExpressionPOW(t *testing.T) {
assertClauseSerialize(t, table1ColInt.POW(table2ColInt), "POW(table1.col_int, table2.col_int)")
assertClauseSerialize(t, table1ColInt.POW(Int(11)), "POW(table1.col_int, ?)", int64(11))
}
func TestIntExpressionBIT_XOR(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_XOR(table2ColInt), "(table1.col_int ^ table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_XOR(Int(11)), "(table1.col_int ^ ?)", int64(11))
}

View file

@ -12,10 +12,21 @@ type IntegerExpression jet.IntegerExpression
type FloatExpression jet.FloatExpression type FloatExpression jet.FloatExpression
type TimeExpression jet.TimeExpression
type DateExpression jet.DateExpression type DateExpression jet.DateExpression
type DateTimeExpression jet.TimestampExpression type DateTimeExpression jet.TimestampExpression
type TimestampExpression jet.TimestampExpression type TimestampExpression jet.TimestampExpression
type TimeExpression jet.TimeExpression var BoolExp = jet.BoolExp
var StringExp = jet.StringExp
var IntExp = jet.IntExp
var FloatExp = jet.FloatExp
var TimeExp = jet.TimeExp
var DateExp = jet.DateExp
var DateTimeExp = jet.TimestampExp
var TimestampExp = jet.TimestampExp
var RAW = jet.RAW

122
mysql/functions.go Normal file
View file

@ -0,0 +1,122 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
// ------------------ Mathematical functions ---------------//
var POW = jet.POW
var LN = jet.LN
var LOG = jet.LOG
var ABSf = jet.ABSf
var ABSi = jet.ABSi
var POWER = jet.POWER
var SQRT = jet.SQRT
func CBRT(number jet.NumericExpression) jet.FloatExpression {
return POWER(number, Float(1.0).DIV(Float(3.0)))
}
var CEIL = jet.CEIL
var FLOOR = jet.FLOOR
var ROUND = jet.ROUND
var SIGN = jet.SIGN
var TRUNC = TRUNCATE
var TRUNCATE = func(floatExpression jet.FloatExpression, precision jet.IntegerExpression) jet.FloatExpression {
return jet.NewFloatFunc("TRUNCATE", floatExpression, precision)
}
var MINUSi = jet.MINUSi
var MINUSf = jet.MINUSf
var BIT_NOT = jet.BIT_NOT
// ----------------- Aggregate functions -------------------//
var BIT_AND = jet.BIT_AND
var BIT_OR = jet.BIT_OR
var BOOL_AND = jet.BOOL_AND
var BOOL_OR = jet.BOOL_OR
var EVERY = jet.EVERY
var MAXi = jet.MAXi
var MINi = jet.MINi
var SUMi = jet.SUMi
var SUMf = jet.SUMf
var AVG = jet.AVG
var MAXf = jet.MAXf
var MINf = jet.MINf
var COUNT = jet.COUNT
//--------------------- String functions ------------------//
var REGEXP_LIKE = jet.REGEXP_LIKE
var BIT_LENGTH = jet.BIT_LENGTH
var CHAR_LENGTH = jet.CHAR_LENGTH
var OCTET_LENGTH = jet.OCTET_LENGTH
var LOWER = jet.LOWER
var UPPER = jet.UPPER
var BTRIM = jet.BTRIM
var LTRIM = jet.LTRIM
var RTRIM = jet.RTRIM
var CHR = jet.CHR
var CONCAT = jet.CONCAT
var CONCAT_WS = jet.CONCAT_WS
var CONVERT = jet.CONVERT
var CONVERT_FROM = jet.CONVERT_FROM
var CONVERT_TO = jet.CONVERT_TO
var ENCODE = jet.ENCODE
var DECODE = jet.DECODE
var FORMAT = jet.FORMAT
var INITCAP = jet.INITCAP
var LEFT = jet.LEFT
var RIGHT = jet.RIGHT
func LENGTH(str jet.StringExpression) jet.StringExpression {
return jet.LENGTH(str)
}
func LPAD(str jet.StringExpression, length jet.IntegerExpression, text jet.StringExpression) jet.StringExpression {
return jet.LPAD(str, length, text)
}
func RPAD(str jet.StringExpression, length jet.IntegerExpression, text jet.StringExpression) jet.StringExpression {
return jet.RPAD(str, length, text)
}
var MD5 = jet.MD5
var REPEAT = jet.REPEAT
var REPLACE = jet.REPLACE
var REVERSE = jet.REVERSE
var STRPOS = jet.STRPOS
var SUBSTR = jet.SUBSTR
var TO_ASCII = jet.TO_ASCII
var TO_HEX = jet.TO_HEX
//----------Data Type Formatting Functions ----------------------//
var TO_CHAR = jet.TO_CHAR
var TO_DATE = jet.TO_DATE
var TO_NUMBER = jet.TO_NUMBER
var TO_TIMESTAMP = jet.TO_TIMESTAMP
//----------------- Date/Time Functions and Operators ------------//
var CURRENT_DATE = jet.CURRENT_DATE
var CURRENT_TIME = jet.CURRENT_TIME
var CURRENT_TIMESTAMP = jet.CURRENT_TIMESTAMP
var LOCALTIME = jet.LOCALTIME
var LOCALTIMESTAMP = jet.LOCALTIMESTAMP
func NOW(fsp ...int) DateTimeExpression {
if len(fsp) > 0 {
return jet.NewTimestampFunc("NOW", Int(int64(fsp[0]), true))
}
return jet.NewTimestampFunc("NOW")
}
// --------------- Conditional Expressions Functions -------------//
var COALESCE = jet.COALESCE
var NULLIF = jet.NULLIF
var GREATEST = jet.GREATEST
var LEAST = jet.LEAST
var EXISTS = jet.EXISTS
var CASE = jet.CASE

View file

@ -1,107 +0,0 @@
package mysql
import (
"testing"
)
func TestIntegerExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.EQ(table2ColInt), "(table1.col_int = table2.col_int)")
assertClauseSerialize(t, table1ColInt.EQ(Int(11)), "(table1.col_int = ?)", int64(11))
}
func TestIntegerExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.NOT_EQ(table2ColInt), "(table1.col_int != table2.col_int)")
assertClauseSerialize(t, table1ColInt.NOT_EQ(Int(11)), "(table1.col_int != ?)", int64(11))
}
func TestIntegerExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.GT(table2ColInt), "(table1.col_int > table2.col_int)")
assertClauseSerialize(t, table1ColInt.GT(Int(11)), "(table1.col_int > ?)", int64(11))
}
func TestIntegerExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.GT_EQ(table2ColInt), "(table1.col_int >= table2.col_int)")
assertClauseSerialize(t, table1ColInt.GT_EQ(Int(11)), "(table1.col_int >= ?)", int64(11))
}
func TestIntegerExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.LT(table2ColInt), "(table1.col_int < table2.col_int)")
assertClauseSerialize(t, table1ColInt.LT(Int(11)), "(table1.col_int < ?)", int64(11))
}
func TestIntegerExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.LT_EQ(table2ColInt), "(table1.col_int <= table2.col_int)")
assertClauseSerialize(t, table1ColInt.LT_EQ(Int(11)), "(table1.col_int <= ?)", int64(11))
}
func TestIntegerExpressionADD(t *testing.T) {
assertClauseSerialize(t, table1ColInt.ADD(table2ColInt), "(table1.col_int + table2.col_int)")
assertClauseSerialize(t, table1ColInt.ADD(Int(11)), "(table1.col_int + ?)", int64(11))
}
func TestIntegerExpressionSUB(t *testing.T) {
assertClauseSerialize(t, table1ColInt.SUB(table2ColInt), "(table1.col_int - table2.col_int)")
assertClauseSerialize(t, table1ColInt.SUB(Int(11)), "(table1.col_int - ?)", int64(11))
}
func TestIntegerExpressionMUL(t *testing.T) {
assertClauseSerialize(t, table1ColInt.MUL(table2ColInt), "(table1.col_int * table2.col_int)")
assertClauseSerialize(t, table1ColInt.MUL(Int(11)), "(table1.col_int * ?)", int64(11))
}
func TestIntegerExpressionDIV(t *testing.T) {
assertClauseSerialize(t, table1ColInt.DIV(table2ColInt), "(table1.col_int DIV table2.col_int)")
assertClauseSerialize(t, table1ColInt.DIV(Int(11)), "(table1.col_int DIV ?)", int64(11))
}
func TestIntExpressionMOD(t *testing.T) {
assertClauseSerialize(t, table1ColInt.MOD(table2ColInt), "(table1.col_int % table2.col_int)")
assertClauseSerialize(t, table1ColInt.MOD(Int(11)), "(table1.col_int % ?)", int64(11))
}
func TestIntExpressionPOW(t *testing.T) {
assertClauseSerialize(t, table1ColInt.POW(table2ColInt), "POW(table1.col_int, table2.col_int)")
assertClauseSerialize(t, table1ColInt.POW(Int(11)), "POW(table1.col_int, ?)", int64(11))
}
func TestIntExpressionBIT_NOT(t *testing.T) {
assertClauseSerialize(t, BIT_NOT(table2ColInt), "(~ table2.col_int)")
assertClauseSerialize(t, BIT_NOT(Int(11)), "(~ ?)", int64(11))
}
func TestIntExpressionBIT_AND(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_AND(table2ColInt), "(table1.col_int & table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_AND(Int(11)), "(table1.col_int & ?)", int64(11))
}
func TestIntExpressionBIT_OR(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_OR(table2ColInt), "(table1.col_int | table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_OR(Int(11)), "(table1.col_int | ?)", int64(11))
}
func TestIntExpressionBIT_XOR(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_XOR(table2ColInt), "(table1.col_int ^ table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_XOR(Int(11)), "(table1.col_int ^ ?)", int64(11))
}
func TestIntExpressionBIT_SHIFT_LEFT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_LEFT(table2ColInt), "(table1.col_int << table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_LEFT(Int(11)), "(table1.col_int << ?)", int64(11))
}
func TestIntExpressionBIT_SHIFT_RIGHT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(table2ColInt), "(table1.col_int >> table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(Int(11)), "(table1.col_int >> ?)", int64(11))
}
//
//func TestIntExpressionIntExp(t *testing.T) {
// assertClauseSerialize(t, IntExp(table1ColFloat), "table1.col_float")
// assertClauseSerialize(t, IntExp(table1ColFloat.ADD(table2ColFloat)).ADD(Int(11)),
// "((table1.col_float + table2.col_float) + ?)", int64(11))
//}
func TestIntExpression_MINUSi(t *testing.T) {
assertClauseSerialize(t, MINUSi(table2ColInt), "(- table2.col_int)")
assertClauseSerialize(t, MINUSi(Int(3)), "(- ?)", int64(3))
}

13
mysql/literal.go Normal file
View file

@ -0,0 +1,13 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
var Bool = jet.Bool
var Int = jet.Int
var Float = jet.Float
var String = jet.String
var Time = jet.Time
var Date = jet.Date
var DateTime = jet.Timestamp
var Timestamp = jet.Timestamp

27
mysql/statements.go Normal file
View file

@ -0,0 +1,27 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
// ----------------- FUNCTIONS ----------------------//
var SELECT = jet.SELECT
type SelectLock jet.SelectLock
var (
UPDATE = jet.NewSelectLock("UPDATE")
SHARE = jet.NewSelectLock("SHARE")
)
var UNION = jet.UNION
var UNION_ALL = jet.UNION_ALL
var INTERSECT = jet.INTERSECT
var INTERSECT_ALL = jet.INTERSECT_ALL
var EXCEPT = jet.EXCEPT
var EXCEPT_ALL = jet.EXCEPT_ALL
//-----------------literals----------------------//
var STAR = jet.STAR
var NULL = jet.NULL
var DEFAULT = jet.DEFAULT

View file

@ -1,86 +0,0 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
type ColumnBool jet.ColumnBool
var BoolColumn = jet.BoolColumn
var Bool = jet.Bool
type ColumnString jet.ColumnString
var StringColumn = jet.StringColumn
var String = jet.String
type ColumnInteger jet.ColumnInteger
var IntegerColumn = jet.IntegerColumn
var Int = jet.Int
type ColumnFloat jet.ColumnFloat
var FloatColumn = jet.FloatColumn
var Float = jet.Float
type ColumnDate jet.ColumnDate
var DateColumn = jet.DateColumn
var Date = jet.Date
type ColumnDateTime jet.ColumnTimestamp
var DateTimeColumn = jet.TimestampColumn
var DateTime = jet.Timestamp
type ColumnTimestamp jet.ColumnTimestamp
var TimestampColumn = jet.TimestampColumn
var Timestamp = jet.Timestamp
// ----------------- FUNCTIONS ----------------------//
var ABSf = jet.ABSf
var ABSi = jet.ABSi
var POWER = jet.POWER
var SQRT = jet.SQRT
func CBRT(number jet.NumericExpression) jet.FloatExpression {
return POWER(number, Float(1.0).DIV(Float(3.0)))
}
var CEIL = jet.CEIL
var FLOOR = jet.FLOOR
var ROUND = jet.ROUND
var SIGN = jet.SIGN
var TRUNC = TRUNCATE
var TRUNCATE = func(floatExpression jet.FloatExpression, precision jet.IntegerExpression) jet.FloatExpression {
return jet.NewFloatFunc("TRUNCATE", floatExpression, precision)
}
var MINUSi = jet.MINUSi
var MINUSf = jet.MINUSf
var BIT_NOT = jet.BIT_NOT
var SUMf = jet.SUMf
var AVG = jet.AVG
var MAXf = jet.MAXf
var MINf = jet.MINf
var COUNT = jet.COUNT
var SELECT = jet.SELECT
type SelectLock jet.SelectLock
var (
UPDATE = jet.NewSelectLock("UPDATE")
SHARE = jet.NewSelectLock("SHARE")
)
var UNION = jet.UNION
//-----------------literals----------------------//
var STAR = jet.STAR
var NULL = jet.NULL
var DEFAULT = jet.DEFAULT

View file

@ -9,6 +9,7 @@ type cast interface {
jet.Cast jet.Cast
// Cast expression AS bool type // Cast expression AS bool type
AS_BOOL() BoolExpression AS_BOOL() BoolExpression
// Cast expression AS smallint type // Cast expression AS smallint type
AS_SMALLINT() IntegerExpression AS_SMALLINT() IntegerExpression
// Cast expression AS integer type // Cast expression AS integer type
@ -16,7 +17,7 @@ type cast interface {
// Cast expression AS bigint type // Cast expression AS bigint type
AS_BIGINT() IntegerExpression AS_BIGINT() IntegerExpression
// Cast expression AS numeric type, using precision and optionally scale // Cast expression AS numeric type, using precision and optionally scale
AS_NUMERIC(precision int, scale ...int) FloatExpression AS_NUMERIC(precisionAndScale ...int) FloatExpression
// Cast expression AS real type // Cast expression AS real type
AS_REAL() FloatExpression AS_REAL() FloatExpression
@ -25,6 +26,8 @@ type cast interface {
// Cast expression AS text type // Cast expression AS text type
AS_TEXT() StringExpression AS_TEXT() StringExpression
AS_BYTEA() StringExpression
// Cast expression AS time with time timezone type // Cast expression AS time with time timezone type
AS_TIMEZ() TimezExpression AS_TIMEZ() TimezExpression
// Cast expression AS timestamp type // Cast expression AS timestamp type
@ -64,16 +67,17 @@ func (b *castImpl) AS_BIGINT() IntegerExpression {
} }
// Cast expression AS numeric type, using precision and optionally scale // Cast expression AS numeric type, using precision and optionally scale
func (b *castImpl) AS_NUMERIC(precision int, scale ...int) FloatExpression { func (b *castImpl) AS_NUMERIC(precisionAndScale ...int) FloatExpression {
var castType string var castArgs string
if len(scale) > 0 { var argLen = len(precisionAndScale)
castType = fmt.Sprintf("numeric(%d, %d)", precision, scale[0]) if argLen >= 2 {
} else { castArgs = fmt.Sprintf("(%d, %d)", precisionAndScale[0], precisionAndScale[1])
castType = fmt.Sprintf("numeric(%d)", precision) } else if argLen == 1 {
castArgs = fmt.Sprintf("(%d)", precisionAndScale[0])
} }
return jet.FloatExp(b.AS(castType)) return jet.FloatExp(b.AS("numeric" + castArgs))
} }
// Cast expression AS real type // Cast expression AS real type
@ -91,6 +95,11 @@ func (b *castImpl) AS_TEXT() StringExpression {
return jet.StringExp(b.AS("text")) return jet.StringExp(b.AS("text"))
} }
// Cast expression AS text type
func (b *castImpl) AS_BYTEA() StringExpression {
return jet.StringExp(b.AS("bytea"))
}
// Cast expression AS date type // Cast expression AS date type
func (b *castImpl) AS_TIME() jet.TimeExpression { func (b *castImpl) AS_TIME() jet.TimeExpression {
return TimeExp(b.AS("time without time zone")) return TimeExp(b.AS("time without time zone"))

View file

@ -2,62 +2,44 @@ package postgres
import "github.com/go-jet/jet/internal/jet" import "github.com/go-jet/jet/internal/jet"
type Column jet.Column
type IColumnList jet.IColumnList
var ColumnList = jet.ColumnList
type ColumnBool jet.ColumnBool type ColumnBool jet.ColumnBool
type BoolExpression jet.BoolExpression
var BoolColumn = jet.BoolColumn var BoolColumn = jet.BoolColumn
type ColumnString jet.ColumnString type ColumnString jet.ColumnString
type StringExpression jet.StringExpression
var StringColumn = jet.StringColumn var StringColumn = jet.StringColumn
type ColumnInteger jet.ColumnInteger type ColumnInteger jet.ColumnInteger
type IntegerExpression jet.IntegerExpression
var IntegerColumn = jet.IntegerColumn var IntegerColumn = jet.IntegerColumn
type ColumnFloat jet.ColumnFloat type ColumnFloat jet.ColumnFloat
type FloatExpression jet.FloatExpression
var FloatColumn = jet.FloatColumn var FloatColumn = jet.FloatColumn
var FloatExp = jet.FloatExp
type ColumnDate jet.ColumnDate type ColumnDate jet.ColumnDate
type DateExpression jet.DateExpression
var DateColumn = jet.DateColumn var DateColumn = jet.DateColumn
type ColumnDateTime jet.ColumnTimestamp
type DateTimeExpression jet.TimestampExpression
var DateTimeColumn = jet.TimestampColumn
type TimeExpression jet.TimeExpression
type ColumnTime jet.ColumnTime type ColumnTime jet.ColumnTime
var TimeColumn = jet.TimeColumn var TimeColumn = jet.TimeColumn
var TimeExp = jet.TimeExp
type TimezExpression jet.TimezExpression
type ColumnTimez jet.ColumnTimez type ColumnTimez jet.ColumnTimez
var TimezColumn = jet.TimezColumn var TimezColumn = jet.TimezColumn
type ColumnTimestamp jet.ColumnTimestamp type ColumnTimestamp jet.ColumnTimestamp
type TimestampExpression jet.TimestampExpression
var TimestampColumn = jet.TimestampColumn var TimestampColumn = jet.TimestampColumn
var TimestampExp = jet.TimestampExp
type TimestampzExpression jet.TimestampzExpression
type ColumnTimestampz jet.ColumnTimestampz type ColumnTimestampz jet.ColumnTimestampz
var TimestampzColumn = jet.TimestampzColumn var TimestampzColumn = jet.TimestampzColumn
type SelectTable jet.SelectTable
// ---------------- statements -----------------//

View file

@ -1,24 +1,30 @@
package postgres package postgres
import ( import (
"errors"
"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{}
serializeOverrides["REGEXP_LIKE"] = postgres_REGEXP_LIKE_function
dialectParams := jet.DialectParams{ dialectParams := jet.DialectParams{
Name: "PostgreSQL", Name: "PostgreSQL",
PackageName: "postgres", PackageName: "postgres",
CastOverride: castFunc, CastOverride: castFunc,
SerializeOverrides: serializeOverrides,
AliasQuoteChar: '"', AliasQuoteChar: '"',
IdentifierQuoteChar: '"', IdentifierQuoteChar: '"',
ArgumentPlaceholder: func(ord int) string { ArgumentPlaceholder: func(ord int) string {
return "$" + strconv.Itoa(ord) return "$" + strconv.Itoa(ord)
}, },
UpdateAssigment: postgresUpdateAssigment, SetClause: postgresSetClause,
SupportsReturning: true, SupportsReturning: true,
} }
@ -35,7 +41,7 @@ func castFunc(expression jet.Expression, castType string) jet.SerializeFunc {
} }
} }
func postgresUpdateAssigment(columns []jet.IColumn, values []jet.Clause, out *jet.SqlBuilder) (err error) { func postgresSetClause(columns []jet.IColumn, values []jet.Clause, out *jet.SqlBuilder) (err error) {
if len(columns) > 1 { if len(columns) > 1 {
out.WriteString("(") out.WriteString("(")
} }
@ -68,3 +74,37 @@ func postgresUpdateAssigment(columns []jet.IColumn, values []jet.Clause, out *je
return return
} }
func postgres_REGEXP_LIKE_function(expressions ...jet.Expression) jet.SerializeFunc {
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error {
if len(expressions) < 2 {
return errors.New("jet: invalid number of expressions for operator")
}
if err := jet.Serialize(expressions[0], statement, out, options...); err != nil {
return err
}
caseSensitive := false
if len(expressions) >= 3 {
if stringLiteral, ok := expressions[2].(jet.LiteralExpression); ok {
matchType := stringLiteral.Value().(string)
caseSensitive = !strings.Contains(matchType, "i")
}
}
if caseSensitive {
out.WriteString("~")
} else {
out.WriteString("~*")
}
if err := jet.Serialize(expressions[1], statement, out, options...); err != nil {
return err
}
return nil
}
}

15
postgres/dialect_test.go Normal file
View file

@ -0,0 +1,15 @@
package postgres
import "testing"
func TestString_REGEXP_LIKE_operator(t *testing.T) {
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"), "i"), "table3.col2 ~* $1", "JOHN")
}
func TestString_REGEXP_LIKE_function(t *testing.T) {
assertClauseSerialize(t, REGEXP_LIKE(table3StrCol, table2ColStr), "table3.col2 ~* table2.col_str")
assertClauseSerialize(t, REGEXP_LIKE(table3StrCol, String("JOHN"), "c"), "table3.col2 ~ $1", "JOHN")
assertClauseSerialize(t, REGEXP_LIKE(table3StrCol, String("JOHN"), "i"), "table3.col2 ~* $1", "JOHN")
}

View file

@ -3,3 +3,34 @@ package postgres
import "github.com/go-jet/jet/internal/jet" import "github.com/go-jet/jet/internal/jet"
type Expression jet.Expression type Expression jet.Expression
type BoolExpression jet.BoolExpression
type StringExpression jet.StringExpression
type IntegerExpression jet.IntegerExpression
type FloatExpression jet.FloatExpression
type TimeExpression jet.TimeExpression
type TimezExpression jet.TimezExpression
type DateExpression jet.DateExpression
type TimestampExpression jet.TimestampExpression
type TimestampzExpression jet.TimestampzExpression
var BoolExp = jet.BoolExp
var IntExp = jet.IntExp
var FloatExp = jet.FloatExp
var TimeExp = jet.TimeExp
var TimezExp = jet.TimezExp
var DateExp = jet.DateExp
var TimestampExp = jet.TimestampExp
var TimestampzExp = jet.TimestampzExp
var RAW = jet.RAW
var NewEnumValue = jet.NewEnumValue

View file

@ -38,6 +38,7 @@ 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
@ -47,11 +48,25 @@ var BTRIM = jet.BTRIM
var LTRIM = jet.LTRIM var LTRIM = jet.LTRIM
var RTRIM = jet.RTRIM var RTRIM = jet.RTRIM
var CHR = jet.CHR var CHR = jet.CHR
var CONCAT = func(expressions ...Expression) StringExpression {
return jet.CONCAT(explicitCasts(expressions...)...)
}
func CONCAT_WS(expressions ...Expression) StringExpression {
return jet.CONCAT_WS(explicitCasts(expressions...)...)
}
var CONVERT = jet.CONVERT var CONVERT = jet.CONVERT
var CONVERT_FROM = jet.CONVERT_FROM var CONVERT_FROM = jet.CONVERT_FROM
var CONVERT_TO = jet.CONVERT_TO var CONVERT_TO = jet.CONVERT_TO
var ENCODE = jet.ENCODE var ENCODE = jet.ENCODE
var DECODE = jet.DECODE var DECODE = jet.DECODE
func FORMAT(formatStr StringExpression, formatArgs ...Expression) StringExpression {
return jet.FORMAT(formatStr, explicitCasts(formatArgs...)...)
}
var INITCAP = jet.INITCAP var INITCAP = jet.INITCAP
var LEFT = jet.LEFT var LEFT = jet.LEFT
var RIGHT = jet.RIGHT var RIGHT = jet.RIGHT
@ -91,3 +106,32 @@ var GREATEST = jet.GREATEST
var LEAST = jet.LEAST var LEAST = jet.LEAST
var EXISTS = jet.EXISTS var EXISTS = jet.EXISTS
var CASE = jet.CASE var CASE = jet.CASE
func explicitCasts(expressions ...Expression) []jet.Expression {
ret := []jet.Expression{}
for _, exp := range expressions {
ret = append(ret, explicitCast(exp))
}
return ret
}
func explicitCast(expresion Expression) jet.Expression {
if _, ok := expresion.(jet.LiteralExpression); !ok {
return expresion
}
switch expresion.(type) {
case jet.BoolExpression:
return CAST(expresion).AS_BOOL()
case jet.IntegerExpression:
return CAST(expresion).AS_INTEGER()
case jet.FloatExpression:
return CAST(expresion).AS_NUMERIC()
case jet.StringExpression:
return CAST(expresion).AS_TEXT()
}
return expresion
}

View file

@ -1,24 +1,32 @@
package postgres package postgres
import "github.com/go-jet/jet/internal/jet" import (
"github.com/go-jet/jet/internal/jet"
"time"
)
var Bool = jet.Bool var Bool = jet.Bool
var Int = jet.Int var Int = jet.Int
var Float = jet.Float var Float = jet.Float
var String = jet.String var String = jet.String
var Date = func(year, month, day int) DateExpression {
var Bytea = func(value string) StringExpression {
return CAST(jet.String(value)).AS_BYTEA()
}
var Date = func(year int, month time.Month, day int) DateExpression {
return CAST(jet.Date(year, month, day)).AS_DATE() return CAST(jet.Date(year, month, day)).AS_DATE()
} }
var Time = func(hour, minute, second, milliseconds int) TimeExpression { var Time = func(hour, minute, second int, milliseconds ...int) TimeExpression {
return CAST(jet.Time(hour, minute, second, milliseconds)).AS_TIME() return CAST(jet.Time(hour, minute, second, milliseconds...)).AS_TIME()
} }
var Timez = func(hour, minute, second, milliseconds int, timezone int) TimezExpression { var Timez = func(hour, minute, second, milliseconds int, timezone int) TimezExpression {
return CAST(jet.Timez(hour, minute, second, milliseconds, timezone)).AS_TIMEZ() return CAST(jet.Timez(hour, minute, second, milliseconds, timezone)).AS_TIMEZ()
} }
var Timestamp = func(year, month, day, hour, minute, second, milliseconds int) TimestampExpression { var Timestamp = func(year int, month time.Month, day, hour, minute, second, milliseconds int) TimestampExpression {
return CAST(jet.Timestamp(year, month, day, hour, minute, second, milliseconds)).AS_TIMESTAMP() return CAST(jet.Timestamp(year, month, day, hour, minute, second, milliseconds)).AS_TIMESTAMP()
} }

7
postgres/literal_test.go Normal file
View file

@ -0,0 +1,7 @@
package postgres
import "testing"
func TestDateLiteral(t *testing.T) {
assertClauseSerialize(t, Date(2019, 8, 6), "$1::DATE", "2019-08-06")
}

View file

@ -4,10 +4,18 @@ import "github.com/go-jet/jet/internal/jet"
// --------- Arithmetic operators -------------// // --------- Arithmetic operators -------------//
var MINUSi = jet.MINUSi //var MINUSi = jet.MINUSi
var MINUSf = jet.MINUSf var MINUSf = jet.MINUSf
//----------- Logical operators ---------------// //----------- Logical operators ---------------//
var NOT = jet.NOT var NOT = jet.NOT
var BIT_NOT = jet.BIT_NOT var BIT_NOT = jet.BIT_NOT
func MINUSi(intExp IntegerExpression) IntegerExpression {
if intLit, ok := intExp.(jet.LiteralExpression); ok {
intLit.SetConstant(true)
}
return intExp
}

View file

@ -1,9 +0,0 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
type Column jet.Column
type IColumnList jet.IColumnList
var ColumnList = jet.ColumnList

View file

@ -1,5 +0,0 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
var NewEnumValue = jet.NewEnumValue

View file

@ -1,5 +0,0 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
var RAW = jet.RAW

View file

@ -3,6 +3,15 @@ package postgres
import "github.com/go-jet/jet/internal/jet" import "github.com/go-jet/jet/internal/jet"
type SelectStatement jet.SelectStatement type SelectStatement jet.SelectStatement
type SelectTable jet.SelectTable
type SelectLock jet.SelectLock
var (
UPDATE = jet.NewSelectLock("UPDATE")
NO_KEY_UPDATE = jet.NewSelectLock("NO KEY UPDATE")
SHARE = jet.NewSelectLock("SHARE")
KEY_SHARE = jet.NewSelectLock("KEY SHARE")
)
var SELECT = jet.SELECT var SELECT = jet.SELECT
@ -31,12 +40,3 @@ func toJetSelects(selects ...SelectStatement) []jet.SelectStatement {
return ret return ret
} }
type SelectLock jet.SelectLock
var (
UPDATE = jet.NewSelectLock("UPDATE")
NO_KEY_UPDATE = jet.NewSelectLock("NO KEY UPDATE")
SHARE = jet.NewSelectLock("SHARE")
KEY_SHARE = jet.NewSelectLock("KEY SHARE")
)

View file

@ -1,53 +0,0 @@
package postgres
import (
"testing"
)
var timeVar = Time(10, 20, 0, 0)
func TestTimeExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColTime.EQ(table2ColTime), "(table1.col_time = table2.col_time)")
assertClauseSerialize(t, table1ColTime.EQ(timeVar), "(table1.col_time = $1::time without time zone)", "10:20:00.000")
}
func TestTimeExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTime.NOT_EQ(table2ColTime), "(table1.col_time != table2.col_time)")
assertClauseSerialize(t, table1ColTime.NOT_EQ(timeVar), "(table1.col_time != $1::time without time zone)", "10:20:00.000")
}
func TestTimeExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTime.IS_DISTINCT_FROM(table2ColTime), "(table1.col_time IS DISTINCT FROM table2.col_time)")
assertClauseSerialize(t, table1ColTime.IS_DISTINCT_FROM(timeVar), "(table1.col_time IS DISTINCT FROM $1::time without time zone)", "10:20:00.000")
}
func TestTimeExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTime.IS_NOT_DISTINCT_FROM(table2ColTime), "(table1.col_time IS NOT DISTINCT FROM table2.col_time)")
assertClauseSerialize(t, table1ColTime.IS_NOT_DISTINCT_FROM(timeVar), "(table1.col_time IS NOT DISTINCT FROM $1::time without time zone)", "10:20:00.000")
}
func TestTimeExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColTime.LT(table2ColTime), "(table1.col_time < table2.col_time)")
assertClauseSerialize(t, table1ColTime.LT(timeVar), "(table1.col_time < $1::time without time zone)", "10:20:00.000")
}
func TestTimeExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTime.LT_EQ(table2ColTime), "(table1.col_time <= table2.col_time)")
assertClauseSerialize(t, table1ColTime.LT_EQ(timeVar), "(table1.col_time <= $1::time without time zone)", "10:20:00.000")
}
func TestTimeExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColTime.GT(table2ColTime), "(table1.col_time > table2.col_time)")
assertClauseSerialize(t, table1ColTime.GT(timeVar), "(table1.col_time > $1::time without time zone)", "10:20:00.000")
}
func TestTimeExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTime.GT_EQ(table2ColTime), "(table1.col_time >= table2.col_time)")
assertClauseSerialize(t, table1ColTime.GT_EQ(timeVar), "(table1.col_time >= $1::time without time zone)", "10:20:00.000")
}
func TestTimeExp(t *testing.T) {
assertClauseSerialize(t, TimeExp(table1ColFloat), "table1.col_float")
assertClauseSerialize(t, TimeExp(table1ColFloat).LT(Time(1, 1, 1, 1)),
"(table1.col_float < $1::time without time zone)", string("01:01:01.001"))
}

View file

@ -1,54 +0,0 @@
package postgres
import (
"testing"
)
var timestamp = Timestamp(2000, 1, 31, 10, 20, 0, 0)
func TestTimestampExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.EQ(table2ColTimestamp), "(table1.col_timestamp = table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.EQ(timestamp),
"(table1.col_timestamp = $1::timestamp without time zone)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.NOT_EQ(table2ColTimestamp), "(table1.col_timestamp != table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.NOT_EQ(timestamp), "(table1.col_timestamp != $1::timestamp without time zone)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.IS_DISTINCT_FROM(table2ColTimestamp), "(table1.col_timestamp IS DISTINCT FROM table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.IS_DISTINCT_FROM(timestamp), "(table1.col_timestamp IS DISTINCT FROM $1::timestamp without time zone)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.IS_NOT_DISTINCT_FROM(table2ColTimestamp), "(table1.col_timestamp IS NOT DISTINCT FROM table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.IS_NOT_DISTINCT_FROM(timestamp), "(table1.col_timestamp IS NOT DISTINCT FROM $1::timestamp without time zone)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.LT(table2ColTimestamp), "(table1.col_timestamp < table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.LT(timestamp), "(table1.col_timestamp < $1::timestamp without time zone)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.LT_EQ(table2ColTimestamp), "(table1.col_timestamp <= table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.LT_EQ(timestamp), "(table1.col_timestamp <= $1::timestamp without time zone)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.GT(table2ColTimestamp), "(table1.col_timestamp > table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.GT(timestamp), "(table1.col_timestamp > $1::timestamp without time zone)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.GT_EQ(table2ColTimestamp), "(table1.col_timestamp >= table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.GT_EQ(timestamp), "(table1.col_timestamp >= $1::timestamp without time zone)", "2000-01-31 10:20:00.000")
}
func TestTimestampExp(t *testing.T) {
assertClauseSerialize(t, TimestampExp(table1ColFloat), "table1.col_float")
assertClauseSerialize(t, TimestampExp(table1ColFloat).LT(timestamp),
"(table1.col_float < $1::timestamp without time zone)", "2000-01-31 10:20:00.000")
}

View file

@ -66,6 +66,8 @@ CREATE TABLE `all_types` (
`bit_ptr` bit(10), `bit_ptr` bit(10),
-- date and time -- date and time
`time` time NOT NULL,
`time_ptr` time,
`date` date NOT NULL, `date` date NOT NULL,
`date_ptr` date, `date_ptr` date,
@ -84,8 +86,8 @@ CREATE TABLE `all_types` (
`char` char(20) NOT NULL, `char` char(20) NOT NULL,
`char_ptr` char(20), `char_ptr` char(20),
`varchar` varchar(20) NOT NULL, `var_char` varchar(20) NOT NULL,
`varchar_ptr` varchar(20), `var_char_ptr` varchar(20),
`binary` binary(20) NOT NULL, `binary` binary(20) NOT NULL,
`binary_ptr` binary(20), `binary_ptr` binary(20),
@ -117,12 +119,14 @@ INSERT INTO `all_types` VALUES
-3,3,14,14,-150,150,-1600,1600,5000,50000, -3,3,14,14,-150,150,-1600,1600,5000,50000,
-3,3,14,14,-150,150,-1600,1600,50000,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, 1.11,1.11,2.22,2.22,3.33,3.33,4.44,4.44,5.55,5.55,
_binary '\0',_binary '\0','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\"}'), _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, (false, NULL,
-3,3,14,14,-150,150,-1600,1600,5000,50000, -3,3,14,14,-150,150,-1600,1600,5000,50000,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, 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, 1.11,NULL,2.22,NULL,3.33,NULL,4.44,NULL,5.55,NULL,
_binary '\0',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); _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);

View file

@ -30,10 +30,10 @@ CREATE TABLE test_sample.ALL_TYPES
-- money_ptr money, -- money_ptr money,
-- money money NOT NULL, -- money money NOT NULL,
character_varying_ptr character varying(100), var_char_ptr character varying(100),
character_varying character varying(200) NOT NULL, var_char character varying(200) NOT NULL,
character_ptr character(80), char_ptr character(80),
character character(80) NOT NULL, char character(80) NOT NULL,
text_ptr text, text_ptr text,
text text NOT NULL, text text NOT NULL,
@ -99,7 +99,7 @@ CREATE TABLE test_sample.ALL_TYPES
INSERT INTO test_sample.ALL_types( 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, 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, -- money_ptr, money,
character_varying_ptr, character_varying, character_ptr, "character", text_ptr, text, var_char_ptr, var_char, char_ptr, char, text_ptr, text,
bytea_ptr, bytea, bytea_ptr, bytea,
timestampz_ptr, timestampz, timestamp_ptr, "timestamp", date_ptr, date, timez_ptr, timez, time_ptr, "time", interval_ptr, "interval", timestampz_ptr, timestampz, timestamp_ptr, "timestamp", date_ptr, date, timez_ptr, timez, time_ptr, "time", interval_ptr, "interval",
boolean_ptr, "boolean", boolean_ptr, "boolean",

View file

@ -1,10 +1,12 @@
package mysql package mysql
import ( import (
"fmt"
"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/common"
"time"
. "github.com/go-jet/jet/mysql" . "github.com/go-jet/jet/mysql"
@ -35,6 +37,8 @@ func TestExpressionOperators(t *testing.T) {
AllTypes.SmallIntPtr.IN(AllTypes.SELECT(AllTypes.Integer)).AS("result.in_select"), AllTypes.SmallIntPtr.IN(AllTypes.SELECT(AllTypes.Integer)).AS("result.in_select"),
AllTypes.SmallIntPtr.NOT_IN(Int(11), Int(22), NULL).AS("result.not_in"), AllTypes.SmallIntPtr.NOT_IN(Int(11), Int(22), NULL).AS("result.not_in"),
AllTypes.SmallIntPtr.NOT_IN(AllTypes.SELECT(AllTypes.Integer)).AS("result.not_in_select"), AllTypes.SmallIntPtr.NOT_IN(AllTypes.SELECT(AllTypes.Integer)).AS("result.not_in_select"),
RAW("DATABASE()"),
).LIMIT(2) ).LIMIT(2)
//fmt.Println(query.Sql()) //fmt.Println(query.Sql())
@ -51,7 +55,8 @@ SELECT all_types.integer IS NULL AS "result.is_null",
(all_types.small_int_ptr NOT IN (( (all_types.small_int_ptr NOT IN ((
SELECT all_types.integer AS "all_types.integer" SELECT all_types.integer AS "all_types.integer"
FROM test_sample.all_types FROM test_sample.all_types
))) AS "result.not_in_select" ))) AS "result.not_in_select",
DATABASE()
FROM test_sample.all_types FROM test_sample.all_types
LIMIT ?; LIMIT ?;
`, int64(11), int64(22), int64(11), int64(22), int64(2)) `, int64(11), int64(22), int64(11), int64(22), int64(2))
@ -116,8 +121,8 @@ SELECT (all_types.boolean = all_types.boolean_ptr) AS "EQ1",
(all_types.boolean = ?) AS "EQ2", (all_types.boolean = ?) AS "EQ2",
(all_types.boolean != all_types.boolean_ptr) AS "NEq1", (all_types.boolean != all_types.boolean_ptr) AS "NEq1",
(all_types.boolean != ?) AS "NEq2", (all_types.boolean != ?) AS "NEq2",
(NOT all_types.boolean <=> all_types.boolean_ptr) AS "distinct1", (NOT(all_types.boolean <=> all_types.boolean_ptr)) AS "distinct1",
(NOT all_types.boolean <=> ?) AS "distinct2", (NOT(all_types.boolean <=> ?)) AS "distinct2",
(all_types.boolean <=> all_types.boolean_ptr) AS "not_distinct_1", (all_types.boolean <=> all_types.boolean_ptr) AS "not_distinct_1",
(all_types.boolean <=> ?) AS "NOTDISTINCT2", (all_types.boolean <=> ?) AS "NOTDISTINCT2",
all_types.boolean IS TRUE AS "ISTRUE", all_types.boolean IS TRUE AS "ISTRUE",
@ -208,9 +213,9 @@ func TestFloatOperators(t *testing.T) {
SELECT (all_types.numeric = all_types.numeric) AS "eq1", SELECT (all_types.numeric = all_types.numeric) AS "eq1",
(all_types.decimal = ?) AS "eq2", (all_types.decimal = ?) AS "eq2",
(all_types.real = ?) AS "eq3", (all_types.real = ?) AS "eq3",
(NOT all_types.numeric <=> all_types.numeric) AS "distinct1", (NOT(all_types.numeric <=> all_types.numeric)) AS "distinct1",
(NOT all_types.decimal <=> ?) AS "distinct2", (NOT(all_types.decimal <=> ?)) AS "distinct2",
(NOT all_types.real <=> ?) AS "distinct3", (NOT(all_types.real <=> ?)) AS "distinct3",
(all_types.numeric <=> all_types.numeric) AS "not_distinct1", (all_types.numeric <=> all_types.numeric) AS "not_distinct1",
(all_types.decimal <=> ?) AS "not_distinct2", (all_types.decimal <=> ?) AS "not_distinct2",
(all_types.real <=> ?) AS "not_distinct3", (all_types.real <=> ?) AS "not_distinct3",
@ -338,8 +343,8 @@ SELECT all_types.big_int AS "all_types.big_int",
(all_types.big_int = ?) AS "eq2", (all_types.big_int = ?) AS "eq2",
(all_types.big_int != all_types.big_int_ptr) AS "neq1", (all_types.big_int != all_types.big_int_ptr) AS "neq1",
(all_types.big_int != ?) AS "neq2", (all_types.big_int != ?) AS "neq2",
(NOT all_types.big_int <=> all_types.big_int) AS "distinct1", (NOT(all_types.big_int <=> all_types.big_int)) AS "distinct1",
(NOT all_types.big_int <=> ?) AS "distinct2", (NOT(all_types.big_int <=> ?)) AS "distinct2",
(all_types.big_int <=> all_types.big_int) AS "not distinct1", (all_types.big_int <=> all_types.big_int) AS "not distinct1",
(all_types.big_int <=> ?) AS "not distinct2", (all_types.big_int <=> ?) AS "not distinct2",
(all_types.big_int < all_types.big_int_ptr) AS "lt1", (all_types.big_int < all_types.big_int_ptr) AS "lt1",
@ -394,6 +399,319 @@ LIMIT ?;
testutils.AssertJSONFile(t, dest, "./testdata/common/int_operators.json") testutils.AssertJSONFile(t, dest, "./testdata/common/int_operators.json")
} }
func TestStringOperators(t *testing.T) {
query := AllTypes.SELECT(
AllTypes.Text.EQ(AllTypes.Char),
AllTypes.Text.EQ(String("Text")),
AllTypes.Text.NOT_EQ(AllTypes.VarCharPtr),
AllTypes.Text.NOT_EQ(String("Text")),
AllTypes.Text.GT(AllTypes.Text),
AllTypes.Text.GT(String("Text")),
AllTypes.Text.GT_EQ(AllTypes.TextPtr),
AllTypes.Text.GT_EQ(String("Text")),
AllTypes.Text.LT(AllTypes.Char),
AllTypes.Text.LT(String("Text")),
AllTypes.Text.LT_EQ(AllTypes.VarCharPtr),
AllTypes.Text.LT_EQ(String("Text")),
AllTypes.Text.CONCAT(String("text2")),
AllTypes.Text.CONCAT(Int(11)),
AllTypes.Text.LIKE(String("abc")),
AllTypes.Text.NOT_LIKE(String("_b_")),
AllTypes.Text.REGEXP_LIKE(String("aba")),
AllTypes.Text.REGEXP_LIKE(String("aba"), "c"),
String("ABA").REGEXP_LIKE(String("aba"), "i"),
BIT_LENGTH(AllTypes.Text),
CHAR_LENGTH(AllTypes.Char),
OCTET_LENGTH(AllTypes.Text),
LOWER(AllTypes.VarCharPtr),
UPPER(AllTypes.Char),
LTRIM(AllTypes.VarCharPtr),
RTRIM(AllTypes.VarCharPtr),
CONCAT(String("string1"), Int(1), Float(11.12)),
CONCAT_WS(String("string1"), Int(1), Float(11.12)),
FORMAT(String("Hello %s, %1$s"), String("World")),
LEFT(String("abcde"), Int(2)),
RIGHT(String("abcde"), Int(2)),
LENGTH(String("jose")),
LPAD(String("Hi"), Int(5), String("xy")),
RPAD(String("Hi"), Int(5), String("xy")),
MD5(AllTypes.VarCharPtr),
REPEAT(AllTypes.Text, Int(33)),
REPLACE(AllTypes.Char, String("BA"), String("AB")),
REVERSE(AllTypes.VarCharPtr),
SUBSTR(AllTypes.CharPtr, Int(3)),
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"),
)
//_, args, _ := query.Sql()
//fmt.Println(query.Sql())
//fmt.Println(args[15])
fmt.Println(query.Sql())
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
var timeT = time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
func TestTimeExpressions(t *testing.T) {
query := AllTypes.SELECT(
Time(timeT.Clock()),
AllTypes.Time.EQ(AllTypes.Time),
AllTypes.Time.EQ(Time(23, 6, 6)),
AllTypes.Time.EQ(Time(22, 6, 6, 11)),
AllTypes.Time.EQ(Time(21, 6, 6, 11111)),
AllTypes.TimePtr.NOT_EQ(AllTypes.Time),
AllTypes.TimePtr.NOT_EQ(Time(20, 16, 6)),
AllTypes.Time.IS_DISTINCT_FROM(AllTypes.Time),
AllTypes.Time.IS_DISTINCT_FROM(Time(19, 26, 6)),
AllTypes.Time.IS_NOT_DISTINCT_FROM(AllTypes.Time),
AllTypes.Time.IS_NOT_DISTINCT_FROM(Time(18, 36, 6)),
AllTypes.Time.LT(AllTypes.Time),
AllTypes.Time.LT(Time(17, 46, 6)),
AllTypes.Time.LT_EQ(AllTypes.Time),
AllTypes.Time.LT_EQ(Time(16, 56, 56)),
AllTypes.Time.GT(AllTypes.Time),
AllTypes.Time.GT(Time(15, 16, 46)),
AllTypes.Time.GT_EQ(AllTypes.Time),
AllTypes.Time.GT_EQ(Time(14, 26, 36)),
CURRENT_TIME(),
CURRENT_TIME(3),
)
fmt.Println(query.Sql())
testutils.AssertStatementSql(t, query, `
SELECT ?,
all_types.time = all_types.time,
all_types.time = ?,
all_types.time = ?,
all_types.time = ?,
all_types.time_ptr != all_types.time,
all_types.time_ptr != ?,
NOT(all_types.time <=> all_types.time),
NOT(all_types.time <=> ?),
all_types.time <=> all_types.time,
all_types.time <=> ?,
all_types.time < all_types.time,
all_types.time < ?,
all_types.time <= all_types.time,
all_types.time <= ?,
all_types.time > all_types.time,
all_types.time > ?,
all_types.time >= all_types.time,
all_types.time >= ?,
CURRENT_TIME,
CURRENT_TIME(3)
FROM test_sample.all_types;
`, "20:34:58", "23:06:06", "22:06:06.011", "21:06:06.11111", "20:16:06",
"19:26:06", "18:36:06", "17:46:06", "16:56:56", "15:16:46", "14:26:36")
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
func TestDateExpressions(t *testing.T) {
query := AllTypes.SELECT(
Date(timeT.Date()),
AllTypes.Date.EQ(AllTypes.Date),
AllTypes.Date.EQ(Date(2019, 6, 6)),
AllTypes.DatePtr.NOT_EQ(AllTypes.Date),
AllTypes.DatePtr.NOT_EQ(Date(2019, 1, 6)),
AllTypes.Date.IS_DISTINCT_FROM(AllTypes.Date),
AllTypes.Date.IS_DISTINCT_FROM(Date(2019, 2, 6)),
AllTypes.Date.IS_NOT_DISTINCT_FROM(AllTypes.Date),
AllTypes.Date.IS_NOT_DISTINCT_FROM(Date(2019, 3, 6)),
AllTypes.Date.LT(AllTypes.Date),
AllTypes.Date.LT(Date(2019, 4, 6)),
AllTypes.Date.LT_EQ(AllTypes.Date),
AllTypes.Date.LT_EQ(Date(2019, 5, 5)),
AllTypes.Date.GT(AllTypes.Date),
AllTypes.Date.GT(Date(2019, 1, 4)),
AllTypes.Date.GT_EQ(AllTypes.Date),
AllTypes.Date.GT_EQ(Date(2019, 2, 3)),
CURRENT_DATE(),
)
//fmt.Println(query.Sql())
testutils.AssertStatementSql(t, query, `
SELECT ?,
all_types.date = all_types.date,
all_types.date = ?,
all_types.date_ptr != all_types.date,
all_types.date_ptr != ?,
NOT(all_types.date <=> all_types.date),
NOT(all_types.date <=> ?),
all_types.date <=> all_types.date,
all_types.date <=> ?,
all_types.date < all_types.date,
all_types.date < ?,
all_types.date <= all_types.date,
all_types.date <= ?,
all_types.date > all_types.date,
all_types.date > ?,
all_types.date >= all_types.date,
all_types.date >= ?,
CURRENT_DATE
FROM test_sample.all_types;
`)
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
func TestDateTimeExpressions(t *testing.T) {
var dateTime = DateTime(2019, 6, 6, 10, 2, 46)
query := AllTypes.SELECT(
AllTypes.DateTime.EQ(AllTypes.DateTime),
AllTypes.DateTime.EQ(dateTime),
AllTypes.DateTimePtr.NOT_EQ(AllTypes.DateTime),
AllTypes.DateTimePtr.NOT_EQ(DateTime(2019, 6, 6, 10, 2, 46, 1000)),
AllTypes.DateTime.IS_DISTINCT_FROM(AllTypes.DateTime),
AllTypes.DateTime.IS_DISTINCT_FROM(dateTime),
AllTypes.DateTime.IS_NOT_DISTINCT_FROM(AllTypes.DateTime),
AllTypes.DateTime.IS_NOT_DISTINCT_FROM(dateTime),
AllTypes.DateTime.LT(AllTypes.DateTime),
AllTypes.DateTime.LT(dateTime),
AllTypes.DateTime.LT_EQ(AllTypes.DateTime),
AllTypes.DateTime.LT_EQ(dateTime),
AllTypes.DateTime.GT(AllTypes.DateTime),
AllTypes.DateTime.GT(dateTime),
AllTypes.DateTime.GT_EQ(AllTypes.DateTime),
AllTypes.DateTime.GT_EQ(dateTime),
NOW(),
NOW(1),
)
fmt.Println(query.DebugSql())
testutils.AssertDebugStatementSql(t, query, `
SELECT all_types.date_time = all_types.date_time,
all_types.date_time = '2019-06-06 10:02:46',
all_types.date_time_ptr != all_types.date_time,
all_types.date_time_ptr != '2019-06-06 10:02:46.1000',
NOT(all_types.date_time <=> all_types.date_time),
NOT(all_types.date_time <=> '2019-06-06 10:02:46'),
all_types.date_time <=> all_types.date_time,
all_types.date_time <=> '2019-06-06 10:02:46',
all_types.date_time < all_types.date_time,
all_types.date_time < '2019-06-06 10:02:46',
all_types.date_time <= all_types.date_time,
all_types.date_time <= '2019-06-06 10:02:46',
all_types.date_time > all_types.date_time,
all_types.date_time > '2019-06-06 10:02:46',
all_types.date_time >= all_types.date_time,
all_types.date_time >= '2019-06-06 10:02:46',
NOW(),
NOW(1)
FROM test_sample.all_types;
`)
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
func TestTimestampExpressions(t *testing.T) {
var timestamp = Timestamp(2019, 6, 6, 10, 2, 46)
query := AllTypes.SELECT(
AllTypes.Timestamp.EQ(AllTypes.Timestamp),
AllTypes.Timestamp.EQ(timestamp),
AllTypes.TimestampPtr.NOT_EQ(AllTypes.Timestamp),
AllTypes.TimestampPtr.NOT_EQ(Timestamp(2019, 6, 6, 10, 2, 46, 1000)),
AllTypes.Timestamp.IS_DISTINCT_FROM(AllTypes.Timestamp),
AllTypes.Timestamp.IS_DISTINCT_FROM(timestamp),
AllTypes.Timestamp.IS_NOT_DISTINCT_FROM(AllTypes.Timestamp),
AllTypes.Timestamp.IS_NOT_DISTINCT_FROM(timestamp),
AllTypes.Timestamp.LT(AllTypes.Timestamp),
AllTypes.Timestamp.LT(timestamp),
AllTypes.Timestamp.LT_EQ(AllTypes.Timestamp),
AllTypes.Timestamp.LT_EQ(timestamp),
AllTypes.Timestamp.GT(AllTypes.Timestamp),
AllTypes.Timestamp.GT(timestamp),
AllTypes.Timestamp.GT_EQ(AllTypes.Timestamp),
AllTypes.Timestamp.GT_EQ(timestamp),
CURRENT_TIMESTAMP(),
CURRENT_TIMESTAMP(2),
)
fmt.Println(query.DebugSql())
testutils.AssertDebugStatementSql(t, query, `
SELECT all_types.timestamp = all_types.timestamp,
all_types.timestamp = '2019-06-06 10:02:46',
all_types.timestamp_ptr != all_types.timestamp,
all_types.timestamp_ptr != '2019-06-06 10:02:46.1000',
NOT(all_types.timestamp <=> all_types.timestamp),
NOT(all_types.timestamp <=> '2019-06-06 10:02:46'),
all_types.timestamp <=> all_types.timestamp,
all_types.timestamp <=> '2019-06-06 10:02:46',
all_types.timestamp < all_types.timestamp,
all_types.timestamp < '2019-06-06 10:02:46',
all_types.timestamp <= all_types.timestamp,
all_types.timestamp <= '2019-06-06 10:02:46',
all_types.timestamp > all_types.timestamp,
all_types.timestamp > '2019-06-06 10:02:46',
all_types.timestamp >= all_types.timestamp,
all_types.timestamp >= '2019-06-06 10:02:46',
CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP(2)
FROM test_sample.all_types;
`)
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
var allTypesJson = ` var allTypesJson = `
[ [
{ {
@ -431,6 +749,8 @@ var allTypesJson = `
"RealPtr": 5.55, "RealPtr": 5.55,
"Bit": "\u0000\u0003", "Bit": "\u0000\u0003",
"BitPtr": "\u0000\u0003", "BitPtr": "\u0000\u0003",
"Time": "0000-01-01T10:11:12Z",
"TimePtr": "0000-01-01T10:11:12Z",
"Date": "2008-07-04T00:00:00Z", "Date": "2008-07-04T00:00:00Z",
"DatePtr": "2008-07-04T00:00:00Z", "DatePtr": "2008-07-04T00:00:00Z",
"DateTime": "2011-12-18T13:17:17Z", "DateTime": "2011-12-18T13:17:17Z",
@ -441,8 +761,8 @@ var allTypesJson = `
"YearPtr": 2004, "YearPtr": 2004,
"Char": "char", "Char": "char",
"CharPtr": "char", "CharPtr": "char",
"Varchar": "varchar", "VarChar": "varchar",
"VarcharPtr": "varchar", "VarCharPtr": "varchar",
"Binary": "YmluYXJ5AAAAAAAAAAAAAAAAAAA=", "Binary": "YmluYXJ5AAAAAAAAAAAAAAAAAAA=",
"BinaryPtr": "YmluYXJ5AAAAAAAAAAAAAAAAAAA=", "BinaryPtr": "YmluYXJ5AAAAAAAAAAAAAAAAAAA=",
"VarBinary": "dmFyYmluYXJ5", "VarBinary": "dmFyYmluYXJ5",
@ -493,6 +813,8 @@ var allTypesJson = `
"RealPtr": null, "RealPtr": null,
"Bit": "\u0000\u0003", "Bit": "\u0000\u0003",
"BitPtr": null, "BitPtr": null,
"Time": "0000-01-01T10:11:12Z",
"TimePtr": null,
"Date": "2008-07-04T00:00:00Z", "Date": "2008-07-04T00:00:00Z",
"DatePtr": null, "DatePtr": null,
"DateTime": "2011-12-18T13:17:17Z", "DateTime": "2011-12-18T13:17:17Z",
@ -503,8 +825,8 @@ var allTypesJson = `
"YearPtr": null, "YearPtr": null,
"Char": "char", "Char": "char",
"CharPtr": null, "CharPtr": null,
"Varchar": "varchar", "VarChar": "varchar",
"VarcharPtr": null, "VarCharPtr": null,
"Binary": "YmluYXJ5AAAAAAAAAAAAAAAAAAA=", "Binary": "YmluYXJ5AAAAAAAAAAAAAAAAAAA=",
"BinaryPtr": null, "BinaryPtr": null,
"VarBinary": "dmFyYmluYXJ5", "VarBinary": "dmFyYmluYXJ5",

View file

@ -127,6 +127,7 @@ func TestExpressionCast(t *testing.T) {
postgres.CAST(String("111")).AS_BIGINT(), postgres.CAST(String("111")).AS_BIGINT(),
postgres.CAST(String("11.23")).AS_NUMERIC(30, 10), postgres.CAST(String("11.23")).AS_NUMERIC(30, 10),
postgres.CAST(String("11.23")).AS_NUMERIC(30), postgres.CAST(String("11.23")).AS_NUMERIC(30),
postgres.CAST(String("11.23")).AS_NUMERIC(),
postgres.CAST(String("11.23")).AS_REAL(), postgres.CAST(String("11.23")).AS_REAL(),
postgres.CAST(String("11.23")).AS_DOUBLE(), postgres.CAST(String("11.23")).AS_DOUBLE(),
postgres.CAST(Int(234)).AS_TEXT(), postgres.CAST(Int(234)).AS_TEXT(),
@ -162,45 +163,56 @@ func TestExpressionCast(t *testing.T) {
func TestStringOperators(t *testing.T) { func TestStringOperators(t *testing.T) {
query := AllTypes.SELECT( query := AllTypes.SELECT(
AllTypes.Text.EQ(AllTypes.Character), AllTypes.Text.EQ(AllTypes.Char),
AllTypes.Text.EQ(String("Text")), AllTypes.Text.EQ(String("Text")),
AllTypes.Text.NOT_EQ(AllTypes.CharacterVaryingPtr), AllTypes.Text.NOT_EQ(AllTypes.VarCharPtr),
AllTypes.Text.NOT_EQ(String("Text")), AllTypes.Text.NOT_EQ(String("Text")),
AllTypes.Text.GT(AllTypes.Text), AllTypes.Text.GT(AllTypes.Text),
AllTypes.Text.GT(String("Text")), AllTypes.Text.GT(String("Text")),
AllTypes.Text.GT_EQ(AllTypes.TextPtr), AllTypes.Text.GT_EQ(AllTypes.TextPtr),
AllTypes.Text.GT_EQ(String("Text")), AllTypes.Text.GT_EQ(String("Text")),
AllTypes.Text.LT(AllTypes.Character), AllTypes.Text.LT(AllTypes.Char),
AllTypes.Text.LT(String("Text")), AllTypes.Text.LT(String("Text")),
AllTypes.Text.LT_EQ(AllTypes.CharacterVaryingPtr), AllTypes.Text.LT_EQ(AllTypes.VarChar),
AllTypes.Text.LT_EQ(String("Text")), AllTypes.Text.LT_EQ(String("Text")),
AllTypes.Text.CONCAT(String("text2")), AllTypes.Text.CONCAT(String("text2")),
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.SIMILAR_TO(String("%(b|d)%")), AllTypes.Text.REGEXP_LIKE(String("aba")),
AllTypes.Text.NOT_SIMILAR_TO(String("(b|c)%")), AllTypes.Text.REGEXP_LIKE(String("aba"), "c"),
AllTypes.Text.REGEXP_LIKE(String("aba"), "i"),
BIT_LENGTH(AllTypes.Text), BIT_LENGTH(String("length")),
CHAR_LENGTH(AllTypes.Character), CHAR_LENGTH(AllTypes.Char),
CHAR_LENGTH(String("length")),
OCTET_LENGTH(AllTypes.Text), OCTET_LENGTH(AllTypes.Text),
LOWER(AllTypes.CharacterVaryingPtr), OCTET_LENGTH(String("length")),
UPPER(AllTypes.Character), LOWER(AllTypes.VarCharPtr),
BTRIM(AllTypes.CharacterVarying), LOWER(String("length")),
BTRIM(AllTypes.CharacterVarying, String("AA")), UPPER(AllTypes.Char),
LTRIM(AllTypes.CharacterVarying), UPPER(String("upper")),
LTRIM(AllTypes.CharacterVarying, String("A")), BTRIM(AllTypes.VarChar),
RTRIM(AllTypes.CharacterVarying), BTRIM(String("btrim")),
RTRIM(AllTypes.CharacterVarying, String("B")), BTRIM(AllTypes.VarChar, String("AA")),
BTRIM(String("btrim"), String("AA")),
LTRIM(AllTypes.VarChar),
LTRIM(String("ltrim")),
LTRIM(AllTypes.VarChar, String("A")),
LTRIM(String("Ltrim"), String("A")),
RTRIM(String("rtrim")),
RTRIM(AllTypes.VarChar, String("B")),
CHR(Int(65)), CHR(Int(65)),
//CONCAT(String("string1"), Int(1), Float(11.12)), CONCAT(AllTypes.VarCharPtr, AllTypes.VarCharPtr, String("aaa"), Int(1)),
//CONCAT_WS(String("string1"), Int(1), Float(11.12)), CONCAT(Bool(false), Int(1), Float(22.2), String("test test")),
CONVERT(String("text_in_utf8"), String("UTF8"), String("LATIN1")), CONCAT_WS(String("string1"), Int(1), Float(11.22), String("bytea"), Bool(false)), //Float(11.12)),
CONVERT(String("bytea"), String("UTF8"), String("LATIN1")),
CONVERT(AllTypes.Bytea, String("UTF8"), String("LATIN1")),
CONVERT_FROM(String("text_in_utf8"), String("UTF8")), CONVERT_FROM(String("text_in_utf8"), String("UTF8")),
CONVERT_TO(String("text_in_utf8"), String("UTF8")), CONVERT_TO(String("text_in_utf8"), String("UTF8")),
ENCODE(String("123\000\001"), String("base64")), ENCODE(String("123\000\001"), String("base64")),
DECODE(String("MTIzAAE="), String("base64")), DECODE(String("MTIzAAE="), String("base64")),
//FORMAT(String("Hello %s, %1$s"), String("World")), FORMAT(String("Hello %s, %1$s"), String("World")),
INITCAP(String("hi THOMAS")), INITCAP(String("hi THOMAS")),
LEFT(String("abcde"), Int(2)), LEFT(String("abcde"), Int(2)),
RIGHT(String("abcde"), Int(2)), RIGHT(String("abcde"), Int(2)),
@ -210,13 +222,13 @@ func TestStringOperators(t *testing.T) {
LPAD(String("Hi"), Int(5), String("xy")), LPAD(String("Hi"), Int(5), String("xy")),
RPAD(String("Hi"), Int(5)), RPAD(String("Hi"), Int(5)),
RPAD(String("Hi"), Int(5), String("xy")), RPAD(String("Hi"), Int(5), String("xy")),
MD5(AllTypes.CharacterVarying), MD5(AllTypes.VarChar),
REPEAT(AllTypes.Text, Int(33)), REPEAT(AllTypes.Text, Int(33)),
REPLACE(AllTypes.Character, String("BA"), String("AB")), REPLACE(AllTypes.Char, String("BA"), String("AB")),
REVERSE(AllTypes.CharacterVarying), REVERSE(AllTypes.VarChar),
STRPOS(AllTypes.Text, String("A")), STRPOS(AllTypes.Text, String("A")),
SUBSTR(AllTypes.CharacterPtr, Int(3)), SUBSTR(AllTypes.Char, Int(3)),
SUBSTR(AllTypes.CharacterPtr, Int(3), Int(2)), SUBSTR(AllTypes.CharPtr, Int(3), Int(2)),
TO_HEX(AllTypes.IntegerPtr), TO_HEX(AllTypes.IntegerPtr),
) )
@ -224,7 +236,7 @@ func TestStringOperators(t *testing.T) {
//fmt.Println(query.Sql()) //fmt.Println(query.Sql())
//fmt.Println(args[15]) //fmt.Println(args[15])
//fmt.Println(query.DebugSql()) fmt.Println(query.Sql())
err := query.Query(db, &struct{}{}) err := query.Query(db, &struct{}{})
@ -459,7 +471,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(MINUSi(AllTypes.SmallInt)).AS("bit_not_1"), BIT_NOT(MINUSi(AllTypes.SmallInt)).AS("bit_not_1"),
BIT_NOT(MINUSi(Int(11, true))).AS("bit_not_2"), BIT_NOT(MINUSi(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"),
@ -513,8 +525,8 @@ SELECT all_types.big_int AS "all_types.big_int",
(all_types.small_int | $16) AS "bit or 2", (all_types.small_int | $16) AS "bit or 2",
(all_types.small_int # all_types.small_int) AS "bit xor 1", (all_types.small_int # all_types.small_int) AS "bit xor 1",
(all_types.small_int # $17) AS "bit xor 2", (all_types.small_int # $17) AS "bit xor 2",
(~ (- all_types.small_int)) AS "bit_not_1", (~ all_types.small_int) AS "bit_not_1",
(~ (- 11)) AS "bit_not_2", (~ 11) AS "bit_not_2",
(all_types.small_int << (all_types.small_int / $18)) AS "bit shift left 1", (all_types.small_int << (all_types.small_int / $18)) AS "bit shift left 1",
(all_types.small_int << $19) AS "bit shift left 2", (all_types.small_int << $19) AS "bit shift left 2",
(all_types.small_int >> (all_types.small_int / $20)) AS "bit shift right 1", (all_types.small_int >> (all_types.small_int / $20)) AS "bit shift right 1",
@ -539,7 +551,7 @@ LIMIT $22;
testutils.AssertJSONFile(t, dest, "./testdata/common/int_operators.json") testutils.AssertJSONFile(t, dest, "./testdata/common/int_operators.json")
} }
func TestTimeOperators(t *testing.T) { func TestTimeExpression(t *testing.T) {
query := AllTypes.SELECT( query := AllTypes.SELECT(
AllTypes.Time.EQ(AllTypes.Time), AllTypes.Time.EQ(AllTypes.Time),
AllTypes.Time.EQ(Time(23, 6, 6, 1)), AllTypes.Time.EQ(Time(23, 6, 6, 1)),
@ -799,10 +811,10 @@ var allTypesRow0 = model.AllTypes{
Bigserial: 1, Bigserial: 1,
//MoneyPtr: nil, //MoneyPtr: nil,
//Money: //Money:
CharacterVaryingPtr: StringPtr("ABBA"), VarCharPtr: StringPtr("ABBA"),
CharacterVarying: "ABBA", VarChar: "ABBA",
CharacterPtr: StringPtr("JOHN "), CharPtr: StringPtr("JOHN "),
Character: "JOHN ", Char: "JOHN ",
TextPtr: StringPtr("Some text"), TextPtr: StringPtr("Some text"),
Text: "Some text", Text: "Some text",
ByteaPtr: ByteArrayPtr([]byte("bytea")), ByteaPtr: ByteArrayPtr([]byte("bytea")),
@ -865,10 +877,10 @@ var allTypesRow1 = model.AllTypes{
Bigserial: 2, Bigserial: 2,
//MoneyPtr: nil, //MoneyPtr: nil,
//Money: //Money:
CharacterVaryingPtr: nil, VarCharPtr: nil,
CharacterVarying: "ABBA", VarChar: "ABBA",
CharacterPtr: nil, CharPtr: nil,
Character: "JOHN ", Char: "JOHN ",
TextPtr: nil, TextPtr: nil,
Text: "Some text", Text: "Some text",
ByteaPtr: nil, ByteaPtr: nil,

View file

@ -1273,8 +1273,6 @@ func TestAllSetOperators(t *testing.T) {
UNION_ALL, UNION_ALL,
INTERSECT, INTERSECT,
INTERSECT_ALL, INTERSECT_ALL,
//EXCEPT,
//EXCEPT_ALL,
} }
expectedDestLen := []int{ expectedDestLen := []int{