2019-06-21 13:56:57 +02:00
|
|
|
package jet
|
2019-05-29 14:03:38 +02:00
|
|
|
|
2019-05-31 12:59:57 +02:00
|
|
|
import "errors"
|
|
|
|
|
|
2019-07-31 13:02:30 +02:00
|
|
|
// --------- Arithmetic operators -------------//
|
|
|
|
|
|
|
|
|
|
// MINUSi changes the sign of the intExp.
|
|
|
|
|
func MINUSi(intExp IntegerExpression) IntegerExpression {
|
|
|
|
|
return newPrefixIntegerOperator(intExp, "-")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MINUSi changes the sign of the intExp.
|
|
|
|
|
func MINUSf(floatExp FloatExpression) FloatExpression {
|
|
|
|
|
return newPrefixFloatOperator(floatExp, "-")
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-29 14:03:38 +02:00
|
|
|
//----------- Logical operators ---------------//
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
// NOT returns negation of bool expression result
|
2019-07-16 12:17:27 +02:00
|
|
|
func NOT(exp BoolExpression) BoolExpression {
|
|
|
|
|
return newPrefixBoolOperator(exp, "NOT")
|
2019-07-15 13:06:06 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
// BIT_NOT inverts every bit in integer expression result
|
2019-07-15 13:06:06 +02:00
|
|
|
func BIT_NOT(expr IntegerExpression) IntegerExpression {
|
|
|
|
|
return newPrefixIntegerOperator(expr, "~")
|
2019-05-29 14:03:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------- Comparison operators ---------------//
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
// EXISTS checks for existence of the rows in subQuery
|
2019-06-27 19:55:21 +02:00
|
|
|
func EXISTS(subQuery SelectStatement) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newPrefixBoolOperator(subQuery, "EXISTS")
|
2019-06-27 19:55:21 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-29 14:03:38 +02:00
|
|
|
// Returns a representation of "a=b"
|
2019-06-27 19:55:21 +02:00
|
|
|
func eq(lhs, rhs Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(lhs, rhs, "=")
|
2019-05-29 14:03:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns a representation of "a!=b"
|
2019-06-27 19:55:21 +02:00
|
|
|
func notEq(lhs, rhs Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(lhs, rhs, "!=")
|
2019-05-29 14:03:38 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-27 19:55:21 +02:00
|
|
|
func isDistinctFrom(lhs, rhs Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(lhs, rhs, "IS DISTINCT FROM")
|
2019-05-30 14:49:36 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-27 19:55:21 +02:00
|
|
|
func isNotDistinctFrom(lhs, rhs Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(lhs, rhs, "IS NOT DISTINCT FROM")
|
2019-05-30 14:49:36 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-29 14:03:38 +02:00
|
|
|
// Returns a representation of "a<b"
|
2019-06-27 19:55:21 +02:00
|
|
|
func lt(lhs Expression, rhs Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(lhs, rhs, "<")
|
2019-05-29 14:03:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns a representation of "a<=b"
|
2019-06-27 19:55:21 +02:00
|
|
|
func ltEq(lhs, rhs Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(lhs, rhs, "<=")
|
2019-05-29 14:03:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns a representation of "a>b"
|
2019-06-27 19:55:21 +02:00
|
|
|
func gt(lhs, rhs Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(lhs, rhs, ">")
|
2019-05-29 14:03:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns a representation of "a>=b"
|
2019-06-27 19:55:21 +02:00
|
|
|
func gtEq(lhs, rhs Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(lhs, rhs, ">=")
|
2019-05-29 14:03:38 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-31 12:59:57 +02:00
|
|
|
// --------------- CASE operator -------------------//
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
// CaseOperator is interface for SQL case operator
|
|
|
|
|
type CaseOperator interface {
|
2019-06-04 12:10:23 +02:00
|
|
|
Expression
|
2019-05-31 12:59:57 +02:00
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
WHEN(condition Expression) CaseOperator
|
|
|
|
|
THEN(then Expression) CaseOperator
|
|
|
|
|
ELSE(els Expression) CaseOperator
|
2019-05-31 12:59:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type caseOperatorImpl struct {
|
|
|
|
|
expressionInterfaceImpl
|
|
|
|
|
|
2019-06-04 12:10:23 +02:00
|
|
|
expression Expression
|
|
|
|
|
when []Expression
|
|
|
|
|
then []Expression
|
|
|
|
|
els Expression
|
2019-05-31 12:59:57 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
// CASE create CASE operator with optional list of expressions
|
|
|
|
|
func CASE(expression ...Expression) CaseOperator {
|
2019-05-31 12:59:57 +02:00
|
|
|
caseExp := &caseOperatorImpl{}
|
|
|
|
|
|
2019-06-03 17:38:47 +02:00
|
|
|
if len(expression) > 0 {
|
2019-05-31 12:59:57 +02:00
|
|
|
caseExp.expression = expression[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
caseExp.expressionInterfaceImpl.parent = caseExp
|
|
|
|
|
|
|
|
|
|
return caseExp
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
func (c *caseOperatorImpl) WHEN(when Expression) CaseOperator {
|
2019-05-31 12:59:57 +02:00
|
|
|
c.when = append(c.when, when)
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
func (c *caseOperatorImpl) THEN(then Expression) CaseOperator {
|
2019-05-31 12:59:57 +02:00
|
|
|
c.then = append(c.then, then)
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
func (c *caseOperatorImpl) ELSE(els Expression) CaseOperator {
|
2019-05-31 12:59:57 +02:00
|
|
|
c.els = els
|
|
|
|
|
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 14:57:02 +02:00
|
|
|
func (c *caseOperatorImpl) accept(visitor visitor) {
|
|
|
|
|
visitor.visit(c)
|
|
|
|
|
|
|
|
|
|
c.expression.accept(visitor)
|
|
|
|
|
|
|
|
|
|
for _, when := range c.when {
|
|
|
|
|
when.accept(visitor)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, then := range c.then {
|
|
|
|
|
then.accept(visitor)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c.els != nil {
|
|
|
|
|
c.els.accept(visitor)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
func (c *caseOperatorImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
|
2019-05-31 12:59:57 +02:00
|
|
|
if c == nil {
|
2019-07-08 13:00:44 +02:00
|
|
|
return errors.New("jet: Case Expression is nil. ")
|
2019-05-31 12:59:57 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString("(CASE")
|
2019-05-31 12:59:57 +02:00
|
|
|
|
|
|
|
|
if c.expression != nil {
|
|
|
|
|
err := c.expression.serialize(statement, out)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(c.when) == 0 || len(c.then) == 0 {
|
2019-07-08 13:00:44 +02:00
|
|
|
return errors.New("jet: Invalid case Statement. There should be at least one when/then Expression pair. ")
|
2019-05-31 12:59:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(c.when) != len(c.then) {
|
2019-07-08 13:00:44 +02:00
|
|
|
return errors.New("jet: When and then Expression count mismatch. ")
|
2019-05-31 12:59:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i, when := range c.when {
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString("WHEN")
|
2019-06-27 19:55:21 +02:00
|
|
|
err := when.serialize(statement, out, noWrap)
|
2019-05-31 12:59:57 +02:00
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString("THEN")
|
2019-06-27 19:55:21 +02:00
|
|
|
err = c.then[i].serialize(statement, out, noWrap)
|
2019-05-31 12:59:57 +02:00
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c.els != nil {
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString("ELSE")
|
2019-06-27 19:55:21 +02:00
|
|
|
err := c.els.serialize(statement, out, noWrap)
|
2019-05-31 12:59:57 +02:00
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString("END)")
|
2019-05-31 12:59:57 +02:00
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|