jet/sqlbuilder/expression.go

161 lines
3.4 KiB
Go
Raw Normal View History

package sqlbuilder
import (
"bytes"
"github.com/dropbox/godropbox/database/sqltypes"
"github.com/dropbox/godropbox/errors"
)
2019-03-31 09:17:28 +02:00
// An expression
type Expression interface {
Clause
2019-03-31 09:17:28 +02:00
As(alias string) Clause
IsDistinct(expression Expression) BoolExpression
IsNull(expression Expression) BoolExpression
}
2019-03-31 09:17:28 +02:00
type expressionInterfaceImpl struct {
parent Expression
}
2019-03-31 09:17:28 +02:00
func (e *expressionInterfaceImpl) As(alias string) Clause {
return NewAlias(e.parent, alias)
}
2019-03-31 09:17:28 +02:00
func (e *expressionInterfaceImpl) IsDistinct(expression Expression) BoolExpression {
return nil
}
2019-03-31 09:17:28 +02:00
func (e *expressionInterfaceImpl) IsNull(expression Expression) BoolExpression {
return nil
}
2019-03-31 09:17:28 +02:00
// Representation of binary operations (e.g. comparisons, arithmetic)
type binaryExpression struct {
expressionInterfaceImpl
lhs, rhs Expression
operator []byte
}
2019-03-31 09:17:28 +02:00
func NewBinaryExpression(lhs, rhs Expression, operator []byte, parent ...Expression) *binaryExpression {
binaryExpression := binaryExpression{
lhs: lhs,
rhs: rhs,
operator: operator,
}
2019-03-31 09:17:28 +02:00
if len(parent) > 0 {
binaryExpression.parent = parent[0]
}
2019-03-31 09:17:28 +02:00
return &binaryExpression
}
func (c *binaryExpression) SerializeSql(out *bytes.Buffer) (err error) {
if c.lhs == nil {
return errors.Newf("nil lhs. Generated sql: %s", out.String())
}
if err = c.lhs.SerializeSql(out); err != nil {
return
}
_, _ = out.Write(c.operator)
if c.rhs == nil {
return errors.Newf("nil rhs. Generated sql: %s", out.String())
}
if err = c.rhs.SerializeSql(out); err != nil {
return
}
return nil
}
2019-03-31 09:17:28 +02:00
// A not expression which negates a expression value
type prefixExpression struct {
expressionInterfaceImpl
2019-03-31 09:17:28 +02:00
expression Expression
operator []byte
}
2019-03-31 09:17:28 +02:00
func NewPrefixExpression(expression Expression, operator []byte, parent ...Expression) *prefixExpression {
prefixExpression := prefixExpression{
expression: expression,
operator: operator,
}
2019-03-31 09:17:28 +02:00
if len(parent) > 0 {
prefixExpression.parent = parent[0]
}
2019-03-31 09:17:28 +02:00
return &prefixExpression
}
2019-03-31 09:17:28 +02:00
func (p *prefixExpression) SerializeSql(out *bytes.Buffer) (err error) {
_, _ = out.Write(p.operator)
2019-03-31 09:17:28 +02:00
if p.expression == nil {
return errors.Newf("nil prefix expression. Generated sql: %s", out.String())
}
2019-03-31 09:17:28 +02:00
if err = p.expression.SerializeSql(out); err != nil {
return
}
2019-03-31 09:17:28 +02:00
return nil
}
2019-03-31 09:17:28 +02:00
// Representation of n-ary conjunctions (AND/OR)
type conjunctExpression struct {
expressionInterfaceImpl
expressions []BoolExpression
conjunction []byte
}
2019-03-31 09:17:28 +02:00
func (conj *conjunctExpression) SerializeSql(out *bytes.Buffer) (err error) {
if len(conj.expressions) == 0 {
return errors.Newf(
"Empty conjunction. Generated sql: %s",
out.String())
}
2019-03-31 09:17:28 +02:00
clauses := make([]Clause, len(conj.expressions), len(conj.expressions))
for i, expr := range conj.expressions {
clauses[i] = expr
}
2019-03-31 09:17:28 +02:00
useParentheses := len(clauses) > 1
if useParentheses {
_ = out.WriteByte('(')
}
2019-03-31 09:17:28 +02:00
if err = serializeClauses(clauses, conj.conjunction, out); err != nil {
return
}
2019-03-31 09:17:28 +02:00
if useParentheses {
_ = out.WriteByte(')')
}
return nil
}
2019-03-31 09:17:28 +02:00
//--------------------------------------------------------------
2019-03-31 09:17:28 +02:00
// Representation of an escaped literal
type literalExpression struct {
expressionInterfaceImpl
value sqltypes.Value
}
2019-03-31 09:17:28 +02:00
func NewLiteralExpression(value sqltypes.Value) *literalExpression {
exp := literalExpression{value: value}
exp.expressionInterfaceImpl.parent = &exp
return &exp
}
2019-03-31 09:17:28 +02:00
func (c literalExpression) SerializeSql(out *bytes.Buffer) error {
sqltypes.Value(c.value).EncodeSql(out)
return nil
}