[jOOQ/jOOQ#14398] Avoid rendering parentheses on left associative operations

This commit is contained in:
Lukas Eder 2024-05-28 13:13:33 +02:00
parent d47a597431
commit aa0ea39a9a
12 changed files with 56 additions and 14 deletions

View File

@ -63,6 +63,7 @@ import java.util.List;
import java.util.Set;
import org.jooq.conf.TransformUnneededArithmeticExpressions;
import org.jooq.impl.Expression.Associativity;
/**
@ -117,7 +118,8 @@ implements
ctx,
this,
q -> new Expression.Expr<>(q.arg1, Operators.OP_PLUS, q.arg2),
c -> c.sql(' ')
c -> c.sql(' '),
Associativity.BOTH
);
ctx.sql(')');
}

View File

@ -52,6 +52,7 @@ import org.jooq.*;
import org.jooq.Function1;
import org.jooq.Record;
import org.jooq.conf.ParamType;
import org.jooq.impl.Expression.Associativity;
import org.jooq.tools.StringUtils;
import java.util.ArrayList;
@ -122,7 +123,8 @@ implements
ctx,
this,
q -> new Expression.Expr<>(q.arg1, Operator.AND.toKeyword(), q.arg2),
Context::formatSeparator
Context::formatSeparator,
Associativity.BOTH
);
ctx.sqlIndentEnd(')');
}

View File

@ -52,6 +52,7 @@ import org.jooq.*;
import org.jooq.Function1;
import org.jooq.Record;
import org.jooq.conf.ParamType;
import org.jooq.impl.Expression.Associativity;
import org.jooq.tools.StringUtils;
import java.util.ArrayList;
@ -171,7 +172,8 @@ implements
ctx,
this,
q -> new Expression.Expr<>(q.arg1, Operators.OP_AMP, q.arg2),
c -> c.sql(' ')
c -> c.sql(' '),
Associativity.BOTH
);
ctx.sql(')');
break;

View File

@ -52,6 +52,7 @@ import org.jooq.*;
import org.jooq.Function1;
import org.jooq.Record;
import org.jooq.conf.ParamType;
import org.jooq.impl.Expression.Associativity;
import org.jooq.tools.StringUtils;
import java.util.ArrayList;
@ -180,7 +181,8 @@ implements
ctx,
this,
q -> new Expression.Expr<>(q.arg1, Operators.OP_VERBAR, q.arg2),
c -> c.sql(' ')
c -> c.sql(' '),
Associativity.BOTH
);
ctx.sql(')');
break;

View File

@ -52,6 +52,7 @@ import org.jooq.*;
import org.jooq.Function1;
import org.jooq.Record;
import org.jooq.conf.ParamType;
import org.jooq.impl.Expression.Associativity;
import org.jooq.tools.StringUtils;
import java.util.ArrayList;
@ -190,7 +191,8 @@ implements
ctx,
this,
q -> new Expression.Expr<>(q.arg1, op, q.arg2),
c -> c.sql(' ')
c -> c.sql(' '),
Associativity.BOTH
);
ctx.sql(')');
break;

View File

@ -63,6 +63,7 @@ import java.util.List;
import java.util.Set;
import org.jooq.conf.TransformUnneededArithmeticExpressions;
import org.jooq.impl.Expression.Associativity;
/**
@ -112,7 +113,15 @@ implements
ctx.sql('(').visit(arg1).sql(" / ").visit(arg2).sql(')');
ctx.sql('(');
Expression.<Field<T>, Div<T>>acceptAssociative(
ctx,
this,
q -> new Expression.Expr<>(q.arg1, Operators.OP_SOL, q.arg2),
c -> c.sql(' '),
Associativity.LEFT
);
ctx.sql(')');
}
@Override

View File

@ -882,12 +882,19 @@ implements
static final record Expr<Q extends QueryPart>(Q lhs, QueryPart op, Q rhs) {}
static enum Associativity {
BOTH,
LEFT,
RIGHT
}
@SuppressWarnings("unchecked")
static final <Q1 extends QueryPart, Q2 extends Q1> void acceptAssociative(
Context<?> ctx,
Q2 exp,
Function<? super Q2, ? extends Expr<Q1>> expProvider,
Consumer<? super Context<?>> formatSeparator
Consumer<? super Context<?>> formatSeparator,
Associativity associativity
) {
Expr<Q1> e = expProvider.apply(exp);
Class<Q2> expType = (Class<Q2>) exp.getClass();
@ -907,7 +914,7 @@ implements
// [#10665] Associativity is only given for two operands of the same data type
// [#12896] ... and if the feature is enabled
boolean associativity = (
boolean a = (
p.lhs instanceof Typed && p.rhs instanceof Typed
? ((Typed<?>) p.lhs).getDataType().equals(((Typed<?>) p.rhs).getDataType())
: true
@ -915,12 +922,12 @@ implements
// [#14356] Delay processing of RHS to emulate depth first
// traversal.
if (associativity && expType.isInstance(p.rhs))
if (a && associativity != Associativity.LEFT && expType.isInstance(p.rhs))
queue.push(expProvider.apply((Q2) p.rhs));
else
queue.push(p.rhs);
if (associativity && expType.isInstance(p.lhs))
if (a && associativity != Associativity.RIGHT && expType.isInstance(p.lhs))
queue.push(expProvider.apply((Q2) p.lhs));
else
elements.add(p.lhs);

View File

@ -63,6 +63,7 @@ import java.util.List;
import java.util.Set;
import org.jooq.conf.TransformUnneededArithmeticExpressions;
import org.jooq.impl.Expression.Associativity;
/**
@ -117,7 +118,8 @@ implements
ctx,
this,
q -> new Expression.Expr<>(q.arg1, Operators.OP_AST, q.arg2),
c -> c.sql(' ')
c -> c.sql(' '),
Associativity.BOTH
);
ctx.sql(')');
}

View File

@ -58,6 +58,7 @@ final class Operators {
static final SQL OP_GT = raw(">");
static final SQL OP_HAT = raw("^");
static final SQL OP_LT = raw("<");
static final SQL OP_MINUS = raw("-");
static final SQL OP_NUM = raw("#");
static final SQL OP_PERCNT = raw("%");
static final SQL OP_PLUS = raw("+");

View File

@ -52,6 +52,7 @@ import org.jooq.*;
import org.jooq.Function1;
import org.jooq.Record;
import org.jooq.conf.ParamType;
import org.jooq.impl.Expression.Associativity;
import org.jooq.tools.StringUtils;
import java.util.ArrayList;
@ -122,7 +123,8 @@ implements
ctx,
this,
q -> new Expression.Expr<>(q.arg1, Operator.OR.toKeyword(), q.arg2),
Context::formatSeparator
Context::formatSeparator,
Associativity.BOTH
);
ctx.sqlIndentEnd(')');
}

View File

@ -63,6 +63,7 @@ import java.util.List;
import java.util.Set;
import org.jooq.conf.TransformUnneededArithmeticExpressions;
import org.jooq.impl.Expression.Associativity;
/**
@ -112,7 +113,15 @@ implements
ctx.sql('(').visit(arg1).sql(" - ").visit(arg2).sql(')');
ctx.sql('(');
Expression.<Field<T>, Sub<T>>acceptAssociative(
ctx,
this,
q -> new Expression.Expr<>(q.arg1, Operators.OP_MINUS, q.arg2),
c -> c.sql(' '),
Associativity.LEFT
);
ctx.sql(')');
}
@Override

View File

@ -52,6 +52,7 @@ import org.jooq.*;
import org.jooq.Function1;
import org.jooq.Record;
import org.jooq.conf.ParamType;
import org.jooq.impl.Expression.Associativity;
import org.jooq.tools.StringUtils;
import java.util.ArrayList;
@ -119,7 +120,8 @@ implements
ctx,
this,
q -> new Expression.Expr<>(q.arg1, Operator.XOR.toKeyword(), q.arg2),
Context::formatSeparator
Context::formatSeparator,
Associativity.BOTH
);
ctx.sqlIndentEnd(')');
}