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

Method optimize

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

Source from the content-addressed store, hash-verified

49 }
50
51 @Override
52 public final Expr optimize(final CompileContext cc) throws QueryException {
53 // pre-evaluate if one value is empty:
54 // () eq local:expensive() → ()
55 // void(123) = 1 → boolean(void('123'))
56 Expr expr = emptyExpr();
57 if(expr != this) return cc.replaceWith(this, cc.function(BOOLEAN, info, expr));
58
59 // remove redundant type conversions
60 final Type t1 = exprs[0].seqType().type.atomic(), t2 = exprs[1].seqType().type.atomic();
61 if(t1 != null && t2 != null) {
62 if(t1.isStringOrUntyped() && t2.isStringOrUntyped()) {
63 exprs = simplifyAll(Simplify.STRING, cc);
64 } else if(t1.isNumber() && t2.isNumber()) {
65 exprs = simplifyAll(Simplify.NUMBER, cc);
66 }
67 }
68
69 // simplify operands
70 exprs = simplifyAll(Simplify.DISTINCT, cc);
71
72 // swap operands
73 if(swap()) {
74 cc.info(QueryText.OPTSWAP_X, this);
75 Collections.reverse(Arrays.asList(exprs));
76 op = op.swap();
77 }
78
79 // optimize expression
80 expr = opt(cc);
81
82 // (if(A) then B else C) = X → if(A) then B = X else C = X
83 final Expr expr1 = exprs[0], expr2 = exprs[1];
84 if(expr == this && expr1 instanceof final If iff && !expr1.has(Flag.NDT)) {
85 final Expr thn = new CmpG(info, iff.arg(0), expr2, op);
86 final Expr els = new CmpG(info, iff.arg(1), expr2.copy(cc, new IntObjectMap<>()), op);
87 return new If(info, iff.cond, thn.optimize(cc), els.optimize(cc)).optimize(cc);
88 }
89
90 if(expr == this) expr = optArith(cc);
91 if(expr == this) expr = CmpIR.get(cc, this, false);
92 if(expr == this) expr = CmpR.get(cc, this);
93 if(expr == this) expr = CmpSR.get(cc, this);
94 if(expr == this) {
95 // skip runtime type check if items are known to be comparable
96 final SeqType st1 = expr1.seqType(), st2 = expr2.seqType();
97 final Type type1 = st1.type, type2 = st2.type;
98 if(type1 == type2 && !type1.oneOf(BasicType.ANY_ATOMIC_TYPE, BasicType.ITEM)
99 || type1.isUntyped() || type2.isUntyped()
100 || type1.isNumber() && type2.isNumber()
101 || type1.isStringOrUntyped() && type2.isStringOrUntyped()
102 || type1.instanceOf(BasicType.BINARY) && type2.instanceOf(BasicType.BINARY)
103 || type1.instanceOf(BasicType.DURATION) && type2.instanceOf(BasicType.DURATION)) {
104 comparable = true;
105 }
106
107 // choose best implementation
108 if(st1.zeroOrOne() && !st1.mayBeWrapped() && st2.zeroOrOne() && !st2.mayBeWrapped()) {

Callers 4

toIfMethod · 0.95
optArithMethod · 0.45
mergeEbvMethod · 0.45
optPredMethod · 0.45

Calls 15

isStringOrUntypedMethod · 0.95
isNumberMethod · 0.95
hasMethod · 0.95
copyMethod · 0.95
optArithMethod · 0.95
getMethod · 0.95
getMethod · 0.95
getMethod · 0.95
seqTypeMethod · 0.95
oneOfMethod · 0.95
isUntypedMethod · 0.95
instanceOfMethod · 0.95

Tested by

no test coverage detected