jet/sqlbuilder/expression.go

146 lines
3.1 KiB
Go
Raw Normal View History

package sqlbuilder
import (
"github.com/dropbox/godropbox/errors"
)
2019-03-31 09:17:28 +02:00
// An expression
type Expression interface {
Clause
Projection
IN(subQuery SelectStatement) BoolExpression
NOT_IN(subQuery SelectStatement) BoolExpression
AS(alias string) Projection
IS_DISTINCT_FROM(expression Expression) BoolExpression
IS_NULL() BoolExpression
ASC() OrderByClause
DESC() OrderByClause
}
2019-03-31 09:17:28 +02:00
type expressionInterfaceImpl struct {
parent Expression
}
func (e *expressionInterfaceImpl) IN(subQuery SelectStatement) BoolExpression {
return newBinaryBoolExpression(e.parent, subQuery, " IN ")
}
func (e *expressionInterfaceImpl) NOT_IN(subQuery SelectStatement) BoolExpression {
return newBinaryBoolExpression(e.parent, subQuery, " NOT_IN ")
}
func (e *expressionInterfaceImpl) AS(alias string) Projection {
2019-03-31 09:17:28 +02:00
return NewAlias(e.parent, alias)
}
func (e *expressionInterfaceImpl) IS_DISTINCT_FROM(expression Expression) BoolExpression {
return newBinaryBoolExpression(e.parent, expression, "IS DISTINCT FROM")
}
func (e *expressionInterfaceImpl) IS_NULL() BoolExpression {
return nil
}
func (e *expressionInterfaceImpl) ASC() OrderByClause {
return &orderByClause{expression: e.parent, ascent: true}
}
func (e *expressionInterfaceImpl) DESC() OrderByClause {
return &orderByClause{expression: e.parent, ascent: false}
}
func (e *expressionInterfaceImpl) SerializeForProjection(out *queryData) error {
return e.parent.Serialize(out, FOR_PROJECTION)
}
2019-03-31 09:17:28 +02:00
// Representation of binary operations (e.g. comparisons, arithmetic)
type binaryExpression struct {
lhs, rhs Expression
operator string
}
func newBinaryExpression(lhs, rhs Expression, operator string, parent ...Expression) binaryExpression {
2019-03-31 09:17:28 +02:00
binaryExpression := binaryExpression{
lhs: lhs,
rhs: rhs,
operator: operator,
}
2019-03-31 14:07:58 +02:00
return binaryExpression
}
2019-05-01 18:23:19 +02:00
func isSimpleOperand(expression Expression) bool {
if _, ok := expression.(*literalExpression); ok {
return true
}
if _, ok := expression.(Column); ok {
return true
}
2019-05-03 12:51:57 +02:00
if _, ok := expression.(*numericFunc); ok {
2019-05-01 18:23:19 +02:00
return true
}
return false
}
func (c *binaryExpression) Serialize(out *queryData, options ...serializeOption) error {
if c.lhs == nil {
return errors.Newf("nil lhs.")
}
2019-05-01 17:25:10 +02:00
if c.rhs == nil {
return errors.Newf("nil rhs.")
}
2019-05-01 18:23:19 +02:00
wrap := !isSimpleOperand(c.lhs) && !isSimpleOperand(c.rhs)
2019-05-01 17:25:10 +02:00
2019-05-01 18:23:19 +02:00
if wrap {
2019-05-01 17:25:10 +02:00
out.WriteString("(")
}
if err := c.lhs.Serialize(out); err != nil {
return err
}
out.WriteString(c.operator)
if err := c.rhs.Serialize(out); err != nil {
return err
}
2019-05-01 18:23:19 +02:00
if wrap {
2019-05-01 17:25:10 +02:00
out.WriteString(")")
}
return nil
}
2019-03-31 09:17:28 +02:00
// A not expression which negates a expression value
type prefixExpression struct {
expression Expression
operator string
}
func newPrefixExpression(expression Expression, operator string) prefixExpression {
2019-03-31 09:17:28 +02:00
prefixExpression := prefixExpression{
expression: expression,
operator: operator,
}
2019-03-31 14:07:58 +02:00
return prefixExpression
}
func (p *prefixExpression) Serialize(out *queryData, options ...serializeOption) error {
out.WriteString(p.operator + " ")
2019-03-31 09:17:28 +02:00
if p.expression == nil {
return errors.Newf("nil prefix expression.")
}
if err := p.expression.Serialize(out); err != nil {
return err
}
2019-03-31 09:17:28 +02:00
return nil
}