diff --git a/internal/jet/bool_expression.go b/internal/jet/bool_expression.go index fa9342f..1a05ab6 100644 --- a/internal/jet/bool_expression.go +++ b/internal/jet/bool_expression.go @@ -53,80 +53,53 @@ func (b *boolInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs BoolExpression) BoolExpress } func (b *boolInterfaceImpl) AND(expression BoolExpression) BoolExpression { - return newBinaryBoolOperator(b.parent, expression, "AND") + return newBinaryBoolOperatorExpression(b.parent, expression, "AND") } func (b *boolInterfaceImpl) OR(expression BoolExpression) BoolExpression { - return newBinaryBoolOperator(b.parent, expression, "OR") + return newBinaryBoolOperatorExpression(b.parent, expression, "OR") } func (b *boolInterfaceImpl) IS_TRUE() BoolExpression { - return newPostifxBoolExpression(b.parent, "IS TRUE") + return newPostfixBoolOperatorExpression(b.parent, "IS TRUE") } func (b *boolInterfaceImpl) IS_NOT_TRUE() BoolExpression { - return newPostifxBoolExpression(b.parent, "IS NOT TRUE") + return newPostfixBoolOperatorExpression(b.parent, "IS NOT TRUE") } func (b *boolInterfaceImpl) IS_FALSE() BoolExpression { - return newPostifxBoolExpression(b.parent, "IS FALSE") + return newPostfixBoolOperatorExpression(b.parent, "IS FALSE") } func (b *boolInterfaceImpl) IS_NOT_FALSE() BoolExpression { - return newPostifxBoolExpression(b.parent, "IS NOT FALSE") + return newPostfixBoolOperatorExpression(b.parent, "IS NOT FALSE") } func (b *boolInterfaceImpl) IS_UNKNOWN() BoolExpression { - return newPostifxBoolExpression(b.parent, "IS UNKNOWN") + return newPostfixBoolOperatorExpression(b.parent, "IS UNKNOWN") } func (b *boolInterfaceImpl) IS_NOT_UNKNOWN() BoolExpression { - return newPostifxBoolExpression(b.parent, "IS NOT UNKNOWN") + return newPostfixBoolOperatorExpression(b.parent, "IS NOT UNKNOWN") } //---------------------------------------------------// -func newBinaryBoolOperator(lhs, rhs Expression, operator string, additionalParams ...Expression) BoolExpression { +func newBinaryBoolOperatorExpression(lhs, rhs Expression, operator string, additionalParams ...Expression) BoolExpression { return BoolExp(newBinaryOperatorExpression(lhs, rhs, operator, additionalParams...)) } //---------------------------------------------------// -type prefixBoolExpression struct { - ExpressionInterfaceImpl - boolInterfaceImpl - - prefixOpExpression -} - -func newPrefixBoolOperator(expression Expression, operator string) BoolExpression { - exp := prefixBoolExpression{} - exp.prefixOpExpression = newPrefixExpression(expression, operator) - - exp.ExpressionInterfaceImpl.Parent = &exp - exp.boolInterfaceImpl.parent = &exp - - return &exp +func newPrefixBoolOperatorExpression(expression Expression, operator string) BoolExpression { + return BoolExp(newPrefixOperatorExpression(expression, operator)) } //---------------------------------------------------// -type postfixBoolOpExpression struct { - ExpressionInterfaceImpl - boolInterfaceImpl - - postfixOpExpression -} - -func newPostifxBoolExpression(expression Expression, operator string) BoolExpression { - exp := postfixBoolOpExpression{} - exp.postfixOpExpression = newPostfixOpExpression(expression, operator) - - exp.ExpressionInterfaceImpl.Parent = &exp - exp.boolInterfaceImpl.parent = &exp - - return &exp +func newPostfixBoolOperatorExpression(expression Expression, operator string) BoolExpression { + return BoolExp(newPostfixOperatorExpression(expression, operator)) } //---------------------------------------------------// - type boolExpressionWrapper struct { boolInterfaceImpl Expression diff --git a/internal/jet/expression.go b/internal/jet/expression.go index 6a99638..379bd70 100644 --- a/internal/jet/expression.go +++ b/internal/jet/expression.go @@ -36,19 +36,19 @@ func (e *ExpressionInterfaceImpl) fromImpl(subQuery SelectTable) Projection { } func (e *ExpressionInterfaceImpl) IS_NULL() BoolExpression { - return newPostifxBoolExpression(e.Parent, "IS NULL") + return newPostfixBoolOperatorExpression(e.Parent, "IS NULL") } func (e *ExpressionInterfaceImpl) IS_NOT_NULL() BoolExpression { - return newPostifxBoolExpression(e.Parent, "IS NOT NULL") + return newPostfixBoolOperatorExpression(e.Parent, "IS NOT NULL") } func (e *ExpressionInterfaceImpl) IN(expressions ...Expression) BoolExpression { - return newBinaryBoolOperator(e.Parent, WRAP(expressions...), "IN") + return newBinaryBoolOperatorExpression(e.Parent, WRAP(expressions...), "IN") } func (e *ExpressionInterfaceImpl) NOT_IN(expressions ...Expression) BoolExpression { - return newBinaryBoolOperator(e.Parent, WRAP(expressions...), "NOT IN") + return newBinaryBoolOperatorExpression(e.Parent, WRAP(expressions...), "NOT IN") } func (e *ExpressionInterfaceImpl) AS(alias string) Projection { @@ -129,21 +129,24 @@ func (c *binaryOperatorExpression) serialize(statement StatementType, out *SQLBu } // A prefix operator Expression -type prefixOpExpression struct { +type prefixExpression struct { + ExpressionInterfaceImpl + expression Expression operator string } -func newPrefixExpression(expression Expression, operator string) prefixOpExpression { - prefixExpression := prefixOpExpression{ +func newPrefixOperatorExpression(expression Expression, operator string) *prefixExpression { + prefixExpression := &prefixExpression{ expression: expression, operator: operator, } + prefixExpression.ExpressionInterfaceImpl.Parent = prefixExpression return prefixExpression } -func (p *prefixOpExpression) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { +func (p *prefixExpression) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.WriteString("(") out.WriteString(p.operator) @@ -156,18 +159,22 @@ func (p *prefixOpExpression) serialize(statement StatementType, out *SQLBuilder, out.WriteString(")") } -// A postifx operator Expression +// A postfix operator Expression type postfixOpExpression struct { + ExpressionInterfaceImpl + expression Expression operator string } -func newPostfixOpExpression(expression Expression, operator string) postfixOpExpression { - postfixOpExpression := postfixOpExpression{ +func newPostfixOperatorExpression(expression Expression, operator string) *postfixOpExpression { + postfixOpExpression := &postfixOpExpression{ expression: expression, operator: operator, } + postfixOpExpression.ExpressionInterfaceImpl.Parent = postfixOpExpression + return postfixOpExpression } diff --git a/internal/jet/integer_expression.go b/internal/jet/integer_expression.go index efda817..c004437 100644 --- a/internal/jet/integer_expression.go +++ b/internal/jet/integer_expression.go @@ -86,23 +86,23 @@ func (i *integerInterfaceImpl) LT_EQ(expression IntegerExpression) BoolExpressio } func (i *integerInterfaceImpl) ADD(expression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, expression, "+") + return newBinaryIntegerOperatorExpression(i.parent, expression, "+") } func (i *integerInterfaceImpl) SUB(expression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, expression, "-") + return newBinaryIntegerOperatorExpression(i.parent, expression, "-") } func (i *integerInterfaceImpl) MUL(expression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, expression, "*") + return newBinaryIntegerOperatorExpression(i.parent, expression, "*") } func (i *integerInterfaceImpl) DIV(expression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, expression, "/") + return newBinaryIntegerOperatorExpression(i.parent, expression, "/") } func (i *integerInterfaceImpl) MOD(expression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, expression, "%") + return newBinaryIntegerOperatorExpression(i.parent, expression, "%") } func (i *integerInterfaceImpl) POW(expression IntegerExpression) IntegerExpression { @@ -110,46 +110,33 @@ func (i *integerInterfaceImpl) POW(expression IntegerExpression) IntegerExpressi } func (i *integerInterfaceImpl) BIT_AND(expression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, expression, "&") + return newBinaryIntegerOperatorExpression(i.parent, expression, "&") } func (i *integerInterfaceImpl) BIT_OR(expression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, expression, "|") + return newBinaryIntegerOperatorExpression(i.parent, expression, "|") } func (i *integerInterfaceImpl) BIT_XOR(expression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, expression, "#") + return newBinaryIntegerOperatorExpression(i.parent, expression, "#") } func (i *integerInterfaceImpl) BIT_SHIFT_LEFT(intExpression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, intExpression, "<<") + return newBinaryIntegerOperatorExpression(i.parent, intExpression, "<<") } func (i *integerInterfaceImpl) BIT_SHIFT_RIGHT(intExpression IntegerExpression) IntegerExpression { - return newBinaryIntegerExpression(i.parent, intExpression, ">>") + return newBinaryIntegerOperatorExpression(i.parent, intExpression, ">>") } //---------------------------------------------------// -func newBinaryIntegerExpression(lhs, rhs IntegerExpression, operator string) IntegerExpression { +func newBinaryIntegerOperatorExpression(lhs, rhs IntegerExpression, operator string) IntegerExpression { return IntExp(newBinaryOperatorExpression(lhs, rhs, operator)) } //---------------------------------------------------// -type prefixIntegerOpExpression struct { - ExpressionInterfaceImpl - integerInterfaceImpl - - prefixOpExpression -} - -func newPrefixIntegerOperator(expression IntegerExpression, operator string) IntegerExpression { - integerExpression := prefixIntegerOpExpression{} - integerExpression.prefixOpExpression = newPrefixExpression(expression, operator) - - integerExpression.ExpressionInterfaceImpl.Parent = &integerExpression - integerExpression.integerInterfaceImpl.parent = &integerExpression - - return &integerExpression +func newPrefixIntegerOperatorExpression(expression IntegerExpression, operator string) IntegerExpression { + return IntExp(newPrefixOperatorExpression(expression, operator)) } //---------------------------------------------------// diff --git a/internal/jet/operators.go b/internal/jet/operators.go index 9229717..fad1e26 100644 --- a/internal/jet/operators.go +++ b/internal/jet/operators.go @@ -11,7 +11,7 @@ const ( // NOT returns negation of bool expression result func NOT(exp BoolExpression) BoolExpression { - return newPrefixBoolOperator(exp, "NOT") + return newPrefixBoolOperatorExpression(exp, "NOT") } // BIT_NOT inverts every bit in integer expression result @@ -19,52 +19,52 @@ func BIT_NOT(expr IntegerExpression) IntegerExpression { if literalExp, ok := expr.(LiteralExpression); ok { literalExp.SetConstant(true) } - return newPrefixIntegerOperator(expr, "~") + return newPrefixIntegerOperatorExpression(expr, "~") } //----------- Comparison operators ---------------// // EXISTS checks for existence of the rows in subQuery func EXISTS(subQuery Expression) BoolExpression { - return newPrefixBoolOperator(subQuery, "EXISTS") + return newPrefixBoolOperatorExpression(subQuery, "EXISTS") } // Returns a representation of "a=b" func eq(lhs, rhs Expression) BoolExpression { - return newBinaryBoolOperator(lhs, rhs, "=") + return newBinaryBoolOperatorExpression(lhs, rhs, "=") } // Returns a representation of "a!=b" func notEq(lhs, rhs Expression) BoolExpression { - return newBinaryBoolOperator(lhs, rhs, "!=") + return newBinaryBoolOperatorExpression(lhs, rhs, "!=") } func isDistinctFrom(lhs, rhs Expression) BoolExpression { - return newBinaryBoolOperator(lhs, rhs, "IS DISTINCT FROM") + return newBinaryBoolOperatorExpression(lhs, rhs, "IS DISTINCT FROM") } func isNotDistinctFrom(lhs, rhs Expression) BoolExpression { - return newBinaryBoolOperator(lhs, rhs, "IS NOT DISTINCT FROM") + return newBinaryBoolOperatorExpression(lhs, rhs, "IS NOT DISTINCT FROM") } // Returns a representation of "ab" func gt(lhs, rhs Expression) BoolExpression { - return newBinaryBoolOperator(lhs, rhs, ">") + return newBinaryBoolOperatorExpression(lhs, rhs, ">") } // Returns a representation of "a>=b" func gtEq(lhs, rhs Expression) BoolExpression { - return newBinaryBoolOperator(lhs, rhs, ">=") + return newBinaryBoolOperatorExpression(lhs, rhs, ">=") } // --------------- CASE operator -------------------// diff --git a/internal/jet/string_expression.go b/internal/jet/string_expression.go index a3a76c7..29ceca6 100644 --- a/internal/jet/string_expression.go +++ b/internal/jet/string_expression.go @@ -60,35 +60,27 @@ func (s *stringInterfaceImpl) LT_EQ(rhs StringExpression) BoolExpression { } func (s *stringInterfaceImpl) CONCAT(rhs Expression) StringExpression { - return newBinaryStringExpression(s.parent, rhs, StringConcatOperator) + return newBinaryStringOperatorExpression(s.parent, rhs, StringConcatOperator) } func (s *stringInterfaceImpl) LIKE(pattern StringExpression) BoolExpression { - return newBinaryBoolOperator(s.parent, pattern, "LIKE") + return newBinaryBoolOperatorExpression(s.parent, pattern, "LIKE") } func (s *stringInterfaceImpl) NOT_LIKE(pattern StringExpression) BoolExpression { - return newBinaryBoolOperator(s.parent, pattern, "NOT LIKE") + return newBinaryBoolOperatorExpression(s.parent, pattern, "NOT LIKE") } func (s *stringInterfaceImpl) REGEXP_LIKE(pattern StringExpression, caseSensitive ...bool) BoolExpression { - return newBinaryBoolOperator(s.parent, pattern, StringRegexpLikeOperator, Bool(len(caseSensitive) > 0 && caseSensitive[0])) + return newBinaryBoolOperatorExpression(s.parent, pattern, StringRegexpLikeOperator, Bool(len(caseSensitive) > 0 && caseSensitive[0])) } func (s *stringInterfaceImpl) NOT_REGEXP_LIKE(pattern StringExpression, caseSensitive ...bool) BoolExpression { - return newBinaryBoolOperator(s.parent, pattern, StringNotRegexpLikeOperator, Bool(len(caseSensitive) > 0 && caseSensitive[0])) + return newBinaryBoolOperatorExpression(s.parent, pattern, StringNotRegexpLikeOperator, Bool(len(caseSensitive) > 0 && caseSensitive[0])) } //---------------------------------------------------// - -type binaryStringExpression struct { - ExpressionInterfaceImpl - stringInterfaceImpl - - binaryOperatorExpression -} - -func newBinaryStringExpression(lhs, rhs Expression, operator string) StringExpression { +func newBinaryStringOperatorExpression(lhs, rhs Expression, operator string) StringExpression { return StringExp(newBinaryOperatorExpression(lhs, rhs, operator)) } diff --git a/postgres/dialect_test.go b/postgres/dialect_test.go index a37c0c9..f53587e 100644 --- a/postgres/dialect_test.go +++ b/postgres/dialect_test.go @@ -27,6 +27,20 @@ func TestExists(t *testing.T) { FROM db.table2 WHERE table1.col1 = table2.col3 ))`, int64(1)) + + assertSerialize(t, EXISTS( + SELECT(Int(1)), + ).EQ(Bool(true)), + `((EXISTS ( + SELECT $1 +)) = $2)`, int64(1), true) + + assertProjectionSerialize(t, EXISTS( + SELECT(Int(1)), + ).AS("exists"), + `(EXISTS ( + SELECT $1 +)) AS "exists"`, int64(1)) } func TestIN(t *testing.T) {