Add ROW constructor and IN/EXISTS operator.

This commit is contained in:
zer0sub 2019-05-05 18:03:30 +02:00
parent 08e4392278
commit 3367df247c
18 changed files with 183 additions and 565 deletions

View file

@ -9,34 +9,45 @@ type Expression interface {
Clause
Projection
As(alias string) Projection
IsDistinct(expression Expression) BoolExpression
IsNull() BoolExpression
Asc() OrderByClause
Desc() OrderByClause
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
}
type expressionInterfaceImpl struct {
parent Expression
}
func (e *expressionInterfaceImpl) As(alias string) Projection {
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 {
return NewAlias(e.parent, alias)
}
func (e *expressionInterfaceImpl) IsDistinct(expression Expression) BoolExpression {
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) IsNull() BoolExpression {
return nil
}
func (e *expressionInterfaceImpl) Asc() OrderByClause {
func (e *expressionInterfaceImpl) ASC() OrderByClause {
return &orderByClause{expression: e.parent, ascent: true}
}
func (e *expressionInterfaceImpl) Desc() OrderByClause {
func (e *expressionInterfaceImpl) DESC() OrderByClause {
return &orderByClause{expression: e.parent, ascent: false}
}
@ -47,10 +58,10 @@ func (e *expressionInterfaceImpl) SerializeForProjection(out *queryData) error {
// Representation of binary operations (e.g. comparisons, arithmetic)
type binaryExpression struct {
lhs, rhs Expression
operator []byte
operator string
}
func newBinaryExpression(lhs, rhs Expression, operator []byte, parent ...Expression) binaryExpression {
func newBinaryExpression(lhs, rhs Expression, operator string, parent ...Expression) binaryExpression {
binaryExpression := binaryExpression{
lhs: lhs,
rhs: rhs,
@ -92,7 +103,7 @@ func (c *binaryExpression) Serialize(out *queryData, options ...serializeOption)
return err
}
out.Write(c.operator)
out.WriteString(c.operator)
if err := c.rhs.Serialize(out); err != nil {
return err
@ -108,10 +119,10 @@ func (c *binaryExpression) Serialize(out *queryData, options ...serializeOption)
// A not expression which negates a expression value
type prefixExpression struct {
expression Expression
operator []byte
operator string
}
func newPrefixExpression(expression Expression, operator []byte) prefixExpression {
func newPrefixExpression(expression Expression, operator string) prefixExpression {
prefixExpression := prefixExpression{
expression: expression,
operator: operator,
@ -121,7 +132,7 @@ func newPrefixExpression(expression Expression, operator []byte) prefixExpressio
}
func (p *prefixExpression) Serialize(out *queryData, options ...serializeOption) error {
out.Write(p.operator)
out.WriteString(p.operator + " ")
if p.expression == nil {
return errors.Newf("nil prefix expression.")
@ -132,69 +143,3 @@ func (p *prefixExpression) Serialize(out *queryData, options ...serializeOption)
return nil
}
//
//// Representation of n-ary conjunctions (AND/OR)
//type conjunctExpression struct {
// expressions []Expression
// conjunction []byte
//}
//
//func (conj *conjunctExpression) Serialize(out *queryData, options ...serializeOption) error {
// if len(conj.expressions) == 0 {
// return errors.New("Empty conjunction.")
// }
//
// //clauses := make([]Clause, len(conj.expressions), len(conj.expressions))
// //for i, expr := range conj.expressions {
// // clauses[i] = expr
// //}
//
// useParentheses := len(conj.expressions) > 1
// if useParentheses {
// out.WriteByte('(')
// }
//
// if err := serializeExpressionList(conj.expressions, string(conj.conjunction), out); err != nil {
// return err
// }
//
// if useParentheses {
// out.WriteByte(')')
// }
//
// return nil
//}
//--------------------------------------------------------------
//------------------------------------------------------//
//// Dummy type for select *
//type ColumnList []Column
//
//func (cl ColumnList) Serialize(out *bytes.Buffer, options ...serializeOption) error {
// for i, column := range cl {
// err := column.Serialize(out)
//
// if err != nil {
// return err
// }
//
// if i != len(cl)-1 {
// out.WriteString(", ")
// }
// }
// return nil
//}
//
//func (e ColumnList) As(alias string) Clause {
// panic("Invalid usage")
//}
//
//func (e ColumnList) IsDistinct(expression Expression) BoolExpression {
// panic("Invalid usage")
//}
//
//func (e ColumnList) IsNull(expression Expression) BoolExpression {
// panic("Invalid usage")
//}