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

Method optBoolean

basex-core/src/main/java/org/basex/query/expr/Cmp.java:153–227  ·  view source on GitHub ↗

Tries to rewrite boolean comparisons. @param op operator @param cc compilation context @return optimized or original expression @throws QueryException query exception

(final CmpOp op, final CompileContext cc)

Source from the content-addressed store, hash-verified

151 * @throws QueryException query exception
152 */
153 private Expr optBoolean(final CmpOp op, final CompileContext cc) throws QueryException {
154 final Expr expr1 = exprs[0], expr2 = exprs[1];
155 final SeqType st1 = expr1.seqType(), st2 = expr2.seqType();
156 if(st1.type == BasicType.BOOLEAN && st2.type == BasicType.BOOLEAN) {
157 final boolean eq = op == CmpOp.EQ, ne = op == CmpOp.NE;
158 if(expr2 instanceof Bln) {
159 final boolean ok = expr2 == Bln.TRUE, success = ne ^ ok;
160
161 // boolean(A) = true() → boolean(A)
162 // boolean(A) <= true() → true()
163 if(st1.zeroOrOne() && (success || st1.one())) {
164 final Expr ex1 = st1.one() ? expr1 : cc.function(BOOLEAN, info, expr1);
165 final QuerySupplier<Expr> not = () -> cc.function(NOT, info, ex1);
166 return switch(op) {
167 case EQ -> ok ? ex1 : not.get();
168 case NE -> ok ? not.get() : ex1;
169 case GE -> ok ? ex1 : Bln.TRUE;
170 case LE -> ok ? Bln.TRUE : not.get();
171 case GT -> ok ? Bln.FALSE : ex1;
172 default -> ok ? not.get() : Bln.FALSE;
173 };
174 }
175
176 if(this instanceof CmpG) {
177 // (A, B) = true() → A or B
178 // (A, B) = false() → not(A and B)
179 final Expr[] args = expr1.args();
180 if((eq || ne) && expr1 instanceof List &&
181 ((Checks<Expr>) expr -> expr.seqType().eq(Types.BOOLEAN_O)).all(args)) {
182 return success ? new Or(info, args).optimize(cc) :
183 cc.function(NOT, info, new And(info, args).optimize(cc));
184 }
185
186 if(expr1 instanceof final SimpleMap map) {
187 final int al = args.length - 1;
188 final Expr last = args[al];
189
190 // expr ! true() = true() → exists(expr)
191 if(last instanceof final Bln bln && (eq || ne)) {
192 return bln.bool(info) != success ? Bln.FALSE :
193 cc.function(EXISTS, info, map.remove(cc, al));
194 }
195
196 final Expr[] ops = last.args();
197 if(ops != null && ops.length > 0 && ops[0] instanceof ContextValue) {
198 if(last instanceof final CmpG cmp) {
199 // (name ! (. = 'Ukraine')) = true() → name = 'Ukraine'
200 // (code ! (. = 1)) = false() → code != 1
201 final Expr op2 = ops[1];
202 if(!op2.has(Flag.CTX) && (eq && ok || op2.seqType().one())) {
203 CmpOp cmpOp = cmp.op;
204 if(!success) cmpOp = cmpOp.invert();
205 return new CmpG(info, map.remove(cc, al), op2, cmpOp).optimize(cc);
206 }
207 } else if(success && last instanceof final CmpR cmp) {
208 // (number ! (. >= 1e0) = true() → number >= 1e0
209 return CmpR.get(cc, info, map.remove(cc, al), cmp.min, cmp.max);
210 } else if(success && last instanceof final CmpIR cmp) {

Callers 1

optMethod · 0.95

Calls 15

seqTypeMethod · 0.95
zeroOrOneMethod · 0.95
oneMethod · 0.95
argsMethod · 0.95
hasMethod · 0.95
invertMethod · 0.95
getMethod · 0.95
getMethod · 0.95
equalsMethod · 0.95
argMethod · 0.95
getMethod · 0.95
getMethod · 0.65

Tested by

no test coverage detected