Skip to content

Commit

Permalink
feat: syntax sugar for Binary Expressions like Conact, Addition, Mult…
Browse files Browse the repository at this point in the history
…iplication

Signed-off-by: Andreas Reichel <[email protected]>
  • Loading branch information
manticore-projects committed Apr 3, 2024
1 parent 2812f75 commit ffddeef
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@

/**
* Analytic function. The name of the function is variable but the parameters following the special
* analytic function path. e.g. row_number() over (order by test). Additional there can be an
* expression for an analytical aggregate like sum(col) or the "all collumns" wildcard like
* count(*).
* analytic function path. e.g. row_number() over (order by test). Additionally, there can be an
* expression for an analytical aggregate like sum(col) or the "all columns" wildcard like count(*).
*
* @author tw
*/
Expand Down
71 changes: 69 additions & 2 deletions src/main/java/net/sf/jsqlparser/expression/BinaryExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@
*/
package net.sf.jsqlparser.expression;

import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Iterator;

/**
* A basic class for binary expressions, that is expressions having a left member and a right member
* which are in turn expressions.
Expand All @@ -20,7 +27,67 @@ public abstract class BinaryExpression extends ASTNodeAccessImpl implements Expr
private Expression leftExpression;
private Expression rightExpression;

public BinaryExpression() {
public BinaryExpression() {}

public BinaryExpression(Expression leftExpression, Expression rightExpression) {
this.leftExpression = leftExpression;
this.rightExpression = rightExpression;
}

public static Expression build(Class<? extends BinaryExpression> clz, Expression... expressions)
throws NoSuchMethodException, InvocationTargetException, InstantiationException,
IllegalAccessException {
switch (expressions.length) {
case 0:
return new NullValue();
case 1:
return expressions[0];
default:
Iterator<Expression> it = Arrays.stream(expressions).iterator();

Expression leftExpression = it.next();
Expression rightExpression = it.next();
BinaryExpression binaryExpression =
clz.getConstructor(Expression.class, Expression.class)
.newInstance(leftExpression, rightExpression);

while (it.hasNext()) {
rightExpression = it.next();
binaryExpression = clz.getConstructor(Expression.class, Expression.class)
.newInstance(binaryExpression, rightExpression);
}
return binaryExpression;
}
}

public static Expression add(Expression... expressions) {
try {
return build(Addition.class, expressions);
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException
| IllegalAccessException e) {
// this should never happen, at least I don't see how
throw new RuntimeException(e);
}
}

public static Expression multiply(Expression... expressions) {
try {
return build(Multiplication.class, expressions);
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException
| IllegalAccessException e) {
// this should never happen, at least I don't see how
throw new RuntimeException(e);
}
}

public static Expression concat(Expression... expressions) {
try {
return build(Concat.class, expressions);
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException
| IllegalAccessException e) {
// this should never happen, at least I don't see how
throw new RuntimeException(e);
}
}

public Expression getLeftExpression() {
Expand Down Expand Up @@ -52,7 +119,7 @@ public void setRightExpression(Expression expression) {
@Override
public String toString() {
return // (not ? "NOT " : "") +
getLeftExpression() + " " + getStringExpression() + " " + getRightExpression();
getLeftExpression() + " " + getStringExpression() + " " + getRightExpression();
}

public abstract String getStringExpression();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@

public class Concat extends BinaryExpression {

public Concat() {}

public Concat(Expression leftExpression, Expression rightExpression) {
super(leftExpression, rightExpression);
}

@Override
public void accept(ExpressionVisitor expressionVisitor) {
expressionVisitor.visit(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package net.sf.jsqlparser.expression.operators.arithmetic;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

class ConcatTest {

@Test
void concatTest() {
Expression expression =
Concat.concat(new StringValue("A"), new StringValue("B"), new StringValue("C"));
Assertions.assertInstanceOf(Concat.class, expression);
Assertions.assertEquals("'A' || 'B' || 'C'", expression.toString());

expression = Concat.concat(new StringValue("A"));
Assertions.assertInstanceOf(StringValue.class, expression);
Assertions.assertEquals("'A'", expression.toString());

expression = Concat.concat();
Assertions.assertInstanceOf(NullValue.class, expression);
Assertions.assertEquals("NULL", expression.toString());
}

void addTest() {
Expression expression = Addition.add(new LongValue(1), new LongValue(2), new LongValue(3));
Assertions.assertInstanceOf(Addition.class, expression);
Assertions.assertEquals("1 + 2 + 3", expression.toString());

expression = Addition.add(new LongValue(1));
Assertions.assertInstanceOf(LongValue.class, expression);
Assertions.assertEquals("1", expression.toString());

expression = Addition.add();
Assertions.assertInstanceOf(NullValue.class, expression);
Assertions.assertEquals("NULL", expression.toString());
}

void multiplyTest() {
Expression expression =
Multiplication.multiply(new LongValue(1), new LongValue(2), new LongValue(3));
Assertions.assertInstanceOf(Addition.class, expression);
Assertions.assertEquals("1 + 2 + 3", expression.toString());

expression = Multiplication.multiply(new LongValue(1));
Assertions.assertInstanceOf(LongValue.class, expression);
Assertions.assertEquals("1", expression.toString());

expression = Multiplication.multiply();
Assertions.assertInstanceOf(NullValue.class, expression);
Assertions.assertEquals("NULL", expression.toString());
}
}

0 comments on commit ffddeef

Please sign in to comment.