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

Method opt

basex-core/src/main/java/org/basex/query/expr/If.java:92–140  ·  view source on GitHub ↗

Optimizes the expression. @param cc compilation context @return optimized or original expression @throws QueryException query exception

(final CompileContext cc)

Source from the content-addressed store, hash-verified

90 * @throws QueryException query exception
91 */
92 private Expr opt(final CompileContext cc) throws QueryException {
93 // choose static branch at compile time
94 if(cond instanceof Value) return expr(cc.qc);
95
96 // if(...empty sequence...) then A else B → B
97 final Expr br1 = exprs[0], br2 = exprs[1];
98 final SeqType ct = cond.seqType();
99 final boolean ndt = cond.has(Flag.NDT);
100 if(ct.zero() && !ndt) return br2;
101
102 // rewrite to otherwise:
103 // if(exists(VALUE)) then VALUE else DEFAULT → VALUE otherwise DEFAULT
104 // if(NODES) then NODES else DEFAULT → NODES otherwise DEFAULT
105 final Expr cmp = EXISTS.is(cond) ? cond.arg(0) : ct.type instanceof NodeType ? cond : null;
106 if(!ndt && cmp != null && cmp.equals(br1)) return new Otherwise(info, br1, br2).optimize(cc);
107
108 // if(A) then B else B → void(A), B
109 if(br1.equals(br2)) return cc.voidAndReturn(cond, br1, info);
110
111 // determine type
112 final SeqType st1 = br1.seqType(), st2 = br2.seqType();
113 exprType.assign(st1.union(st2)).data(exprs);
114
115 // logical rewritings
116 if(st1.eq(Types.BOOLEAN_O) && st2.eq(Types.BOOLEAN_O)) {
117 if(br1 == Bln.TRUE) return br2 == Bln.FALSE ?
118 // if(A) then true() else false() → boolean(A)
119 cc.function(BOOLEAN, info, cond) :
120 // if(A) then true() else C → A or C
121 new Or(info, cond, br2).optimize(cc);
122 if(br2 == Bln.TRUE) return br1 == Bln.FALSE ?
123 // if(A) then false() else true() → not(A)
124 cc.function(NOT, info, cond) :
125 // if(A) then B else true() → not(A) or B
126 new Or(info, cc.function(NOT, info, cond), br1).optimize(cc);
127 // if(A) then false() else C → not(A) and C
128 if(br1 == Bln.FALSE) return
129 new And(info, cc.function(NOT, info, cond), br2).optimize(cc);
130 // if(A) then B else false() → A and B
131 if(br2 == Bln.FALSE) return
132 new And(info, cond, br1).optimize(cc);
133
134 if(contradict(br1, br2, false)) return new CmpG(
135 info, cc.function(BOOLEAN, info, cond), br1, CmpOp.EQ).optimize(cc);
136 if(contradict(br2, br1, false)) return new CmpG(
137 info, cc.function(BOOLEAN, info, cond), br2, CmpOp.NE).optimize(cc);
138 }
139 return this;
140 }
141
142 /**
143 * Swaps the arguments.

Callers 3

optimizeMethod · 0.95
optimizeMethod · 0.45
optimizeMethod · 0.45

Calls 15

exprMethod · 0.95
zeroMethod · 0.95
equalsMethod · 0.95
seqTypeMethod · 0.95
unionMethod · 0.95
eqMethod · 0.95
voidAndReturnMethod · 0.80
contradictMethod · 0.80
seqTypeMethod · 0.65
isMethod · 0.65
hasMethod · 0.45
argMethod · 0.45

Tested by

no test coverage detected