MCPcopy Create free account
hub / github.com/BaseXdb/basex / optimize

Method optimize

basex-core/src/main/java/org/basex/query/expr/Arith.java:40–115  ·  view source on GitHub ↗
(final CompileContext cc)

Source from the content-addressed store, hash-verified

38 }
39
40 @Override
41 public Expr optimize(final CompileContext cc) throws QueryException {
42 exprs = simplifyAll(Simplify.NUMBER, cc);
43 if(values(false, cc)) return cc.preEval(this);
44
45 // move values to second position
46 // 1 + position() → position() + 1
47 Expr expr1 = exprs[0], expr2 = exprs[1];
48 if((calc == Calc.ADD || calc == Calc.MULTIPLY) && expr1 instanceof Value &&
49 !(expr2 instanceof Value)) {
50 cc.info(OPTSWAP_X, this);
51 exprs[0] = expr2;
52 exprs[1] = expr1;
53 expr1 = exprs[0];
54 expr2 = exprs[1];
55 }
56
57 final SeqType st1 = expr1.seqType(), st2 = expr2.seqType();
58 final Type type1 = st1.type, type2 = st2.type;
59 final boolean numbers = type1.isNumberOrUntyped() && type2.isNumberOrUntyped();
60
61 final Type type = calc.type(type1, type2);
62 final boolean noArrays = !st1.mayBeWrapped() && !st2.mayBeWrapped();
63 final boolean oneOrMore = noArrays && st1.oneOrMore() && st2.oneOrMore();
64 exprType.assign(type, oneOrMore ? Occ.EXACTLY_ONE : Occ.ZERO_OR_ONE);
65
66 Expr expr = emptyExpr();
67 // 0 - $x → -$x
68 if(expr == this && expr1 == Itr.ZERO && calc == Calc.SUBTRACT) {
69 expr = new Unary(info, expr2, true).optimize(cc);
70 }
71 // count($n/@*) + count($n/*) → count(($n/@*, $n/*))
72 if(expr == this && Function.COUNT.is(expr1) && calc == Calc.ADD && Function.COUNT.is(expr2)) {
73 expr = cc.function(Function.COUNT, info, List.get(cc, info, expr1.arg(0), expr2.arg(0)));
74 }
75 if(expr == this && numbers && noArrays && st1.one() && st2.one()) {
76 // example: number($a) + 0 → number($a)
77 final Expr ex = calc.optimize(expr1, expr2, info, cc);
78 if(ex != null) {
79 expr = ex;
80 } else if(expr1 instanceof final Arith arth1) {
81 final Calc acalc = arth1.calc;
82 final boolean add = acalc.oneOf(Calc.ADD, Calc.MULTIPLY);
83 final boolean sub = acalc.oneOf(Calc.SUBTRACT, Calc.DIVIDE);
84 final boolean inverse = acalc == calc.invert();
85 final Expr arg1 = arth1.arg(0), arg2 = arth1.arg(1);
86
87 if(arg2 instanceof ANum && expr2 instanceof ANum && (acalc == calc || inverse)) {
88 // (E - 3) + 2 → E - (3 - 2)
89 // (E * 3 div 2 → E * (3 div 2)
90 final Calc ncalc = add ? calc : sub ? calc.invert() : null;
91 if(ncalc != null) expr = new Arith(info, arg1,
92 new Arith(info, arg2, expr2, ncalc).optimize(cc), acalc).optimize(cc);
93 } else if(inverse) {
94 // E + NUMBER - NUMBER → E
95 // NUMBER * E div NUMBER → E
96 expr = arg2.equals(expr2) ? arg1 : arg1.equals(expr2) && add ? arg2 : this;
97 if(expr != this) expr = new Cast(info, expr, Types.NUMERIC_O).optimize(cc);

Callers

nothing calls this directly

Calls 15

seqTypeMethod · 0.95
isNumberOrUntypedMethod · 0.95
mayBeWrappedMethod · 0.95
oneOrMoreMethod · 0.95
getMethod · 0.95
argMethod · 0.95
oneMethod · 0.95
oneOfMethod · 0.95
equalsMethod · 0.95
getMethod · 0.95
zeroOrOneMethod · 0.95
simplifyAllMethod · 0.80

Tested by

no test coverage detected