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

Method mergePaths

basex-core/src/main/java/org/basex/query/expr/Set.java:109–194  ·  view source on GitHub ↗

Tries to merge paths. @param cc compilation context @return merged expression or null @throws QueryException query exception

(final CompileContext cc)

Source from the content-addressed store, hash-verified

107 * @throws QueryException query exception
108 */
109 private Expr mergePaths(final CompileContext cc) throws QueryException {
110 Expr root = null;
111 Axis axis = null;
112 final int sl = exprs.length;
113 final ArrayList<Step> steps = new ArrayList<>(sl);
114
115 // collect common root, common axis, and individual steps
116 for(final Expr expr : exprs) {
117 if(!(expr instanceof final Path path)) return null;
118 if(path.steps.length != 1 || !(path.steps[0] instanceof final Step step)) return null;
119 if(steps.isEmpty()) {
120 root = path.root;
121 axis = step.axis;
122 if(root != null && root.has(Flag.CNS, Flag.NDT)) return null;
123 } else if(!Objects.equals(root, path.root) || axis != step.axis) {
124 // further operands: abort if root or axis differs
125 return null;
126 }
127 // do not merge paths with positional predicates
128 if(step.mayBePositional()) return null;
129 steps.add(step);
130 }
131
132 // try to merge tests (precondition: predicates are identical)
133 Expr[] preds = null;
134 final ArrayList<Test> tests = new ArrayList<>(sl);
135 for(int s = 0; s < sl; s++) {
136 final Step step = steps.get(s);
137 if(preds == null) {
138 preds = step.exprs;
139 } else if(!Arrays.equals(preds, step.exprs)) {
140 preds = null;
141 break;
142 }
143 tests.add(step.test);
144 }
145
146 Test test = null;
147 if(preds != null) {
148 if(this instanceof Union) {
149 // a union b → (a|b)
150 test = Test.get(tests);
151 } else if(this instanceof Intersect) {
152 // * intersect a → a, a intersect b → ()
153 for(final Test t : tests) {
154 if(test == null || t.instanceOf(test)) {
155 test = t;
156 } else if(test.intersect(t) == null) {
157 return Empty.VALUE;
158 }
159 }
160 } else {
161 // a except a → (), a except * → ()
162 for(final Test t : tests) {
163 if(test == null) {
164 test = t;
165 } else if(test.instanceOf(t)) {
166 return Empty.VALUE;

Callers 1

optimizeMethod · 0.95

Calls 15

hasMethod · 0.95
getMethod · 0.95
intersectMethod · 0.95
instanceOfMethod · 0.95
newPredicateMethod · 0.95
mergePredicatesMethod · 0.95
getMethod · 0.95
getMethod · 0.95
addMethod · 0.65
getMethod · 0.65
instanceOfMethod · 0.65
isEmptyMethod · 0.45

Tested by

no test coverage detected