Fix parentheses wrap on binary operators.
This commit is contained in:
parent
2b6288d317
commit
cf022ab68d
19 changed files with 99 additions and 97 deletions
|
|
@ -7,13 +7,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBoolExpressionEQ(t *testing.T) {
|
func TestBoolExpressionEQ(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColBool.EQ(table2ColBool)), "table1.colBool = table2.colBool")
|
assert.Equal(t, getTestSerialize(t, table1ColBool.EQ(table2ColBool)), "(table1.colBool = table2.colBool)")
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColBool.AND(table2ColBool).EQ(table2ColBool)), "table1.colBool AND table2.colBool = table2.colBool")
|
assert.Equal(t, getTestSerialize(t, table1ColBool.AND(table2ColBool).EQ(table2ColBool)), "((table1.colBool AND table2.colBool) = table2.colBool)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoolExpressionNOT_EQ(t *testing.T) {
|
func TestBoolExpressionNOT_EQ(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColBool.NOT_EQ(table2ColBool)), "table1.colBool != table2.colBool")
|
assert.Equal(t, getTestSerialize(t, table1ColBool.NOT_EQ(table2ColBool)), "(table1.colBool != table2.colBool)")
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColBool.AND(table2ColBool).NOT_EQ(table2ColBool)), "table1.colBool AND table2.colBool != table2.colBool")
|
assert.Equal(t, getTestSerialize(t, table1ColBool.AND(table2ColBool).NOT_EQ(table2ColBool)), "((table1.colBool AND table2.colBool) != table2.colBool)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoolExpressionIS_TRUE(t *testing.T) {
|
func TestBoolExpressionIS_TRUE(t *testing.T) {
|
||||||
|
|
@ -48,7 +48,7 @@ func TestBinaryExpression(t *testing.T) {
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, out.buff.String(), "$1 = $2")
|
assert.Equal(t, out.buff.String(), "($1 = $2)")
|
||||||
assert.Equal(t, len(out.args), 2)
|
assert.Equal(t, len(out.args), 2)
|
||||||
|
|
||||||
t.Run("alias", func(t *testing.T) {
|
t.Run("alias", func(t *testing.T) {
|
||||||
|
|
@ -58,7 +58,7 @@ func TestBinaryExpression(t *testing.T) {
|
||||||
err := alias.serializeForProjection(select_statement, &out)
|
err := alias.serializeForProjection(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), `$1 = $2 AS "alias_eq_expression"`)
|
assert.Equal(t, out.buff.String(), `($1 = $2) AS "alias_eq_expression"`)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("and", func(t *testing.T) {
|
t.Run("and", func(t *testing.T) {
|
||||||
|
|
@ -68,7 +68,7 @@ func TestBinaryExpression(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), `($1 = $2 AND $3 = $4)`)
|
assert.Equal(t, out.buff.String(), `(($1 = $2) AND ($3 = $4))`)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("or", func(t *testing.T) {
|
t.Run("or", func(t *testing.T) {
|
||||||
|
|
@ -78,7 +78,7 @@ func TestBinaryExpression(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), `($1 = $2 OR $3 = $4)`)
|
assert.Equal(t, out.buff.String(), `(($1 = $2) OR ($3 = $4))`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ func TestUnaryExpression(t *testing.T) {
|
||||||
err := notExpression.serialize(select_statement, &out)
|
err := notExpression.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), "NOT $1 = $2")
|
assert.Equal(t, out.buff.String(), "NOT ($1 = $2)")
|
||||||
|
|
||||||
t.Run("alias", func(t *testing.T) {
|
t.Run("alias", func(t *testing.T) {
|
||||||
alias := notExpression.AS("alias_not_expression")
|
alias := notExpression.AS("alias_not_expression")
|
||||||
|
|
@ -98,7 +98,7 @@ func TestUnaryExpression(t *testing.T) {
|
||||||
err := alias.serializeForProjection(select_statement, &out)
|
err := alias.serializeForProjection(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), `NOT $1 = $2 AS "alias_not_expression"`)
|
assert.Equal(t, out.buff.String(), `NOT ($1 = $2) AS "alias_not_expression"`)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("and", func(t *testing.T) {
|
t.Run("and", func(t *testing.T) {
|
||||||
|
|
@ -108,7 +108,7 @@ func TestUnaryExpression(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), `(NOT $1 = $2 AND $3 = $4)`)
|
assert.Equal(t, out.buff.String(), `(NOT ($1 = $2) AND ($3 = $4))`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,7 +119,7 @@ func TestUnaryIsTrueExpression(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), "$1 = $2 IS TRUE")
|
assert.Equal(t, out.buff.String(), "($1 = $2) IS TRUE")
|
||||||
|
|
||||||
t.Run("and", func(t *testing.T) {
|
t.Run("and", func(t *testing.T) {
|
||||||
exp := exp.AND(EQ(Literal(4), Literal(5)))
|
exp := exp.AND(EQ(Literal(4), Literal(5)))
|
||||||
|
|
@ -128,7 +128,7 @@ func TestUnaryIsTrueExpression(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), `($1 = $2 IS TRUE AND $3 = $4)`)
|
assert.Equal(t, out.buff.String(), `(($1 = $2) IS TRUE AND ($3 = $4))`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,7 +170,7 @@ func TestIn(t *testing.T) {
|
||||||
query := Literal(1.11).IN(table1.SELECT(table1Col1))
|
query := Literal(1.11).IN(table1.SELECT(table1Col1))
|
||||||
|
|
||||||
out := queryData{}
|
out := queryData{}
|
||||||
err := query.serialize(select_statement, &out)
|
err := query.serialize(select_statement, &out, NO_WRAP)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
fmt.Println(out.buff.String())
|
fmt.Println(out.buff.String())
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,24 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type serializeOption int
|
||||||
|
|
||||||
|
const (
|
||||||
|
NO_WRAP serializeOption = iota
|
||||||
|
)
|
||||||
|
|
||||||
type clause interface {
|
type clause interface {
|
||||||
serialize(statement statementType, out *queryData) error
|
serialize(statement statementType, out *queryData, options ...serializeOption) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func contains(options []serializeOption, option serializeOption) bool {
|
||||||
|
for _, opt := range options {
|
||||||
|
if opt == option {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type queryData struct {
|
type queryData struct {
|
||||||
|
|
@ -65,7 +81,7 @@ func (q *queryData) writeWhere(statement statementType, where expression) error
|
||||||
q.writeString("WHERE")
|
q.writeString("WHERE")
|
||||||
|
|
||||||
q.increaseIdent()
|
q.increaseIdent()
|
||||||
err := where.serialize(statement, q)
|
err := where.serialize(statement, q, NO_WRAP)
|
||||||
q.decreaseIdent()
|
q.decreaseIdent()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
@ -98,7 +114,7 @@ func (q *queryData) writeHaving(statement statementType, having expression) erro
|
||||||
q.writeString("HAVING")
|
q.writeString("HAVING")
|
||||||
|
|
||||||
q.increaseIdent()
|
q.increaseIdent()
|
||||||
err := having.serialize(statement, q)
|
err := having.serialize(statement, q, NO_WRAP)
|
||||||
q.decreaseIdent()
|
q.decreaseIdent()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ func (c *baseColumn) serializeAsOrderBy(statement statementType, out *queryData)
|
||||||
return c.serialize(statement, out)
|
return c.serialize(statement, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c baseColumn) serialize(statement statementType, out *queryData) error {
|
func (c baseColumn) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
|
|
||||||
columnRef := ""
|
columnRef := ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,21 +83,7 @@ func newBinaryExpression(lhs, rhs expression, operator string, parent ...express
|
||||||
return binaryExpression
|
return binaryExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSimpleOperand(expression expression) bool {
|
func (c *binaryOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if _, ok := expression.(*literalExpression); ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if _, ok := expression.(column); ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if _, ok := expression.(*floatFunc); ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *binaryOpExpression) serialize(statement statementType, out *queryData) error {
|
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return errors.New("Binary expression is nil.")
|
return errors.New("Binary expression is nil.")
|
||||||
}
|
}
|
||||||
|
|
@ -108,7 +94,7 @@ func (c *binaryOpExpression) serialize(statement statementType, out *queryData)
|
||||||
return errors.Newf("nil rhs.")
|
return errors.Newf("nil rhs.")
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap := !isSimpleOperand(c.lhs) && !isSimpleOperand(c.rhs)
|
wrap := !contains(options, NO_WRAP)
|
||||||
|
|
||||||
if wrap {
|
if wrap {
|
||||||
out.writeString("(")
|
out.writeString("(")
|
||||||
|
|
@ -146,7 +132,7 @@ func newPrefixExpression(expression expression, operator string) prefixOpExpress
|
||||||
return prefixExpression
|
return prefixExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *prefixOpExpression) serialize(statement statementType, out *queryData) error {
|
func (p *prefixOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return errors.New("Prefix expression is nil.")
|
return errors.New("Prefix expression is nil.")
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +164,7 @@ func newPostfixOpExpression(expression expression, operator string) postfixOpExp
|
||||||
return postfixOpExpression
|
return postfixOpExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *postfixOpExpression) serialize(statement statementType, out *queryData) error {
|
func (p *postfixOpExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return errors.New("Postifx operator expression is nil.")
|
return errors.New("Postifx operator expression is nil.")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ type intervalExpression struct {
|
||||||
|
|
||||||
const intervalSep = ":"
|
const intervalSep = ":"
|
||||||
|
|
||||||
func (c *intervalExpression) serialize(statement statementType, out *queryData) error {
|
func (c *intervalExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
out.writeString("INTERVAL '")
|
out.writeString("INTERVAL '")
|
||||||
|
|
||||||
duration := c.duration
|
duration := c.duration
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ func (e *expressionTableImpl) RefStringColumn(column column) *StringColumn {
|
||||||
return strColumn
|
return strColumn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *expressionTableImpl) serialize(statement statementType, out *queryData) error {
|
func (e *expressionTableImpl) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return errors.New("Expression table is nil. ")
|
return errors.New("Expression table is nil. ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,20 @@ import (
|
||||||
|
|
||||||
func TestExpressionIS_NULL(t *testing.T) {
|
func TestExpressionIS_NULL(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table2Col3.IS_NULL()), "table2.col3 IS NULL")
|
assert.Equal(t, getTestSerialize(t, table2Col3.IS_NULL()), "table2.col3 IS NULL")
|
||||||
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_NULL()), "table2.col3 + table2.col3 IS NULL")
|
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_NULL()), "(table2.col3 + table2.col3) IS NULL")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExpressionIS_NOT_NULL(t *testing.T) {
|
func TestExpressionIS_NOT_NULL(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table2Col3.IS_NOT_NULL()), "table2.col3 IS NOT NULL")
|
assert.Equal(t, getTestSerialize(t, table2Col3.IS_NOT_NULL()), "table2.col3 IS NOT NULL")
|
||||||
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_NULL()), "table2.col3 + table2.col3 IS NOT NULL")
|
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_NULL()), "(table2.col3 + table2.col3) IS NOT NULL")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExpressionIS_DISTINCT_FROM(t *testing.T) {
|
func TestExpressionIS_DISTINCT_FROM(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table2Col3.IS_DISTINCT_FROM(table2Col4)), "table2.col3 IS DISTINCT FROM table2.col4")
|
assert.Equal(t, getTestSerialize(t, table2Col3.IS_DISTINCT_FROM(table2Col4)), "(table2.col3 IS DISTINCT FROM table2.col4)")
|
||||||
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_DISTINCT_FROM(Int(23))), "(table2.col3 + table2.col3 IS DISTINCT FROM $1)")
|
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_DISTINCT_FROM(Int(23))), "((table2.col3 + table2.col3) IS DISTINCT FROM $1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
|
func TestExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table2Col3.IS_NOT_DISTINCT_FROM(table2Col4)), "table2.col3 IS NOT DISTINCT FROM table2.col4")
|
assert.Equal(t, getTestSerialize(t, table2Col3.IS_NOT_DISTINCT_FROM(table2Col4)), "(table2.col3 IS NOT DISTINCT FROM table2.col4)")
|
||||||
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_DISTINCT_FROM(Int(23))), "(table2.col3 + table2.col3 IS NOT DISTINCT FROM $1)")
|
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_DISTINCT_FROM(Int(23))), "((table2.col3 + table2.col3) IS NOT DISTINCT FROM $1)")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ func newFloatExpressionWrap(expression expression) FloatExpression {
|
||||||
return &floatExpressionWrap
|
return &floatExpressionWrap
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *floatExpressionWrapper) serialize(statement statementType, out *queryData) error {
|
func (n *floatExpressionWrapper) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return errors.New("Float expression wrapper is nil. ")
|
return errors.New("Float expression wrapper is nil. ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,33 +6,33 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFloatExpressionEQColumn(t *testing.T) {
|
func TestFloatExpressionEQColumn(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1Col1.EQ(table2Col3)), "table1.col1 = table2.col3")
|
assert.Equal(t, getTestSerialize(t, table1Col1.EQ(table2Col3)), "(table1.col1 = table2.col3)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatExpressionEQInt(t *testing.T) {
|
func TestFloatExpressionEQInt(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1Col1.EQ(Int(11))), "table1.col1 = $1")
|
assert.Equal(t, getTestSerialize(t, table1Col1.EQ(Int(11))), "(table1.col1 = $1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatExpressionEQFloat(t *testing.T) {
|
func TestFloatExpressionEQFloat(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1Col1.EQ(Int(22))), "table1.col1 = $1")
|
assert.Equal(t, getTestSerialize(t, table1Col1.EQ(Int(22))), "(table1.col1 = $1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatExpressionNOT_EQ(t *testing.T) {
|
func TestFloatExpressionNOT_EQ(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1Col1.NOT_EQ(table2Col3)), "table1.col1 != table2.col3")
|
assert.Equal(t, getTestSerialize(t, table1Col1.NOT_EQ(table2Col3)), "(table1.col1 != table2.col3)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatExpressionGT(t *testing.T) {
|
func TestFloatExpressionGT(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1Col1.GT(table2Col3)), "table1.col1 > table2.col3")
|
assert.Equal(t, getTestSerialize(t, table1Col1.GT(table2Col3)), "(table1.col1 > table2.col3)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatExpressionGT_EQ(t *testing.T) {
|
func TestFloatExpressionGT_EQ(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1Col1.GT_EQ(table2Col3)), "table1.col1 >= table2.col3")
|
assert.Equal(t, getTestSerialize(t, table1Col1.GT_EQ(table2Col3)), "(table1.col1 >= table2.col3)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatExpressionLT(t *testing.T) {
|
func TestFloatExpressionLT(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1Col1.LT(table2Col3)), "table1.col1 < table2.col3")
|
assert.Equal(t, getTestSerialize(t, table1Col1.LT(table2Col3)), "(table1.col1 < table2.col3)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatExpressionLT_EQ(t *testing.T) {
|
func TestFloatExpressionLT_EQ(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1Col1.LT_EQ(table2Col3)), "table1.col1 <= table2.col3")
|
assert.Equal(t, getTestSerialize(t, table1Col1.LT_EQ(table2Col3)), "(table1.col1 <= table2.col3)")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ func newFunc(name string, expressions []expression, parent expression) *funcExpr
|
||||||
return funcExp
|
return funcExp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *funcExpressionImpl) serialize(statement statementType, out *queryData) error {
|
func (f *funcExpressionImpl) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return errors.New("Function expression is nil. ")
|
return errors.New("Function expression is nil. ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const (
|
||||||
|
|
||||||
type keywordClause string
|
type keywordClause string
|
||||||
|
|
||||||
func (k keywordClause) serialize(statement statementType, out *queryData) error {
|
func (k keywordClause) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
out.writeString(string(k))
|
out.writeString(string(k))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ func Literal(value interface{}) *literalExpression {
|
||||||
return &exp
|
return &exp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l literalExpression) serialize(statement statementType, out *queryData) error {
|
func (l literalExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
out.insertArgument(l.value)
|
out.insertArgument(l.value)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ func (c *caseOperatorImpl) ELSE(els expression) caseOperatorExpression {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *caseOperatorImpl) serialize(statement statementType, out *queryData) error {
|
func (c *caseOperatorImpl) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return errors.New("Case expression is nil. ")
|
return errors.New("Case expression is nil. ")
|
||||||
}
|
}
|
||||||
|
|
@ -174,14 +174,14 @@ func (c *caseOperatorImpl) serialize(statement statementType, out *queryData) er
|
||||||
|
|
||||||
for i, when := range c.when {
|
for i, when := range c.when {
|
||||||
out.writeString("WHEN")
|
out.writeString("WHEN")
|
||||||
err := when.serialize(statement, out)
|
err := when.serialize(statement, out, NO_WRAP)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
out.writeString("THEN")
|
out.writeString("THEN")
|
||||||
err = c.then[i].serialize(statement, out)
|
err = c.then[i].serialize(statement, out, NO_WRAP)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -190,7 +190,7 @@ func (c *caseOperatorImpl) serialize(statement statementType, out *queryData) er
|
||||||
|
|
||||||
if c.els != nil {
|
if c.els != nil {
|
||||||
out.writeString("ELSE")
|
out.writeString("ELSE")
|
||||||
err := c.els.serialize(statement, out)
|
err := c.els.serialize(statement, out, NO_WRAP)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ func (s *selectStatementImpl) FROM(table readableTable) selectStatement {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *selectStatementImpl) serialize(statement statementType, out *queryData) error {
|
func (s *selectStatementImpl) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return errors.New("Select statement is nil. ")
|
return errors.New("Select statement is nil. ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ func (us *setStatementImpl) AsTable(alias string) expressionTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *setStatementImpl) serialize(statement statementType, out *queryData) error {
|
func (s *setStatementImpl) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return errors.New("Set statement is nil. ")
|
return errors.New("Set statement is nil. ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ func TestStringEQColumn(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), "table3.col2 = table2.colStr")
|
assert.Equal(t, out.buff.String(), "(table3.col2 = table2.colStr)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringEQString(t *testing.T) {
|
func TestStringEQString(t *testing.T) {
|
||||||
|
|
@ -22,7 +22,7 @@ func TestStringEQString(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), "table3.col2 = $1")
|
assert.Equal(t, out.buff.String(), "(table3.col2 = $1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringNOT_EQ(t *testing.T) {
|
func TestStringNOT_EQ(t *testing.T) {
|
||||||
|
|
@ -32,7 +32,7 @@ func TestStringNOT_EQ(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), "table3.col2 != table2.colStr")
|
assert.Equal(t, out.buff.String(), "(table3.col2 != table2.colStr)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringGT(t *testing.T) {
|
func TestStringGT(t *testing.T) {
|
||||||
|
|
@ -42,7 +42,7 @@ func TestStringGT(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), "table3.col2 > table2.colStr")
|
assert.Equal(t, out.buff.String(), "(table3.col2 > table2.colStr)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringGT_EQ(t *testing.T) {
|
func TestStringGT_EQ(t *testing.T) {
|
||||||
|
|
@ -52,7 +52,7 @@ func TestStringGT_EQ(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), "table3.col2 >= table2.colStr")
|
assert.Equal(t, out.buff.String(), "(table3.col2 >= table2.colStr)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringLT(t *testing.T) {
|
func TestStringLT(t *testing.T) {
|
||||||
|
|
@ -62,7 +62,7 @@ func TestStringLT(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), "table3.col2 < table2.colStr")
|
assert.Equal(t, out.buff.String(), "(table3.col2 < table2.colStr)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringLT_EQ(t *testing.T) {
|
func TestStringLT_EQ(t *testing.T) {
|
||||||
|
|
@ -72,5 +72,5 @@ func TestStringLT_EQ(t *testing.T) {
|
||||||
err := exp.serialize(select_statement, &out)
|
err := exp.serialize(select_statement, &out)
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, out.buff.String(), "table3.col2 <= table2.colStr")
|
assert.Equal(t, out.buff.String(), "(table3.col2 <= table2.colStr)")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ func (t *Table) Columns() []column {
|
||||||
|
|
||||||
// Generates the sql string for the current tableName expression. Note: the
|
// Generates the sql string for the current tableName expression. Note: the
|
||||||
// generated string may not be a valid/executable sql Statement.
|
// generated string may not be a valid/executable sql Statement.
|
||||||
func (t *Table) serialize(statement statementType, out *queryData) error {
|
func (t *Table) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return errors.Newf("Table is nil. ")
|
return errors.Newf("Table is nil. ")
|
||||||
}
|
}
|
||||||
|
|
@ -271,7 +271,7 @@ func (t *joinTable) Column(name string) column {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *joinTable) serialize(statement statementType, out *queryData) (err error) {
|
func (t *joinTable) serialize(statement statementType, out *queryData, options ...serializeOption) (err error) {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return errors.New("Join table is nil. ")
|
return errors.New("Join table is nil. ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,31 +6,31 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTimeExpressionEQ(t *testing.T) {
|
func TestTimeExpressionEQ(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.EQ(table2ColTime)), "table1.colTime = table2.colTime")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.EQ(table2ColTime)), "(table1.colTime = table2.colTime)")
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.EQ(Time(10, 20, 0, 0))), "table1.colTime = $1")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.EQ(Time(10, 20, 0, 0))), "(table1.colTime = $1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionNOT_EQ(t *testing.T) {
|
func TestTimeExpressionNOT_EQ(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.NOT_EQ(table2ColTime)), "table1.colTime != table2.colTime")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.NOT_EQ(table2ColTime)), "(table1.colTime != table2.colTime)")
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.NOT_EQ(Time(10, 20, 0, 0))), "table1.colTime != $1")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.NOT_EQ(Time(10, 20, 0, 0))), "(table1.colTime != $1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionLT(t *testing.T) {
|
func TestTimeExpressionLT(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.LT(table2ColTime)), "table1.colTime < table2.colTime")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.LT(table2ColTime)), "(table1.colTime < table2.colTime)")
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.LT(Time(10, 20, 0, 0))), "table1.colTime < $1")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.LT(Time(10, 20, 0, 0))), "(table1.colTime < $1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionLT_EQ(t *testing.T) {
|
func TestTimeExpressionLT_EQ(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.LT_EQ(table2ColTime)), "table1.colTime <= table2.colTime")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.LT_EQ(table2ColTime)), "(table1.colTime <= table2.colTime)")
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.LT_EQ(Time(10, 20, 0, 0))), "table1.colTime <= $1")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.LT_EQ(Time(10, 20, 0, 0))), "(table1.colTime <= $1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionGT(t *testing.T) {
|
func TestTimeExpressionGT(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.GT(table2ColTime)), "table1.colTime > table2.colTime")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.GT(table2ColTime)), "(table1.colTime > table2.colTime)")
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.GT(Time(10, 20, 0, 0))), "table1.colTime > $1")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.GT(Time(10, 20, 0, 0))), "(table1.colTime > $1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionGT_EQ(t *testing.T) {
|
func TestTimeExpressionGT_EQ(t *testing.T) {
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.GT_EQ(table2ColTime)), "table1.colTime >= table2.colTime")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.GT_EQ(table2ColTime)), "(table1.colTime >= table2.colTime)")
|
||||||
assert.Equal(t, getTestSerialize(t, table1ColTime.GT_EQ(Time(10, 20, 0, 0))), "table1.colTime >= $1")
|
assert.Equal(t, getTestSerialize(t, table1ColTime.GT_EQ(Time(10, 20, 0, 0))), "(table1.colTime >= $1)")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ SELECT payment.payment_id AS "payment.payment_id",
|
||||||
customer.last_update AS "customer.last_update",
|
customer.last_update AS "customer.last_update",
|
||||||
customer.active AS "customer.active"
|
customer.active AS "customer.active"
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
JOIN dvds.customer ON payment.customer_id = customer.customer_id
|
JOIN dvds.customer ON (payment.customer_id = customer.customer_id)
|
||||||
ORDER BY payment.payment_id ASC
|
ORDER BY payment.payment_id ASC
|
||||||
LIMIT 30;
|
LIMIT 30;
|
||||||
`
|
`
|
||||||
|
|
@ -196,11 +196,11 @@ SELECT film_actor.actor_id AS "film_actor.actor_id",
|
||||||
rental.staff_id AS "rental.staff_id",
|
rental.staff_id AS "rental.staff_id",
|
||||||
rental.last_update AS "rental.last_update"
|
rental.last_update AS "rental.last_update"
|
||||||
FROM dvds.film_actor
|
FROM dvds.film_actor
|
||||||
JOIN dvds.actor ON film_actor.actor_id = actor.actor_id
|
JOIN dvds.actor ON (film_actor.actor_id = actor.actor_id)
|
||||||
JOIN dvds.film ON film_actor.film_id = film.film_id
|
JOIN dvds.film ON (film_actor.film_id = film.film_id)
|
||||||
JOIN dvds.language ON film.language_id = language.language_id
|
JOIN dvds.language ON (film.language_id = language.language_id)
|
||||||
JOIN dvds.inventory ON inventory.film_id = film.film_id
|
JOIN dvds.inventory ON (inventory.film_id = film.film_id)
|
||||||
JOIN dvds.rental ON rental.inventory_id = inventory.inventory_id
|
JOIN dvds.rental ON (rental.inventory_id = inventory.inventory_id)
|
||||||
ORDER BY film.film_id ASC
|
ORDER BY film.film_id ASC
|
||||||
LIMIT 50;
|
LIMIT 50;
|
||||||
`
|
`
|
||||||
|
|
@ -271,7 +271,7 @@ SELECT language.language_id AS "language.language_id",
|
||||||
film.special_features AS "film.special_features",
|
film.special_features AS "film.special_features",
|
||||||
film.fulltext AS "film.fulltext"
|
film.fulltext AS "film.fulltext"
|
||||||
FROM dvds.film
|
FROM dvds.film
|
||||||
JOIN dvds.language ON film.language_id = language.language_id
|
JOIN dvds.language ON (film.language_id = language.language_id)
|
||||||
WHERE film.rating = 'NC-17'
|
WHERE film.rating = 'NC-17'
|
||||||
LIMIT 15;
|
LIMIT 15;
|
||||||
`
|
`
|
||||||
|
|
@ -413,7 +413,7 @@ SELECT customer.customer_id AS "customer.customer_id",
|
||||||
address.phone AS "address.phone",
|
address.phone AS "address.phone",
|
||||||
address.last_update AS "address.last_update"
|
address.last_update AS "address.last_update"
|
||||||
FROM dvds.customer
|
FROM dvds.customer
|
||||||
FULL JOIN dvds.address ON customer.address_id = address.address_id
|
FULL JOIN dvds.address ON (customer.address_id = address.address_id)
|
||||||
ORDER BY customer.customer_id ASC;
|
ORDER BY customer.customer_id ASC;
|
||||||
`
|
`
|
||||||
query := Customer.
|
query := Customer.
|
||||||
|
|
@ -500,7 +500,7 @@ SELECT employee.employee_id AS "employee.employee_id",
|
||||||
manager.last_name AS "manager.last_name",
|
manager.last_name AS "manager.last_name",
|
||||||
manager.manager_id AS "manager.manager_id"
|
manager.manager_id AS "manager.manager_id"
|
||||||
FROM test_sample.employee
|
FROM test_sample.employee
|
||||||
LEFT JOIN test_sample.employee AS manager ON manager.employee_id = employee.manager_id
|
LEFT JOIN test_sample.employee AS manager ON (manager.employee_id = employee.manager_id)
|
||||||
ORDER BY employee.employee_id;
|
ORDER BY employee.employee_id;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -568,7 +568,7 @@ SELECT f1.film_id AS "f1.film_id",
|
||||||
f2.special_features AS "f2.special_features",
|
f2.special_features AS "f2.special_features",
|
||||||
f2.fulltext AS "f2.fulltext"
|
f2.fulltext AS "f2.fulltext"
|
||||||
FROM dvds.film AS f1
|
FROM dvds.film AS f1
|
||||||
JOIN dvds.film AS f2 ON (f1.film_id < f2.film_id AND f1.length = f2.length)
|
JOIN dvds.film AS f2 ON ((f1.film_id < f2.film_id) AND (f1.length = f2.length))
|
||||||
ORDER BY f1.film_id ASC;
|
ORDER BY f1.film_id ASC;
|
||||||
`
|
`
|
||||||
f1 := Film.AS("f1")
|
f1 := Film.AS("f1")
|
||||||
|
|
@ -605,7 +605,7 @@ SELECT f1.title AS "thesame_length_films.title1",
|
||||||
f2.title AS "thesame_length_films.title2",
|
f2.title AS "thesame_length_films.title2",
|
||||||
f1.length AS "thesame_length_films.length"
|
f1.length AS "thesame_length_films.length"
|
||||||
FROM dvds.film AS f1
|
FROM dvds.film AS f1
|
||||||
JOIN dvds.film AS f2 ON (f1.film_id != f2.film_id AND f1.length = f2.length)
|
JOIN dvds.film AS f2 ON ((f1.film_id != f2.film_id) AND (f1.length = f2.length))
|
||||||
ORDER BY f1.length ASC, f1.title ASC, f2.title ASC
|
ORDER BY f1.length ASC, f1.title ASC, f2.title ASC
|
||||||
LIMIT 1000;
|
LIMIT 1000;
|
||||||
`
|
`
|
||||||
|
|
@ -731,14 +731,14 @@ SELECT actor.actor_id AS "actor.actor_id",
|
||||||
films."film.title" AS "film.title",
|
films."film.title" AS "film.title",
|
||||||
films."film.rating" AS "film.rating"
|
films."film.rating" AS "film.rating"
|
||||||
FROM dvds.actor
|
FROM dvds.actor
|
||||||
JOIN dvds.film_actor ON actor.actor_id = film_actor.film_id
|
JOIN dvds.film_actor ON (actor.actor_id = film_actor.film_id)
|
||||||
JOIN (
|
JOIN (
|
||||||
SELECT film.film_id AS "film.film_id",
|
SELECT film.film_id AS "film.film_id",
|
||||||
film.title AS "film.title",
|
film.title AS "film.title",
|
||||||
film.rating AS "film.rating"
|
film.rating AS "film.rating"
|
||||||
FROM dvds.film
|
FROM dvds.film
|
||||||
WHERE film.rating = 'R'
|
WHERE film.rating = 'R'
|
||||||
) AS films ON film_actor.film_id = films."film.film_id";
|
) AS films ON (film_actor.film_id = films."film.film_id");
|
||||||
`
|
`
|
||||||
|
|
||||||
rFilmsOnly := Film.SELECT(Film.FilmID, Film.Title, Film.Rating).
|
rFilmsOnly := Film.SELECT(Film.FilmID, Film.Title, Film.Rating).
|
||||||
|
|
@ -906,7 +906,7 @@ FROM dvds.customer
|
||||||
SUM(payment.amount) AS "amount_sum"
|
SUM(payment.amount) AS "amount_sum"
|
||||||
FROM dvds.payment
|
FROM dvds.payment
|
||||||
GROUP BY payment.customer_id
|
GROUP BY payment.customer_id
|
||||||
) AS customer_payment_sum ON customer.customer_id = customer_payment_sum."payment.customer_id"
|
) AS customer_payment_sum ON (customer.customer_id = customer_payment_sum."payment.customer_id")
|
||||||
ORDER BY customer_payment_sum.amount_sum ASC;
|
ORDER BY customer_payment_sum.amount_sum ASC;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue