2019-06-21 13:56:57 +02:00
|
|
|
package jet
|
2019-03-02 12:34:08 +01:00
|
|
|
|
|
|
|
|
import (
|
2019-06-05 17:15:20 +02:00
|
|
|
"errors"
|
2019-03-02 12:34:08 +01:00
|
|
|
)
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
// Expression is common interface for all expressions.
|
|
|
|
|
// Can be Bool, Int, Float, String, Date, Time, Timez, Timestamp or Timestampz expressions.
|
2019-06-04 12:10:23 +02:00
|
|
|
type Expression interface {
|
2019-05-07 19:06:21 +02:00
|
|
|
clause
|
|
|
|
|
projection
|
|
|
|
|
groupByClause
|
2019-07-18 17:43:11 +02:00
|
|
|
orderByClause
|
2019-03-02 12:34:08 +01:00
|
|
|
|
2019-06-27 19:55:21 +02:00
|
|
|
// Test expression whether it is a NULL value.
|
2019-05-31 12:59:57 +02:00
|
|
|
IS_NULL() BoolExpression
|
2019-06-27 19:55:21 +02:00
|
|
|
// Test expression whether it is a non-NULL value.
|
2019-05-31 12:59:57 +02:00
|
|
|
IS_NOT_NULL() BoolExpression
|
2019-05-29 14:03:38 +02:00
|
|
|
|
2019-06-27 19:55:21 +02:00
|
|
|
// Check if this expressions matches any in expressions list
|
2019-06-04 12:10:23 +02:00
|
|
|
IN(expressions ...Expression) BoolExpression
|
2019-06-27 19:55:21 +02:00
|
|
|
// Check if this expressions is different of all expressions in expressions list
|
2019-06-04 12:10:23 +02:00
|
|
|
NOT_IN(expressions ...Expression) BoolExpression
|
2019-05-05 18:03:30 +02:00
|
|
|
|
2019-06-27 19:55:21 +02:00
|
|
|
// The temporary alias name to assign to the expression
|
2019-05-07 19:06:21 +02:00
|
|
|
AS(alias string) projection
|
2019-05-29 14:03:38 +02:00
|
|
|
|
2019-06-27 19:55:21 +02:00
|
|
|
// Expression will be used to sort query result in ascending order
|
2019-07-18 17:43:11 +02:00
|
|
|
ASC() orderByClause
|
2019-06-27 19:55:21 +02:00
|
|
|
// Expression will be used to sort query result in ascending order
|
2019-07-18 17:43:11 +02:00
|
|
|
DESC() orderByClause
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
type expressionInterfaceImpl struct {
|
2019-06-04 12:10:23 +02:00
|
|
|
parent Expression
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
func (e *expressionInterfaceImpl) from(subQuery SelectTable) projection {
|
2019-06-18 14:35:32 +02:00
|
|
|
return e.parent
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-31 12:59:57 +02:00
|
|
|
func (e *expressionInterfaceImpl) IS_NULL() BoolExpression {
|
2019-05-29 14:03:38 +02:00
|
|
|
return newPostifxBoolExpression(e.parent, "IS NULL")
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-31 12:59:57 +02:00
|
|
|
func (e *expressionInterfaceImpl) IS_NOT_NULL() BoolExpression {
|
2019-05-29 14:03:38 +02:00
|
|
|
return newPostifxBoolExpression(e.parent, "IS NOT NULL")
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-04 12:10:23 +02:00
|
|
|
func (e *expressionInterfaceImpl) IN(expressions ...Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(e.parent, WRAP(expressions...), "IN")
|
2019-05-05 18:03:30 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-04 12:10:23 +02:00
|
|
|
func (e *expressionInterfaceImpl) NOT_IN(expressions ...Expression) BoolExpression {
|
2019-07-15 13:06:06 +02:00
|
|
|
return newBinaryBoolOperator(e.parent, WRAP(expressions...), "NOT IN")
|
2019-05-05 18:03:30 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-07 19:06:21 +02:00
|
|
|
func (e *expressionInterfaceImpl) AS(alias string) projection {
|
2019-06-18 14:35:32 +02:00
|
|
|
return newAlias(e.parent, alias)
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
func (e *expressionInterfaceImpl) ASC() orderByClause {
|
2019-06-21 13:56:57 +02:00
|
|
|
return newOrderByClause(e.parent, true)
|
2019-04-03 11:03:07 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
func (e *expressionInterfaceImpl) DESC() orderByClause {
|
2019-06-21 13:56:57 +02:00
|
|
|
return newOrderByClause(e.parent, false)
|
2019-04-03 11:03:07 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 10:48:03 +02:00
|
|
|
func (e *expressionInterfaceImpl) serializeForGroupBy(statement statementType, out *sqlBuilder) error {
|
2019-06-27 19:55:21 +02:00
|
|
|
return e.parent.serialize(statement, out, noWrap)
|
2019-05-07 19:06:21 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 10:48:03 +02:00
|
|
|
func (e *expressionInterfaceImpl) serializeForProjection(statement statementType, out *sqlBuilder) error {
|
2019-06-27 19:55:21 +02:00
|
|
|
return e.parent.serialize(statement, out, noWrap)
|
2019-04-03 11:03:07 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 10:48:03 +02:00
|
|
|
func (e *expressionInterfaceImpl) serializeForOrderBy(statement statementType, out *sqlBuilder) error {
|
2019-06-27 19:55:21 +02:00
|
|
|
return e.parent.serialize(statement, out, noWrap)
|
2019-05-08 12:49:36 +02:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
// Representation of binary operations (e.g. comparisons, arithmetic)
|
2019-05-29 14:03:38 +02:00
|
|
|
type binaryOpExpression struct {
|
2019-06-04 12:10:23 +02:00
|
|
|
lhs, rhs Expression
|
2019-05-05 18:03:30 +02:00
|
|
|
operator string
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-06-04 12:10:23 +02:00
|
|
|
func newBinaryExpression(lhs, rhs Expression, operator string) binaryOpExpression {
|
2019-05-29 14:03:38 +02:00
|
|
|
binaryExpression := binaryOpExpression{
|
2019-03-31 09:17:28 +02:00
|
|
|
lhs: lhs,
|
|
|
|
|
rhs: rhs,
|
|
|
|
|
operator: operator,
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 14:07:58 +02:00
|
|
|
return binaryExpression
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 10:48:03 +02:00
|
|
|
func (c *binaryOpExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
|
2019-05-13 12:33:11 +02:00
|
|
|
if c == nil {
|
2019-07-08 13:00:44 +02:00
|
|
|
return errors.New("jet: binary Expression is nil")
|
2019-05-13 12:33:11 +02:00
|
|
|
}
|
2019-03-02 12:34:08 +01:00
|
|
|
if c.lhs == nil {
|
2019-07-08 13:00:44 +02:00
|
|
|
return errors.New("jet: nil lhs")
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
2019-05-01 17:25:10 +02:00
|
|
|
if c.rhs == nil {
|
2019-07-08 13:00:44 +02:00
|
|
|
return errors.New("jet: nil rhs")
|
2019-05-01 17:25:10 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-27 19:55:21 +02:00
|
|
|
wrap := !contains(options, noWrap)
|
2019-05-01 17:25:10 +02:00
|
|
|
|
2019-05-01 18:23:19 +02:00
|
|
|
if wrap {
|
2019-05-08 13:47:01 +02:00
|
|
|
out.writeString("(")
|
2019-05-01 17:25:10 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-08 13:47:01 +02:00
|
|
|
if err := c.lhs.serialize(statement, out); err != nil {
|
2019-04-29 14:39:48 +02:00
|
|
|
return err
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-06-17 12:05:52 +02:00
|
|
|
out.writeString(c.operator)
|
2019-03-02 12:34:08 +01:00
|
|
|
|
2019-05-08 13:47:01 +02:00
|
|
|
if err := c.rhs.serialize(statement, out); err != nil {
|
2019-04-29 14:39:48 +02:00
|
|
|
return err
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 18:23:19 +02:00
|
|
|
if wrap {
|
2019-05-08 13:47:01 +02:00
|
|
|
out.writeString(")")
|
2019-05-01 17:25:10 +02:00
|
|
|
}
|
|
|
|
|
|
2019-03-02 12:34:08 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-04 12:10:23 +02:00
|
|
|
// A prefix operator Expression
|
2019-05-29 14:03:38 +02:00
|
|
|
type prefixOpExpression struct {
|
2019-06-04 12:10:23 +02:00
|
|
|
expression Expression
|
2019-05-05 18:03:30 +02:00
|
|
|
operator string
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-06-04 12:10:23 +02:00
|
|
|
func newPrefixExpression(expression Expression, operator string) prefixOpExpression {
|
2019-05-29 14:03:38 +02:00
|
|
|
prefixExpression := prefixOpExpression{
|
2019-03-31 09:17:28 +02:00
|
|
|
expression: expression,
|
|
|
|
|
operator: operator,
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 14:07:58 +02:00
|
|
|
return prefixExpression
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 10:48:03 +02:00
|
|
|
func (p *prefixOpExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
|
2019-05-13 12:33:11 +02:00
|
|
|
if p == nil {
|
2019-07-18 17:43:11 +02:00
|
|
|
return errors.New("jet: Prefix Expression is nil")
|
2019-05-13 12:33:11 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-08 13:47:01 +02:00
|
|
|
out.writeString(p.operator + " ")
|
2019-03-02 12:34:08 +01:00
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
if p.expression == nil {
|
2019-07-18 17:43:11 +02:00
|
|
|
return errors.New("jet: nil prefix Expression")
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
2019-05-08 13:47:01 +02:00
|
|
|
if err := p.expression.serialize(statement, out); err != nil {
|
2019-04-29 14:39:48 +02:00
|
|
|
return err
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-31 09:17:28 +02:00
|
|
|
return nil
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
2019-05-29 14:03:38 +02:00
|
|
|
|
2019-06-04 12:10:23 +02:00
|
|
|
// A postifx operator Expression
|
2019-05-29 14:03:38 +02:00
|
|
|
type postfixOpExpression struct {
|
2019-06-04 12:10:23 +02:00
|
|
|
expression Expression
|
2019-05-29 14:03:38 +02:00
|
|
|
operator string
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-04 12:10:23 +02:00
|
|
|
func newPostfixOpExpression(expression Expression, operator string) postfixOpExpression {
|
2019-05-29 14:03:38 +02:00
|
|
|
postfixOpExpression := postfixOpExpression{
|
|
|
|
|
expression: expression,
|
|
|
|
|
operator: operator,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return postfixOpExpression
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 10:48:03 +02:00
|
|
|
func (p *postfixOpExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
|
2019-05-29 14:03:38 +02:00
|
|
|
if p == nil {
|
2019-07-18 17:43:11 +02:00
|
|
|
return errors.New("jet: Postifx operator Expression is nil")
|
2019-05-29 14:03:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if p.expression == nil {
|
2019-07-18 17:43:11 +02:00
|
|
|
return errors.New("jet: nil prefix Expression")
|
2019-05-29 14:03:38 +02:00
|
|
|
}
|
|
|
|
|
if err := p.expression.serialize(statement, out); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out.writeString(p.operator)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|