Merge lp:~mmcm/akiban-server/product-nested into lp:~akiban-technologies/akiban-server/trunk
- product-nested
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Mike McMahon |
Approved revision: | 2723 |
Merged at revision: | 2704 |
Proposed branch: | lp:~mmcm/akiban-server/product-nested |
Merge into: | lp:~akiban-technologies/akiban-server/trunk |
Prerequisite: | lp:~mmcm/akiban-server/query-bindings-cancel |
Diff against target: |
1496 lines (+316/-429) 25 files modified
src/main/java/com/akiban/qp/operator/API.java (+34/-2) src/main/java/com/akiban/qp/operator/BranchLookup_Nested.java (+23/-15) src/main/java/com/akiban/qp/operator/Map_NestedLoops.java (+3/-2) src/main/java/com/akiban/qp/operator/Product_Nested.java (+57/-253) src/main/java/com/akiban/server/explain/Type.java (+1/-0) src/main/java/com/akiban/server/explain/format/DefaultFormatter.java (+11/-5) src/main/java/com/akiban/sql/optimizer/rule/OperatorAssembler.java (+21/-15) src/test/java/com/akiban/server/test/it/qp/Map_NestedLoopsIT.java (+1/-1) src/test/java/com/akiban/server/test/it/qp/Product3WayIT.java (+50/-30) src/test/java/com/akiban/server/test/it/qp/Product_NestedIT.java (+26/-32) src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiindex-multi-duplicate.expected (+7/-6) src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiindex-multi-ordered.expected (+7/-6) src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiple-table-conds-1.expected (+7/-6) src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiple-table-conds-1.t3expected (+7/-6) src/test/resources/com/akiban/sql/optimizer/operator/coia-group-index/select-17bu.expected (+6/-5) src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2.expected (+6/-5) src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2n.expected (+6/-5) src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2v.expected (+6/-5) src/test/resources/com/akiban/sql/optimizer/operator/coia/select-2.expected (+5/-4) src/test/resources/com/akiban/sql/optimizer/operator/coia/select-5.expected (+5/-4) src/test/resources/com/akiban/sql/optimizer/operator/coia/select-6.expected (+5/-4) src/test/resources/com/akiban/sql/optimizer/operator/coia/select-7.expected (+5/-4) src/test/resources/com/akiban/sql/optimizer/operator/coia/select-8.expected (+6/-5) src/test/resources/com/akiban/sql/optimizer/rule/operator/full-text-2.expected (+6/-5) src/test/resources/com/akiban/sql/optimizer/rule/operator/select-5.expected (+5/-4) |
To merge this branch: | bzr merge lp:~mmcm/akiban-server/product-nested |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nathan Williams | Approve | ||
Review via email: mp+175519@code.launchpad.net |
Commit message
Description of the change
Replace Product_NestedLoops with Product_Nested.
The new operator is much simpler: it produces a Product row of its input row and a bound row.
There was some subtlety to Product_
(1) It maintained a cache by common ancestor hkey and didn't re-run the inner loop sometimes. While it's possible for ancestors to just happen to coincide from any secondary index, the cases where they do so reliably are rare, mostly involving GroupScans. Since maintaining this cache means keeping all the inner rows, I'm not sure it's worth it in balance. Presumably database caches will have the inner rows in memory at least.
(2) The row set in the bindings is not the one used for the product, but the common ancestor. This isn't possible with Map_NestedLoops. But it's just as easy to do the ancestor in BranchLookup_
Some notes on the relevant ITs:
Product_
Product2WayIT had a comment about run ids, which again was from long ago. Also it was reusing binding slots for each loop, which isn't reliable, even if the Maps nest on the outer side, because the second inner row of the outer loop is allowed to assume that the bound value is still there. This worked okay with nested Product_
- 2722. By Mike McMahon
-
Merge from trunk.
- 2723. By Mike McMahon
-
Missed one.
Preview Diff
1 | === modified file 'src/main/java/com/akiban/qp/operator/API.java' |
2 | --- src/main/java/com/akiban/qp/operator/API.java 2013-07-13 21:17:31 +0000 |
3 | +++ src/main/java/com/akiban/qp/operator/API.java 2013-07-18 16:47:28 +0000 |
4 | @@ -210,6 +210,7 @@ |
5 | int inputBindingPosition) |
6 | { |
7 | return new BranchLookup_Nested(group, |
8 | + inputRowType, |
9 | inputRowType, |
10 | null, |
11 | outputRowType, |
12 | @@ -225,6 +226,7 @@ |
13 | int inputBindingPosition) |
14 | { |
15 | return new BranchLookup_Nested(group, |
16 | + inputRowType, |
17 | inputRowType, |
18 | ancestorRowType, |
19 | outputRowType, |
20 | @@ -232,6 +234,23 @@ |
21 | inputBindingPosition); |
22 | } |
23 | |
24 | + public static Operator branchLookup_Nested(Group group, |
25 | + RowType inputRowType, |
26 | + RowType sourceRowType, |
27 | + UserTableRowType ancestorRowType, |
28 | + UserTableRowType outputRowType, |
29 | + InputPreservationOption flag, |
30 | + int inputBindingPosition) |
31 | + { |
32 | + return new BranchLookup_Nested(group, |
33 | + inputRowType, |
34 | + sourceRowType, |
35 | + ancestorRowType, |
36 | + outputRowType, |
37 | + flag, |
38 | + inputBindingPosition); |
39 | + } |
40 | + |
41 | // Limit |
42 | |
43 | public static Operator limit_Default(Operator inputOperator, int limitRows) |
44 | @@ -448,9 +467,10 @@ |
45 | RowType innerType, |
46 | int inputBindingPosition) |
47 | { |
48 | - return new Product_NestedLoops(outerInput, innerInput, outerType, null, innerType, inputBindingPosition); |
49 | + return product_NestedLoops(outerInput, innerInput, outerType, null, innerType, inputBindingPosition); |
50 | } |
51 | |
52 | + /** deprecated */ |
53 | public static Operator product_NestedLoops(Operator outerInput, |
54 | Operator innerInput, |
55 | RowType outerType, |
56 | @@ -458,7 +478,19 @@ |
57 | RowType innerType, |
58 | int inputBindingPosition) |
59 | { |
60 | - return new Product_NestedLoops(outerInput, innerInput, outerType, branchType, innerType, inputBindingPosition); |
61 | + return map_NestedLoops(outerInput, |
62 | + product_Nested(innerInput, outerType, branchType, innerType, inputBindingPosition), |
63 | + inputBindingPosition, |
64 | + false, 0); |
65 | + } |
66 | + |
67 | + public static Operator product_Nested(Operator input, |
68 | + RowType outerType, |
69 | + UserTableRowType branchType, |
70 | + RowType inputType, |
71 | + int bindingPosition) |
72 | + { |
73 | + return new Product_Nested(input, outerType, branchType, inputType, bindingPosition); |
74 | } |
75 | |
76 | // Count |
77 | |
78 | === modified file 'src/main/java/com/akiban/qp/operator/BranchLookup_Nested.java' |
79 | --- src/main/java/com/akiban/qp/operator/BranchLookup_Nested.java 2013-07-17 18:15:10 +0000 |
80 | +++ src/main/java/com/akiban/qp/operator/BranchLookup_Nested.java 2013-07-18 16:47:28 +0000 |
81 | @@ -56,7 +56,9 @@ |
82 | <li><b>GroupTable groupTable:</b> The group table containing the |
83 | ancestors of interest. |
84 | |
85 | - <li><b>RowType inputRowType:</b> Branches will be located for input |
86 | + <li><b>RowType inputRowType:</b> Bound row will be of this type. |
87 | + |
88 | + <li><b>RowType sourceRowType:</b> Branches will be located for input |
89 | rows of this type. |
90 | |
91 | <li><b>UserTableRowType ancestorRowType:</b> Identifies the table in the group at which branching occurs. |
92 | @@ -136,7 +138,7 @@ |
93 | return String.format("%s(%s %s -> %s)", |
94 | getClass().getSimpleName(), |
95 | group.getRoot().getName(), |
96 | - inputRowType, |
97 | + sourceRowType, |
98 | outputRowType); |
99 | } |
100 | |
101 | @@ -163,6 +165,7 @@ |
102 | |
103 | public BranchLookup_Nested(Group group, |
104 | RowType inputRowType, |
105 | + RowType sourceRowType, |
106 | UserTableRowType ancestorRowType, |
107 | UserTableRowType outputRowType, |
108 | API.InputPreservationOption flag, |
109 | @@ -170,21 +173,22 @@ |
110 | { |
111 | ArgumentValidation.notNull("group", group); |
112 | ArgumentValidation.notNull("inputRowType", inputRowType); |
113 | + ArgumentValidation.notNull("sourceRowType", sourceRowType); |
114 | ArgumentValidation.notNull("outputRowType", outputRowType); |
115 | ArgumentValidation.notNull("flag", flag); |
116 | - ArgumentValidation.isTrue("inputRowType instanceof UserTableRowType || flag == API.InputPreservationOption.DISCARD_INPUT", |
117 | - inputRowType instanceof UserTableRowType || flag == API.InputPreservationOption.DISCARD_INPUT); |
118 | + ArgumentValidation.isTrue("sourceRowType instanceof UserTableRowType || flag == API.InputPreservationOption.DISCARD_INPUT", |
119 | + sourceRowType instanceof UserTableRowType || flag == API.InputPreservationOption.DISCARD_INPUT); |
120 | ArgumentValidation.isGTE("hKeyBindingPosition", inputBindingPosition, 0); |
121 | UserTableRowType inputTableType = null; |
122 | - if (inputRowType instanceof UserTableRowType) { |
123 | - inputTableType = (UserTableRowType) inputRowType; |
124 | - } else if (inputRowType instanceof IndexRowType) { |
125 | - inputTableType = ((IndexRowType) inputRowType).tableType(); |
126 | - } else if (inputRowType instanceof HKeyRowType) { |
127 | + if (sourceRowType instanceof UserTableRowType) { |
128 | + inputTableType = (UserTableRowType) sourceRowType; |
129 | + } else if (sourceRowType instanceof IndexRowType) { |
130 | + inputTableType = ((IndexRowType) sourceRowType).tableType(); |
131 | + } else if (sourceRowType instanceof HKeyRowType) { |
132 | Schema schema = outputRowType.schema(); |
133 | - inputTableType = schema.userTableRowType(inputRowType.hKey().userTable()); |
134 | + inputTableType = schema.userTableRowType(sourceRowType.hKey().userTable()); |
135 | } |
136 | - assert inputTableType != null : inputRowType; |
137 | + assert inputTableType != null : sourceRowType; |
138 | UserTable inputTable = inputTableType.userTable(); |
139 | UserTable outputTable = outputRowType.userTable(); |
140 | ArgumentValidation.isSame("inputTable.getGroup()", |
141 | @@ -193,6 +197,7 @@ |
142 | outputTable.getGroup()); |
143 | this.group = group; |
144 | this.inputRowType = inputRowType; |
145 | + this.sourceRowType = sourceRowType; |
146 | this.outputRowType = outputRowType; |
147 | this.keepInput = flag == API.InputPreservationOption.KEEP_INPUT; |
148 | this.inputBindingPosition = inputBindingPosition; |
149 | @@ -262,7 +267,7 @@ |
150 | // Object state |
151 | |
152 | private final Group group; |
153 | - private final RowType inputRowType; |
154 | + private final RowType inputRowType, sourceRowType; |
155 | private final UserTableRowType outputRowType; |
156 | private final boolean keepInput; |
157 | // If keepInput is true, inputPrecedesBranch controls whether input row appears before the retrieved branch. |
158 | @@ -278,9 +283,9 @@ |
159 | atts.put(Label.BINDING_POSITION, PrimitiveExplainer.getInstance(inputBindingPosition)); |
160 | atts.put(Label.OUTPUT_TYPE, outputRowType.getExplainer(context)); |
161 | UserTableRowType ancestorRowType = outputRowType.schema().userTableRowType(commonAncestor); |
162 | - if ((ancestorRowType != inputRowType) && (ancestorRowType != outputRowType)) |
163 | + if ((ancestorRowType != sourceRowType) && (ancestorRowType != outputRowType)) |
164 | atts.put(Label.ANCESTOR_TYPE, ancestorRowType.getExplainer(context)); |
165 | - return new LookUpOperatorExplainer(getName(), atts, inputRowType, false, null, context); |
166 | + return new LookUpOperatorExplainer(getName(), atts, sourceRowType, false, null, context); |
167 | } |
168 | |
169 | // Inner classes |
170 | @@ -296,10 +301,13 @@ |
171 | try { |
172 | CursorLifecycle.checkIdle(this); |
173 | Row rowFromBindings = bindings.getRow(inputBindingPosition); |
174 | + assert rowFromBindings.rowType() == inputRowType : rowFromBindings; |
175 | + if (inputRowType != sourceRowType) { |
176 | + rowFromBindings = rowFromBindings.subRow(sourceRowType); |
177 | + } |
178 | if (LOG_EXECUTION) { |
179 | LOG.debug("BranchLookup_Nested: open using {}", rowFromBindings); |
180 | } |
181 | - assert rowFromBindings.rowType() == inputRowType : rowFromBindings; |
182 | computeLookupRowHKey(rowFromBindings); |
183 | cursor.rebind(hKey, true); |
184 | cursor.open(); |
185 | |
186 | === modified file 'src/main/java/com/akiban/qp/operator/Map_NestedLoops.java' |
187 | --- src/main/java/com/akiban/qp/operator/Map_NestedLoops.java 2013-07-18 13:05:48 +0000 |
188 | +++ src/main/java/com/akiban/qp/operator/Map_NestedLoops.java 2013-07-18 16:47:28 +0000 |
189 | @@ -76,7 +76,7 @@ |
190 | |
191 | <h1>Performance</h1> |
192 | |
193 | - Product_NestedLoops does no IO. |
194 | + Map_NestedLoops does no IO. |
195 | |
196 | <h1>Memory Requirements</h1> |
197 | |
198 | @@ -135,7 +135,8 @@ |
199 | ArgumentValidation.notNull("outerInputOperator", outerInputOperator); |
200 | ArgumentValidation.notNull("innerInputOperator", innerInputOperator); |
201 | ArgumentValidation.isGTE("inputBindingPosition", inputBindingPosition, 0); |
202 | - ArgumentValidation.isGT("depth", depth, 0); |
203 | + if (pipeline) |
204 | + ArgumentValidation.isGT("depth", depth, 0); |
205 | this.outerInputOperator = outerInputOperator; |
206 | this.innerInputOperator = innerInputOperator; |
207 | this.inputBindingPosition = inputBindingPosition; |
208 | |
209 | === renamed file 'src/main/java/com/akiban/qp/operator/Product_NestedLoops.java' => 'src/main/java/com/akiban/qp/operator/Product_Nested.java' |
210 | --- src/main/java/com/akiban/qp/operator/Product_NestedLoops.java 2013-07-18 13:05:48 +0000 |
211 | +++ src/main/java/com/akiban/qp/operator/Product_Nested.java 2013-07-18 16:47:28 +0000 |
212 | @@ -22,9 +22,7 @@ |
213 | import com.akiban.qp.rowtype.ProductRowType; |
214 | import com.akiban.qp.rowtype.RowType; |
215 | import com.akiban.qp.rowtype.UserTableRowType; |
216 | -import com.akiban.server.explain.CompoundExplainer; |
217 | -import com.akiban.server.explain.ExplainContext; |
218 | -import com.akiban.server.explain.std.NestedLoopsExplainer; |
219 | +import com.akiban.server.explain.*; |
220 | import com.akiban.util.ArgumentValidation; |
221 | import com.akiban.util.ShareHolder; |
222 | import com.akiban.util.tap.InOutTap; |
223 | @@ -39,7 +37,7 @@ |
224 | |
225 | <h1>Overview</h1> |
226 | |
227 | - Product_NestedLoops computes the cartesian product of child rows owned by the same parent row. For example, if customer c1 has orders o10 and o11, and addresses a10 and a11; and customer c2 has order o20 and address a20, then Product_NestedLoops computes \{o10, o11\} x \{a10, a11\} for c1, and \{o20\} x \{a20\} for c2. |
228 | + Product_Nested computes the cartesian product of child rows owned by the same parent row. For example, if customer c1 has orders o10 and o11, and addresses a10 and a11; and customer c2 has order o20 and address a20, then Product_Nested computes \{o10, o11\} x \{a10, a11\} for c1, and \{o20\} x \{a20\} for c2. |
229 | |
230 | <h1>Arguments</h1> |
231 | |
232 | @@ -48,34 +46,32 @@ |
233 | <li><b>RowType outerType:</b> Type of one child row. parent rows to be |
234 | flattened. |
235 | |
236 | - <li><b>UserTableRowType branchType:</b> Ancestor type of outerType and innerType. Output will consist |
237 | - of the cartesian product of outer and inner rows that match when projected to the branch type. |
238 | - |
239 | - <li><b>RowType innerType:</b> Type of the other child row. |
240 | - |
241 | - <li><b>int inputBindingPosition:</b> The position in the bindings that |
242 | + <li><b>UserTableRowType branchType:</b> Ancestor type of outerType and inputType. Output will consist |
243 | + of the cartesian product of outer and input rows that match when projected to the branch type. |
244 | + |
245 | + <li><b>RowType inputType:</b> Type of the other child row. |
246 | + |
247 | + <li><b>int bindingPosition:</b> The position in the bindings that |
248 | will be used to pass rows from the outer loop to the inner loop. |
249 | |
250 | </ul> |
251 | |
252 | - The input types must have resulted from Flattens of some common |
253 | + The row types must have resulted from Flattens of some common |
254 | ancestor, e.g. Flatten(customer, order) and Flatten(customer, |
255 | address). |
256 | |
257 | <h1>Behavior</h1> |
258 | |
259 | Suppose we have a COA schema (C is the parent of O and A), and that we |
260 | - have flattened C with O, and C with A. Product_NestedLoops has two |
261 | + have flattened C with O, and C with A. Product_Nested has two |
262 | input streams, with CO in one and CA in the other. The branch type is C. |
263 | For this discussion, let's assume that CO is the outer stream, and CA is in the |
264 | - inner stream. The terms "outer" and "inner" reflect the relative |
265 | - positions of the inputs in the nested loops used to compute the |
266 | - product of the inputs. |
267 | + input stream. |
268 | |
269 | - For each CO row from the outer input stream, a set of matching CA rows, |
270 | + For each CO row from the outer stream, a set of matching CA rows, |
271 | (i.e., matching in C) |
272 | - from the inner input stream are retrieved. The CO row and all of the |
273 | - CA rows will have the same customer primary key. Product_NestedLoops |
274 | + from the input stream are retrieved. The CO row and all of the |
275 | + CA rows will have the same customer primary key. Product_Nested |
276 | will write to the output stream product rows for each CO/CA |
277 | combination. |
278 | |
279 | @@ -93,31 +89,31 @@ |
280 | |
281 | <h1>Performance</h1> |
282 | |
283 | - Product_NestedLoops does no IO. |
284 | - |
285 | - <h1>Memory Requirements</h1> |
286 | - |
287 | - For each outer row, all matching rows from the inner input are kept in |
288 | - memory. This avoids the need to retrieve the inner rows repeatedly in |
289 | - situations where consecutive outer rows match the same inner rows, |
290 | - e.g. for hkey-ordered outer rows. |
291 | + Product_Nested does no IO. |
292 | |
293 | */ |
294 | |
295 | -class Product_NestedLoops extends Operator |
296 | +class Product_Nested extends Operator |
297 | { |
298 | // Object interface |
299 | |
300 | @Override |
301 | public String toString() |
302 | { |
303 | - return String.format("%s(%s x %s)", getClass().getSimpleName(), outerType, innerType); |
304 | + return String.format("%s(%s x %s)", getClass().getSimpleName(), outerType, inputType); |
305 | } |
306 | |
307 | @Override |
308 | public CompoundExplainer getExplainer(ExplainContext context) |
309 | { |
310 | - return new NestedLoopsExplainer(getName(), innerInputOperator, outerInputOperator, innerType, outerType, context); |
311 | + Attributes atts = new Attributes(); |
312 | + |
313 | + atts.put(Label.NAME, PrimitiveExplainer.getInstance(getName())); |
314 | + atts.put(Label.OUTER_TYPE, outerType.getExplainer(context)); |
315 | + atts.put(Label.INNER_TYPE, inputType.getExplainer(context)); |
316 | + atts.put(Label.INPUT_OPERATOR, inputOperator.getExplainer(context)); |
317 | + atts.put(Label.BINDING_POSITION, PrimitiveExplainer.getInstance(bindingPosition)); |
318 | + return new CompoundExplainer(Type.PRODUCT_OPERATOR, atts); |
319 | } |
320 | |
321 | // Operator interface |
322 | @@ -125,7 +121,7 @@ |
323 | @Override |
324 | protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
325 | { |
326 | - return new Execution(context, bindingsCursor); |
327 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
328 | } |
329 | |
330 | @Override |
331 | @@ -137,8 +133,7 @@ |
332 | @Override |
333 | public void findDerivedTypes(Set<RowType> derivedTypes) |
334 | { |
335 | - innerInputOperator.findDerivedTypes(derivedTypes); |
336 | - outerInputOperator.findDerivedTypes(derivedTypes); |
337 | + inputOperator.findDerivedTypes(derivedTypes); |
338 | derivedTypes.add(productType); |
339 | } |
340 | |
341 | @@ -146,76 +141,58 @@ |
342 | public List<Operator> getInputOperators() |
343 | { |
344 | List<Operator> result = new ArrayList<>(2); |
345 | - result.add(outerInputOperator); |
346 | - result.add(innerInputOperator); |
347 | + result.add(inputOperator); |
348 | return result; |
349 | } |
350 | |
351 | @Override |
352 | public String describePlan() |
353 | { |
354 | - return describePlan(outerInputOperator); |
355 | + return describePlan(inputOperator); |
356 | } |
357 | |
358 | - // Product_NestedLoops interface |
359 | + // Product_Nested interface |
360 | |
361 | - public Product_NestedLoops(Operator outerInputOperator, |
362 | - Operator innerInputOperator, |
363 | - RowType outerType, |
364 | - UserTableRowType branchType, |
365 | - RowType innerType, |
366 | - int inputBindingPosition) |
367 | + public Product_Nested(Operator inputOperator, |
368 | + RowType outerType, |
369 | + UserTableRowType branchType, |
370 | + RowType inputType, |
371 | + int bindingPosition) |
372 | { |
373 | - ArgumentValidation.notNull("outerInputOperator", outerInputOperator); |
374 | - ArgumentValidation.notNull("innerInputOperator", innerInputOperator); |
375 | + ArgumentValidation.notNull("inputOperator", inputOperator); |
376 | ArgumentValidation.notNull("outerType", outerType); |
377 | - ArgumentValidation.notNull("innerType", innerType); |
378 | - ArgumentValidation.isGTE("inputBindingPosition", inputBindingPosition, 0); |
379 | - this.outerInputOperator = outerInputOperator; |
380 | - this.innerInputOperator = innerInputOperator; |
381 | + ArgumentValidation.notNull("inputType", inputType); |
382 | + ArgumentValidation.isGTE("bindingPosition", bindingPosition, 0); |
383 | + this.inputOperator = inputOperator; |
384 | this.outerType = outerType; |
385 | - this.innerType = innerType; |
386 | - this.productType = outerType.schema().newProductType(outerType, branchType, innerType); |
387 | + this.inputType = inputType; |
388 | + this.productType = inputType.schema().newProductType(outerType, branchType, inputType); |
389 | this.branchType = productType.branchType(); |
390 | - this.inputBindingPosition = inputBindingPosition; |
391 | + this.bindingPosition = bindingPosition; |
392 | } |
393 | |
394 | // Class state |
395 | |
396 | - private static InOutTap TAP_OPEN = OPERATOR_TAP.createSubsidiaryTap("operator: Product_NestedLoops open"); |
397 | - private static InOutTap TAP_NEXT = OPERATOR_TAP.createSubsidiaryTap("operator: Product_NestedLoops next"); |
398 | - private static final Logger LOG = LoggerFactory.getLogger(Product_NestedLoops.class); |
399 | + private static InOutTap TAP_OPEN = OPERATOR_TAP.createSubsidiaryTap("operator: Product_Nested open"); |
400 | + private static InOutTap TAP_NEXT = OPERATOR_TAP.createSubsidiaryTap("operator: Product_Nested next"); |
401 | + private static final Logger LOG = LoggerFactory.getLogger(Product_Nested.class); |
402 | |
403 | // Object state |
404 | |
405 | - private final Operator outerInputOperator; |
406 | - private final Operator innerInputOperator; |
407 | + private final Operator inputOperator; |
408 | private final RowType branchType; |
409 | private final RowType outerType; |
410 | - private final RowType innerType; |
411 | + private final RowType inputType; |
412 | private final ProductRowType productType; |
413 | - private final int inputBindingPosition; |
414 | + private final int bindingPosition; |
415 | |
416 | // Inner classes |
417 | |
418 | - private class Execution extends OperatorCursor |
419 | + private class Execution extends ChainedCursor |
420 | { |
421 | // Cursor interface |
422 | |
423 | @Override |
424 | - public void open() |
425 | - { |
426 | - TAP_OPEN.in(); |
427 | - try { |
428 | - CursorLifecycle.checkIdle(this); |
429 | - this.outerInput.open(); |
430 | - this.closed = false; |
431 | - } finally { |
432 | - TAP_OPEN.out(); |
433 | - } |
434 | - } |
435 | - |
436 | - @Override |
437 | public Row next() |
438 | { |
439 | if (TAP_NEXT_ENABLED) { |
440 | @@ -226,38 +203,14 @@ |
441 | CursorLifecycle.checkIdleOrActive(this); |
442 | } |
443 | checkQueryCancelation(); |
444 | - Row outputRow = null; |
445 | - while (!closed && outputRow == null) { |
446 | - outputRow = nextProductRow(); |
447 | - if (outputRow == null) { |
448 | - Row row = outerInput.next(); |
449 | - if (row == null) { |
450 | - close(); |
451 | - } else { |
452 | - RowType rowType = row.rowType(); |
453 | - if (rowType == outerType) { |
454 | - Row branchRow = row.subRow(branchType); |
455 | - assert branchRow != null : row; |
456 | - if (outerBranchRow.isEmpty() || !branchRow.hKey().equals(outerBranchRow.get().hKey())) { |
457 | - if (LOG_EXECUTION) { |
458 | - LOG.debug("Product_NestedLoops: branch row {}", row); |
459 | - } |
460 | - outerBranchRow.hold(branchRow); |
461 | - innerRows.newBranchRow(branchRow); |
462 | - } |
463 | - outerRow.hold(row); |
464 | - if (LOG_EXECUTION) { |
465 | - LOG.debug("Product_NestedLoops: restart inner loop using current branch row"); |
466 | - } |
467 | - innerRows.resetForCurrentBranchRow(); |
468 | - } |
469 | - } |
470 | - } |
471 | + Row row = input.next(); |
472 | + if ((row != null) && (row.rowType() == inputType)) { |
473 | + row = new ProductRow(productType, bindings.getRow(bindingPosition), row); |
474 | } |
475 | if (LOG_EXECUTION) { |
476 | - LOG.debug("Product_NestedLoops: yield {}", outputRow); |
477 | + LOG.debug("Product_Nested: yield {}", row); |
478 | } |
479 | - return outputRow; |
480 | + return row; |
481 | } finally { |
482 | if (TAP_NEXT_ENABLED) { |
483 | TAP_NEXT.out(); |
484 | @@ -265,160 +218,11 @@ |
485 | } |
486 | } |
487 | |
488 | - @Override |
489 | - public void close() |
490 | - { |
491 | - CursorLifecycle.checkIdleOrActive(this); |
492 | - if (!closed) { |
493 | - closeOuter(); |
494 | - closed = true; |
495 | - } |
496 | - } |
497 | - |
498 | - @Override |
499 | - public void destroy() |
500 | - { |
501 | - close(); |
502 | - outerInput.destroy(); |
503 | - innerRows.destroy(); |
504 | - } |
505 | - |
506 | - @Override |
507 | - public boolean isIdle() |
508 | - { |
509 | - return closed; |
510 | - } |
511 | - |
512 | - @Override |
513 | - public boolean isActive() |
514 | - { |
515 | - return !closed; |
516 | - } |
517 | - |
518 | - @Override |
519 | - public boolean isDestroyed() |
520 | - { |
521 | - return outerInput.isDestroyed(); |
522 | - } |
523 | - |
524 | - @Override |
525 | - public void openBindings() { |
526 | - outerInput.openBindings(); |
527 | - } |
528 | - |
529 | - @Override |
530 | - public QueryBindings nextBindings() { |
531 | - outerBindings = outerInput.nextBindings(); |
532 | - return outerBindings; |
533 | - } |
534 | - |
535 | - @Override |
536 | - public void closeBindings() { |
537 | - outerInput.closeBindings(); |
538 | - } |
539 | - |
540 | - @Override |
541 | - public void cancelBindings(QueryBindings bindings) { |
542 | - closeInner(); |
543 | - outerInput.cancelBindings(bindings); |
544 | - closed = true; |
545 | - } |
546 | - |
547 | // Execution interface |
548 | |
549 | - Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
550 | - { |
551 | - super(context); |
552 | - this.outerInput = outerInputOperator.cursor(context, bindingsCursor); |
553 | - this.innerRows = new InnerRows(context, bindingsCursor); |
554 | - } |
555 | - |
556 | - // For use by this class |
557 | - |
558 | - private Row nextProductRow() |
559 | - { |
560 | - Row productRow = null; |
561 | - if (outerRow.isHolding()) { |
562 | - Row innerRow = innerRows.next(); |
563 | - if (innerRow == null) { |
564 | - closeInner(); |
565 | - } else { |
566 | - productRow = new ProductRow(productType, outerRow.get(), innerRow); |
567 | - } |
568 | - } |
569 | - return productRow; |
570 | - } |
571 | - |
572 | - private void closeOuter() |
573 | - { |
574 | - closeInner(); |
575 | - outerInput.close(); |
576 | - } |
577 | - |
578 | - private void closeInner() |
579 | - { |
580 | - outerRow.release(); |
581 | - innerRows.close(); |
582 | - } |
583 | - |
584 | - // Object state |
585 | - |
586 | - private final Cursor outerInput; |
587 | - private final ShareHolder<Row> outerRow = new ShareHolder<>(); |
588 | - private final ShareHolder<Row> outerBranchRow = new ShareHolder<>(); |
589 | - private final InnerRows innerRows; |
590 | - private boolean closed = true; |
591 | - private QueryBindings outerBindings; |
592 | - |
593 | - // Inner classes |
594 | - |
595 | - private class InnerRows |
596 | - { |
597 | - public InnerRows(QueryContext context, QueryBindingsCursor bindingsCursor) |
598 | - { |
599 | - this.innerBindingsCursor = new SingletonQueryBindingsCursor(null); |
600 | - this.innerInput = innerInputOperator.cursor(context, innerBindingsCursor); |
601 | - } |
602 | - |
603 | - public Row next() |
604 | - { |
605 | - return scan.next(); |
606 | - } |
607 | - |
608 | - public void resetForCurrentBranchRow() |
609 | - { |
610 | - scan.reset(); |
611 | - } |
612 | - |
613 | - public void newBranchRow(Row branchRow) |
614 | - { |
615 | - close(); |
616 | - outerBindings.setRow(inputBindingPosition, branchRow); |
617 | - innerBindingsCursor.reset(outerBindings); |
618 | - innerInput.openTopLevel(); |
619 | - rows.clear(); |
620 | - Row row; |
621 | - while ((row = innerInput.next()) != null) { |
622 | - rows.add(row); |
623 | - } |
624 | - resetForCurrentBranchRow(); |
625 | - } |
626 | - |
627 | - public void close() |
628 | - { |
629 | - innerInput.close(); |
630 | - } |
631 | - |
632 | - public void destroy() |
633 | - { |
634 | - close(); |
635 | - innerInput.destroy(); |
636 | - } |
637 | - |
638 | - private final Cursor innerInput; |
639 | - private final RowList rows = new RowList(); |
640 | - private final RowList.Scan scan = rows.scan(); |
641 | - private final SingletonQueryBindingsCursor innerBindingsCursor; |
642 | + Execution(QueryContext context, Cursor input) |
643 | + { |
644 | + super(context, input); |
645 | } |
646 | } |
647 | } |
648 | |
649 | === modified file 'src/main/java/com/akiban/server/explain/Type.java' |
650 | --- src/main/java/com/akiban/server/explain/Type.java 2013-03-22 20:05:57 +0000 |
651 | +++ src/main/java/com/akiban/server/explain/Type.java 2013-07-18 16:47:28 +0000 |
652 | @@ -51,6 +51,7 @@ |
653 | DUI(GeneralType.OPERATOR), // delete/update/insert |
654 | DISTINCT(GeneralType.OPERATOR), |
655 | FLATTEN_OPERATOR(GeneralType.OPERATOR), |
656 | + PRODUCT_OPERATOR(GeneralType.OPERATOR), |
657 | LIMIT_OPERATOR(GeneralType.OPERATOR), |
658 | NESTED_LOOPS(GeneralType.OPERATOR), |
659 | IF_EMPTY(GeneralType.OPERATOR), |
660 | |
661 | === modified file 'src/main/java/com/akiban/server/explain/format/DefaultFormatter.java' |
662 | --- src/main/java/com/akiban/server/explain/format/DefaultFormatter.java 2013-03-22 20:05:57 +0000 |
663 | +++ src/main/java/com/akiban/server/explain/format/DefaultFormatter.java 2013-07-18 16:47:28 +0000 |
664 | @@ -233,6 +233,9 @@ |
665 | case FLATTEN_OPERATOR: |
666 | appendFlattenOperator(name, atts); |
667 | break; |
668 | + case PRODUCT_OPERATOR: |
669 | + appendProductOperator(name, atts); |
670 | + break; |
671 | case ORDERED: |
672 | appendOrderedOperator(name, atts); |
673 | break; |
674 | @@ -530,6 +533,14 @@ |
675 | } |
676 | } |
677 | |
678 | + protected void appendProductOperator(String name, Attributes atts) { |
679 | + if (levelOfDetail != LevelOfDetail.BRIEF) { |
680 | + append(atts.getAttribute(Label.OUTER_TYPE)); |
681 | + sb.append(" x "); |
682 | + append(atts.getAttribute(Label.INNER_TYPE)); |
683 | + } |
684 | + } |
685 | + |
686 | protected void appendOrderedOperator(String name, Attributes atts) { |
687 | if (levelOfDetail != LevelOfDetail.BRIEF) { |
688 | if (atts.containsKey(Label.UNION_OPTION) && |
689 | @@ -586,11 +597,6 @@ |
690 | if (name.equals("Map_NestedLoops")) { |
691 | // Label the loop? |
692 | } |
693 | - else if (name.equals("Product_NestedLoops")) { |
694 | - append(atts.getAttribute(Label.OUTER_TYPE)); |
695 | - sb.append(" x "); |
696 | - append(atts.getAttribute(Label.INNER_TYPE)); |
697 | - } |
698 | } |
699 | } |
700 | |
701 | |
702 | === modified file 'src/main/java/com/akiban/sql/optimizer/rule/OperatorAssembler.java' |
703 | --- src/main/java/com/akiban/sql/optimizer/rule/OperatorAssembler.java 2013-07-13 21:17:31 +0000 |
704 | +++ src/main/java/com/akiban/sql/optimizer/rule/OperatorAssembler.java 2013-07-18 16:47:28 +0000 |
705 | @@ -1472,10 +1472,12 @@ |
706 | RowStream stream; |
707 | Group group = branchLookup.getSource().getGroup(); |
708 | if (branchLookup.getInput() == null) { |
709 | - // Simple version for Product_NestedLoops. |
710 | + // Simple version for Product_Nested. |
711 | stream = new RowStream(); |
712 | API.InputPreservationOption flag = API.InputPreservationOption.KEEP_INPUT; |
713 | + ColumnExpressionToIndex boundRow = boundRows.get(boundRows.size()-1); |
714 | stream.operator = API.branchLookup_Nested(group, |
715 | + boundRow.getRowType(), |
716 | tableRowType(branchLookup.getSource()), |
717 | tableRowType(branchLookup.getAncestor()), |
718 | tableRowType(branchLookup.getBranch()), |
719 | @@ -1491,6 +1493,7 @@ |
720 | ColumnExpressionToIndex boundRow = boundRows.get(rowIndex); |
721 | stream.operator = API.branchLookup_Nested(group, |
722 | boundRow.getRowType(), |
723 | + boundRow.getRowType(), |
724 | tableRowType(branchLookup.getAncestor()), |
725 | tableRowType(branchLookup.getBranch()), |
726 | flag, |
727 | @@ -1546,14 +1549,12 @@ |
728 | ancestorRowType = tableRowType(product.getAncestor()); |
729 | RowStream pstream = new RowStream(); |
730 | Flattened flattened = new Flattened(); |
731 | + pstream.fieldOffsets = flattened; |
732 | int nbound = 0; |
733 | for (PlanNode subplan : product.getSubplans()) { |
734 | if (pstream.operator != null) { |
735 | - // The actual bound row is the branch row, which |
736 | - // we don't access directly. Just give each |
737 | - // product a separate position; nesting doesn't |
738 | - // matter. |
739 | - pushBoundRow(null); |
740 | + pushBoundRow(flattened); |
741 | + nestedBindingsDepth++; |
742 | nbound++; |
743 | } |
744 | RowStream stream = assembleStream(subplan); |
745 | @@ -1562,13 +1563,18 @@ |
746 | pstream.rowType = stream.rowType; |
747 | } |
748 | else { |
749 | - pstream.operator = API.product_NestedLoops(pstream.operator, |
750 | - stream.operator, |
751 | - pstream.rowType, |
752 | - ancestorRowType, |
753 | - stream.rowType, |
754 | - currentBindingPosition()); |
755 | - pstream.rowType = pstream.operator.rowType(); |
756 | + stream.operator = API.product_Nested(stream.operator, |
757 | + pstream.rowType, |
758 | + ancestorRowType, |
759 | + stream.rowType, |
760 | + currentBindingPosition()); |
761 | + stream.rowType = stream.operator.rowType(); |
762 | + pstream.operator = API.map_NestedLoops(pstream.operator, |
763 | + stream.operator, |
764 | + currentBindingPosition(), |
765 | + rulesContext.getPipelineConfiguration().isMapEnabled(), |
766 | + nestedBindingsDepth); |
767 | + pstream.rowType = stream.rowType; |
768 | } |
769 | if (stream.fieldOffsets instanceof ColumnSourceFieldOffsets) { |
770 | TableSource table = ((ColumnSourceFieldOffsets) |
771 | @@ -1578,13 +1584,13 @@ |
772 | else { |
773 | flattened.product((Flattened)stream.fieldOffsets); |
774 | } |
775 | + flattened.setRowType(pstream.rowType); |
776 | } |
777 | while (nbound > 0) { |
778 | popBoundRow(); |
779 | + nestedBindingsDepth--; |
780 | nbound--; |
781 | } |
782 | - flattened.setRowType(pstream.rowType); |
783 | - pstream.fieldOffsets = flattened; |
784 | return pstream; |
785 | } |
786 | |
787 | |
788 | === modified file 'src/test/java/com/akiban/server/test/it/qp/Map_NestedLoopsIT.java' |
789 | --- src/test/java/com/akiban/server/test/it/qp/Map_NestedLoopsIT.java 2013-07-15 22:46:16 +0000 |
790 | +++ src/test/java/com/akiban/server/test/it/qp/Map_NestedLoopsIT.java 2013-07-18 16:47:28 +0000 |
791 | @@ -120,7 +120,7 @@ |
792 | @Test(expected = IllegalArgumentException.class) |
793 | public void testNonPositiveDepth() |
794 | { |
795 | - map_NestedLoops(groupScan_Default(coi), groupScan_Default(coi), 0, pipelineMap(),0); |
796 | + map_NestedLoops(groupScan_Default(coi), groupScan_Default(coi), 0, true,0); |
797 | } |
798 | |
799 | // Test operator execution |
800 | |
801 | === modified file 'src/test/java/com/akiban/server/test/it/qp/Product3WayIT.java' |
802 | --- src/test/java/com/akiban/server/test/it/qp/Product3WayIT.java 2013-07-08 20:48:05 +0000 |
803 | +++ src/test/java/com/akiban/server/test/it/qp/Product3WayIT.java 2013-07-18 16:47:28 +0000 |
804 | @@ -34,11 +34,6 @@ |
805 | import static com.akiban.qp.operator.API.*; |
806 | import static org.junit.Assert.assertTrue; |
807 | |
808 | -// Product_ByRun relies on run ids. Here is an explanation of why run ids are needed: |
809 | -// http://akibainc.onconfluence.com/display/db/Implementation+of+the+Product+operator. |
810 | -// But no other operator relies on runs, and run ids can probably be omitted if we implement |
811 | -// a nested-loops form of product. This test uses a 3-way product, the case motivating run ids. |
812 | - |
813 | public class Product3WayIT extends OperatorITBase |
814 | { |
815 | @Override |
816 | @@ -134,28 +129,35 @@ |
817 | flatten_HKeyOrdered( |
818 | branchLookup_Nested( |
819 | rabc, |
820 | + RA.rowType(), |
821 | rRowType, |
822 | + null, |
823 | bRowType, |
824 | KEEP_INPUT, |
825 | 0), |
826 | rRowType, |
827 | bRowType, |
828 | INNER_JOIN); |
829 | + Operator RAB = product_Nested(RB, RA.rowType(), null, RB.rowType(), 0); |
830 | Operator RC = |
831 | flatten_HKeyOrdered( |
832 | branchLookup_Nested( |
833 | rabc, |
834 | + RAB.rowType(), |
835 | rRowType, |
836 | + null, |
837 | cRowType, |
838 | KEEP_INPUT, |
839 | - 0), |
840 | + 1), |
841 | rRowType, |
842 | cRowType, |
843 | INNER_JOIN); |
844 | - Operator RAB = product_NestedLoops(RA, RB, RA.rowType(), RB.rowType(), 0); |
845 | - Operator RABC = product_NestedLoops(RAB, RC, RAB.rowType(), RC.rowType(), 0); |
846 | - Cursor cursor = cursor(RABC, queryContext, queryBindings); |
847 | + Operator RABC = product_Nested(RC, RAB.rowType(), null, RC.rowType(), 1); |
848 | RowType rabcRowType = RABC.rowType(); |
849 | + Operator plan = map_NestedLoops( |
850 | + map_NestedLoops(RA, RAB, 0, pipelineMap(), 1), |
851 | + RABC, 1, pipelineMap(), 1); |
852 | + Cursor cursor = cursor(plan, queryContext, queryBindings); |
853 | RowBase[] expected = new RowBase[]{ |
854 | row(rabcRowType, 1L, "r1", 13L, 1L, "a13", 15L, 1L, "b15", 17L, 1L, "c17"), |
855 | row(rabcRowType, 1L, "r1", 13L, 1L, "a13", 15L, 1L, "b15", 18L, 1L, "c18"), |
856 | @@ -192,32 +194,39 @@ |
857 | rRowType, |
858 | aRowType, |
859 | INNER_JOIN); |
860 | + Operator RC = |
861 | + flatten_HKeyOrdered( |
862 | + branchLookup_Nested( |
863 | + rabc, |
864 | + RA.rowType(), |
865 | + rRowType, |
866 | + null, |
867 | + cRowType, |
868 | + KEEP_INPUT, |
869 | + 0), |
870 | + rRowType, |
871 | + cRowType, |
872 | + INNER_JOIN); |
873 | + Operator RAC = product_Nested(RC, RA.rowType(), null, RC.rowType(), 0); |
874 | Operator RB = |
875 | flatten_HKeyOrdered( |
876 | branchLookup_Nested( |
877 | rabc, |
878 | + RAC.rowType(), |
879 | rRowType, |
880 | + null, |
881 | bRowType, |
882 | KEEP_INPUT, |
883 | - 0), |
884 | + 1), |
885 | rRowType, |
886 | bRowType, |
887 | INNER_JOIN); |
888 | - Operator RC = |
889 | - flatten_HKeyOrdered( |
890 | - branchLookup_Nested( |
891 | - rabc, |
892 | - rRowType, |
893 | - cRowType, |
894 | - KEEP_INPUT, |
895 | - 0), |
896 | - rRowType, |
897 | - cRowType, |
898 | - INNER_JOIN); |
899 | - Operator RAC = product_NestedLoops(RA, RC, RA.rowType(), RC.rowType(), 0); |
900 | - Operator RACB = product_NestedLoops(RAC, RB, RAC.rowType(), RB.rowType(), 0); |
901 | - Cursor cursor = cursor(RACB, queryContext, queryBindings); |
902 | + Operator RACB = product_Nested(RB, RAC.rowType(), null, RB.rowType(), 1); |
903 | RowType racbRowType = RACB.rowType(); |
904 | + Operator plan = map_NestedLoops( |
905 | + map_NestedLoops(RA, RAC, 0, pipelineMap(), 1), |
906 | + RACB, 1, pipelineMap(), 1); |
907 | + Cursor cursor = cursor(plan, queryContext, queryBindings); |
908 | RowBase[] expected = new RowBase[]{ |
909 | row(racbRowType, 1L, "r1", 13L, 1L, "a13", 17L, 1L, "c17", 15L, 1L, "b15"), |
910 | row(racbRowType, 1L, "r1", 13L, 1L, "a13", 17L, 1L, "c17", 16L, 1L, "b16"), |
911 | @@ -254,39 +263,50 @@ |
912 | branchLookup_Nested( |
913 | rabc, |
914 | rRowType, |
915 | + rRowType, |
916 | + null, |
917 | aRowType, |
918 | KEEP_INPUT, |
919 | 0), |
920 | rRowType, |
921 | aRowType, |
922 | INNER_JOIN); |
923 | + Operator RA = product_Nested(flattenRA, rRowType, null, flattenRA.rowType(), 0); |
924 | Operator flattenRB = |
925 | flatten_HKeyOrdered( |
926 | branchLookup_Nested( |
927 | rabc, |
928 | + RA.rowType(), |
929 | rRowType, |
930 | + null, |
931 | bRowType, |
932 | KEEP_INPUT, |
933 | - 0), |
934 | + 1), |
935 | rRowType, |
936 | bRowType, |
937 | INNER_JOIN); |
938 | + Operator RAB = product_Nested(flattenRB, RA.rowType(), null, flattenRB.rowType(), 1); |
939 | Operator flattenRC = |
940 | flatten_HKeyOrdered( |
941 | branchLookup_Nested( |
942 | rabc, |
943 | + RAB.rowType(), |
944 | rRowType, |
945 | + null, |
946 | cRowType, |
947 | KEEP_INPUT, |
948 | - 0), |
949 | + 2), |
950 | rRowType, |
951 | cRowType, |
952 | INNER_JOIN); |
953 | - Operator RA = product_NestedLoops(rScan, flattenRA, rRowType, flattenRA.rowType(), 0); |
954 | - Operator RAB = product_NestedLoops(RA, flattenRB, RA.rowType(), flattenRB.rowType(), 0); |
955 | - Operator RABC = product_NestedLoops(RAB, flattenRC, RAB.rowType(), flattenRC.rowType(), 0); |
956 | - Cursor cursor = cursor(RABC, queryContext, queryBindings); |
957 | + Operator RABC = product_Nested(flattenRC, RAB.rowType(), null, flattenRC.rowType(), 2); |
958 | RowType rabcRowType = RABC.rowType(); |
959 | + Operator plan = map_NestedLoops( |
960 | + map_NestedLoops( |
961 | + map_NestedLoops(rScan, RA, 0, pipelineMap(), 1), |
962 | + RAB, 1, pipelineMap(), 1), |
963 | + RABC, 2, pipelineMap(), 1); |
964 | + Cursor cursor = cursor(plan, queryContext, queryBindings); |
965 | RowBase[] expected = new RowBase[]{ |
966 | row(rabcRowType, 1L, "r1", 13L, 1L, "a13", 15L, 1L, "b15", 17L, 1L, "c17"), |
967 | row(rabcRowType, 1L, "r1", 13L, 1L, "a13", 15L, 1L, "b15", 18L, 1L, "c18"), |
968 | |
969 | === renamed file 'src/test/java/com/akiban/server/test/it/qp/Product_NestedLoopsIT.java' => 'src/test/java/com/akiban/server/test/it/qp/Product_NestedIT.java' |
970 | --- src/test/java/com/akiban/server/test/it/qp/Product_NestedLoopsIT.java 2013-07-08 18:16:50 +0000 |
971 | +++ src/test/java/com/akiban/server/test/it/qp/Product_NestedIT.java 2013-07-18 16:47:28 +0000 |
972 | @@ -33,14 +33,13 @@ |
973 | import java.util.Set; |
974 | |
975 | import static com.akiban.qp.operator.API.*; |
976 | -import static com.akiban.qp.operator.API.FlattenOption.KEEP_PARENT; |
977 | import static com.akiban.qp.operator.API.JoinType.INNER_JOIN; |
978 | import static com.akiban.qp.rowtype.RowTypeChecks.checkRowTypeFields; |
979 | import static com.akiban.server.types.AkType.INT; |
980 | import static com.akiban.server.types.AkType.VARCHAR; |
981 | import static org.junit.Assert.assertTrue; |
982 | |
983 | -public class Product_NestedLoopsIT extends OperatorITBase |
984 | +public class Product_NestedIT extends OperatorITBase |
985 | { |
986 | @Override |
987 | protected void setupPostCreateSchema() |
988 | @@ -97,33 +96,27 @@ |
989 | // Test argument validation |
990 | |
991 | @Test(expected = IllegalArgumentException.class) |
992 | - public void testLeftInputNull() |
993 | - { |
994 | - product_NestedLoops(null, groupScan_Default(coi), customerRowType, customerRowType, 0); |
995 | - } |
996 | - |
997 | - @Test(expected = IllegalArgumentException.class) |
998 | - public void testRightInputNull() |
999 | - { |
1000 | - product_NestedLoops(groupScan_Default(coi), null, customerRowType, customerRowType, 0); |
1001 | + public void testInputNull() |
1002 | + { |
1003 | + product_Nested(null, customerRowType, null, customerRowType, 0); |
1004 | } |
1005 | |
1006 | @Test(expected = IllegalArgumentException.class) |
1007 | public void testLeftTypeNull() |
1008 | { |
1009 | - product_NestedLoops(groupScan_Default(coi), groupScan_Default(coi), null, customerRowType, 0); |
1010 | + product_Nested(groupScan_Default(coi), null, null, customerRowType, 0); |
1011 | } |
1012 | |
1013 | @Test(expected = IllegalArgumentException.class) |
1014 | public void testRightTypeNull() |
1015 | { |
1016 | - product_NestedLoops(groupScan_Default(coi), groupScan_Default(coi), customerRowType, null, 0); |
1017 | + product_Nested(groupScan_Default(coi), customerRowType, null, null, 0); |
1018 | } |
1019 | |
1020 | @Test(expected = IllegalArgumentException.class) |
1021 | public void testNegativeInputBindingPosition() |
1022 | { |
1023 | - product_NestedLoops(groupScan_Default(coi), groupScan_Default(coi), customerRowType, customerRowType, -1); |
1024 | + product_Nested(groupScan_Default(coi), customerRowType, null, customerRowType, -1); |
1025 | } |
1026 | |
1027 | // Test operator execution |
1028 | @@ -150,17 +143,17 @@ |
1029 | removeDescendentTypes(orderRowType)), |
1030 | customerRowType, |
1031 | orderRowType, |
1032 | - INNER_JOIN, |
1033 | - KEEP_PARENT); |
1034 | + INNER_JOIN); |
1035 | Operator flattenCA = |
1036 | flatten_HKeyOrdered( |
1037 | - branchLookup_Nested(coi, customerRowType, addressRowType, InputPreservationOption.KEEP_INPUT, 0), |
1038 | + branchLookup_Nested(coi, flattenCO.rowType(), customerRowType, null, addressRowType, InputPreservationOption.KEEP_INPUT, 0), |
1039 | customerRowType, |
1040 | addressRowType, |
1041 | INNER_JOIN); |
1042 | - Operator plan = product_NestedLoops(flattenCO, flattenCA, flattenCO.rowType(), flattenCA.rowType(), 0); |
1043 | - RowType coaRowType = plan.rowType(); |
1044 | + Operator product = product_Nested(flattenCA, flattenCO.rowType(), null, flattenCA.rowType(), 0); |
1045 | + RowType coaRowType = product.rowType(); |
1046 | checkRowTypeFields(coaRowType, INT, VARCHAR, INT, INT, VARCHAR, INT, INT, VARCHAR); |
1047 | + Operator plan = map_NestedLoops(flattenCO, product, 0, pipelineMap(), 1); |
1048 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
1049 | RowBase[] expected = new RowBase[]{ |
1050 | row(coaRowType, 2L, "foundation", 200L, 2L, "david", 2000L, 2L, "222 2000 st"), |
1051 | @@ -191,13 +184,14 @@ |
1052 | INNER_JOIN); |
1053 | Operator flattenCA = |
1054 | flatten_HKeyOrdered( |
1055 | - branchLookup_Nested(coi, customerRowType, addressRowType, InputPreservationOption.KEEP_INPUT, 0), |
1056 | + branchLookup_Nested(coi, flattenCO.rowType(), customerRowType, null, addressRowType, InputPreservationOption.KEEP_INPUT, 0), |
1057 | customerRowType, |
1058 | addressRowType, |
1059 | INNER_JOIN); |
1060 | - Operator plan = product_NestedLoops(flattenCO, flattenCA, flattenCO.rowType(), flattenCA.rowType(), 0); |
1061 | - RowType coaRowType = plan.rowType(); |
1062 | + Operator product = product_Nested(flattenCA, flattenCO.rowType(), null, flattenCA.rowType(), 0); |
1063 | + RowType coaRowType = product.rowType(); |
1064 | checkRowTypeFields(coaRowType, INT, VARCHAR, INT, INT, VARCHAR, INT, INT, VARCHAR); |
1065 | + Operator plan = map_NestedLoops(flattenCO, product, 0, pipelineMap(), 1); |
1066 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
1067 | RowBase[] expected = new RowBase[]{ |
1068 | row(coaRowType, 2L, "foundation", 200L, 2L, "david", 2000L, 2L, "222 2000 st"), |
1069 | @@ -222,12 +216,12 @@ |
1070 | Arrays.asList(customerRowType, addressRowType)), |
1071 | customerRowType, |
1072 | addressRowType, |
1073 | - JoinType.LEFT_JOIN, |
1074 | - FlattenOption.KEEP_PARENT); |
1075 | + JoinType.LEFT_JOIN); |
1076 | Operator flattenCAInner = |
1077 | flatten_HKeyOrdered( |
1078 | branchLookup_Nested( |
1079 | coi, |
1080 | + flattenCAOuter.rowType(), |
1081 | customerRowType, |
1082 | customerRowType, |
1083 | addressRowType, |
1084 | @@ -237,14 +231,14 @@ |
1085 | addressRowType, |
1086 | JoinType.LEFT_JOIN); |
1087 | Operator product = |
1088 | - product_NestedLoops( |
1089 | - flattenCAOuter, |
1090 | + product_Nested( |
1091 | flattenCAInner, |
1092 | flattenCAOuter.rowType(), |
1093 | customerRowType, |
1094 | flattenCAInner.rowType(), |
1095 | 0); |
1096 | RowType productRowType = product.rowType(); |
1097 | + Operator plan = map_NestedLoops(flattenCAOuter, product, 0, pipelineMap(), 1); |
1098 | RowBase[] expected = new RowBase[]{ |
1099 | row(productRowType, 1L, "northbridge", 1000L, 1L, "111 1000 st", 1000L, 1L, "111 1000 st"), |
1100 | row(productRowType, 1L, "northbridge", 1000L, 1L, "111 1000 st", 1001L, 1L, "111 1001 st"), |
1101 | @@ -262,7 +256,7 @@ |
1102 | row(productRowType, 5L, "highland", 5001L, 5L, "555 5001 st", 5001, 5L, "555 5001 st"), |
1103 | row(productRowType, 6L, "flybridge", null, null, null, null, null, null), |
1104 | }; |
1105 | - compareRows(expected, cursor(product, queryContext, queryBindings)); |
1106 | + compareRows(expected, cursor(plan, queryContext, queryBindings)); |
1107 | } |
1108 | |
1109 | @Test |
1110 | @@ -285,16 +279,16 @@ |
1111 | removeDescendentTypes(orderRowType)), |
1112 | customerRowType, |
1113 | orderRowType, |
1114 | - INNER_JOIN, |
1115 | - KEEP_PARENT); |
1116 | + INNER_JOIN); |
1117 | Operator flattenCA = |
1118 | flatten_HKeyOrdered( |
1119 | - branchLookup_Nested(coi, customerRowType, addressRowType, InputPreservationOption.KEEP_INPUT, 0), |
1120 | + branchLookup_Nested(coi, flattenCO.rowType(), customerRowType, null, addressRowType, InputPreservationOption.KEEP_INPUT, 0), |
1121 | customerRowType, |
1122 | addressRowType, |
1123 | INNER_JOIN); |
1124 | - Operator plan = product_NestedLoops(flattenCO, flattenCA, flattenCO.rowType(), flattenCA.rowType(), 0); |
1125 | - final RowType coaRowType = plan.rowType(); |
1126 | + Operator product = product_Nested(flattenCA, flattenCO.rowType(), null, flattenCA.rowType(), 0); |
1127 | + final RowType coaRowType = product.rowType(); |
1128 | + Operator plan = map_NestedLoops(flattenCO, product, 0, pipelineMap(), 1); |
1129 | CursorLifecycleTestCase testCase = new CursorLifecycleTestCase() |
1130 | { |
1131 | @Override |
1132 | |
1133 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiindex-multi-duplicate.expected' |
1134 | --- src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiindex-multi-duplicate.expected 2012-08-29 13:38:58 +0000 |
1135 | +++ src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiindex-multi-duplicate.expected 2013-07-18 16:47:28 +0000 |
1136 | @@ -1,14 +1,15 @@ |
1137 | PhysicalSelect[quan:int[INT], quan:int[INT]] |
1138 | Project_Default(i1.quan, i2.quan) |
1139 | - Product_NestedLoops(customers - orders - items x customers - orders - items) |
1140 | + Map_NestedLoops() |
1141 | Flatten_HKeyOrdered(customers - orders INNER items) |
1142 | Flatten_HKeyOrdered(customers INNER orders) |
1143 | AncestorLookup_Default(Index(items.sku) -> customers, orders, items) |
1144 | Intersect_Ordered(skip 1 left, skip 1 right, compare 1) |
1145 | IndexScan_Default(Index(items.sku), sku = '1234') |
1146 | IndexScan_Default(Index(items.sku), sku = '4567') |
1147 | - Filter_Default(customers - orders - items) |
1148 | - Flatten_HKeyOrdered(customers - orders INNER items) |
1149 | - Flatten_HKeyOrdered(customers INNER orders) |
1150 | - Select_HKeyOrdered(i2.sku == '4567') |
1151 | - BranchLookup_Nested(customers -> orders) |
1152 | \ No newline at end of file |
1153 | + Product_Nested(customers - orders - items x customers - orders - items) |
1154 | + Filter_Default(customers - orders - items) |
1155 | + Flatten_HKeyOrdered(customers - orders INNER items) |
1156 | + Flatten_HKeyOrdered(customers INNER orders) |
1157 | + Select_HKeyOrdered(i2.sku == '4567') |
1158 | + BranchLookup_Nested(customers -> orders) |
1159 | \ No newline at end of file |
1160 | |
1161 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiindex-multi-ordered.expected' |
1162 | --- src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiindex-multi-ordered.expected 2012-08-29 13:38:58 +0000 |
1163 | +++ src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiindex-multi-ordered.expected 2013-07-18 16:47:28 +0000 |
1164 | @@ -1,14 +1,15 @@ |
1165 | PhysicalSelect[quan:int[INT], quan:int[INT]] |
1166 | Project_Default(i1.quan, i2.quan) |
1167 | - Product_NestedLoops(customers - orders - items x customers - orders - items) |
1168 | + Map_NestedLoops() |
1169 | Flatten_HKeyOrdered(customers - orders INNER items) |
1170 | Flatten_HKeyOrdered(customers INNER orders) |
1171 | AncestorLookup_Default(Index(items.sku) -> customers, orders, items) |
1172 | Intersect_Ordered(skip 1 left, skip 1 right, compare 1) |
1173 | IndexScan_Default(Index(items.sku), sku = '1234', orders.cid DESC, oid, iid) |
1174 | IndexScan_Default(Index(items.sku), sku = '4567', orders.cid DESC, oid, iid) |
1175 | - Filter_Default(customers - orders - items) |
1176 | - Flatten_HKeyOrdered(customers - orders INNER items) |
1177 | - Flatten_HKeyOrdered(customers INNER orders) |
1178 | - Select_HKeyOrdered(i2.sku == '4567') |
1179 | - BranchLookup_Nested(customers -> orders) |
1180 | \ No newline at end of file |
1181 | + Product_Nested(customers - orders - items x customers - orders - items) |
1182 | + Filter_Default(customers - orders - items) |
1183 | + Flatten_HKeyOrdered(customers - orders INNER items) |
1184 | + Flatten_HKeyOrdered(customers INNER orders) |
1185 | + Select_HKeyOrdered(i2.sku == '4567') |
1186 | + BranchLookup_Nested(customers -> orders) |
1187 | \ No newline at end of file |
1188 | |
1189 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiple-table-conds-1.expected' |
1190 | --- src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiple-table-conds-1.expected 2012-10-19 19:07:51 +0000 |
1191 | +++ src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiple-table-conds-1.expected 2013-07-18 16:47:28 +0000 |
1192 | @@ -3,13 +3,14 @@ |
1193 | AncestorLookup_Default(Index(parent.PRIMARY) -> parent) |
1194 | IndexScan_Default(Index(parent.PRIMARY), id > 1) |
1195 | Project_Default(customers.cid) |
1196 | - Product_NestedLoops(customers - items x customers - addresses) |
1197 | + Map_NestedLoops() |
1198 | Flatten_HKeyOrdered(customers INNER items) |
1199 | Select_HKeyOrdered(items.quan > 100) |
1200 | AncestorLookup_Default(Index(customers.cname_and_sku) -> customers, items) |
1201 | IndexScan_Default(Index(customers.cname_and_sku), customers.name = parent.name, items.sku = '1234') |
1202 | - Select_HKeyOrdered(addresses.city != customers.name) |
1203 | - Filter_Default(customers - addresses) |
1204 | - Flatten_HKeyOrdered(customers INNER addresses) |
1205 | - Select_HKeyOrdered(parent.state == addresses.state) |
1206 | - BranchLookup_Nested(customers -> addresses) |
1207 | + Product_Nested(customers - items x customers - addresses) |
1208 | + Select_HKeyOrdered(addresses.city != customers.name) |
1209 | + Filter_Default(customers - addresses) |
1210 | + Flatten_HKeyOrdered(customers INNER addresses) |
1211 | + Select_HKeyOrdered(parent.state == addresses.state) |
1212 | + BranchLookup_Nested(customers -> addresses) |
1213 | |
1214 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiple-table-conds-1.t3expected' |
1215 | --- src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiple-table-conds-1.t3expected 2012-10-20 04:06:22 +0000 |
1216 | +++ src/test/resources/com/akiban/sql/optimizer/operator/cbo/multiple-table-conds-1.t3expected 2013-07-18 16:47:28 +0000 |
1217 | @@ -3,13 +3,14 @@ |
1218 | AncestorLookup_Default(Index(parent.PRIMARY) -> parent) |
1219 | IndexScan_Default(Index(parent.PRIMARY), id > 1) |
1220 | Project_Default(customers.cid) |
1221 | - Product_NestedLoops(customers - items x customers - addresses) |
1222 | + Map_NestedLoops() |
1223 | Flatten_HKeyOrdered(customers INNER items) |
1224 | Select_HKeyOrdered(items.quan > 100) |
1225 | AncestorLookup_Default(Index(customers.cname_and_sku) -> customers, items) |
1226 | IndexScan_Default(Index(customers.cname_and_sku), customers.name = parent.name, items.sku = '1234') |
1227 | - Select_HKeyOrdered(addresses.city != customers.name) |
1228 | - Filter_Default(customers - addresses) |
1229 | - Flatten_HKeyOrdered(customers INNER addresses) |
1230 | - Select_HKeyOrdered(parent.state == addresses.state) |
1231 | - BranchLookup_Nested(customers -> addresses) |
1232 | \ No newline at end of file |
1233 | + Product_Nested(customers - items x customers - addresses) |
1234 | + Select_HKeyOrdered(addresses.city != customers.name) |
1235 | + Filter_Default(customers - addresses) |
1236 | + Flatten_HKeyOrdered(customers INNER addresses) |
1237 | + Select_HKeyOrdered(parent.state == addresses.state) |
1238 | + BranchLookup_Nested(customers -> addresses) |
1239 | \ No newline at end of file |
1240 | |
1241 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/coia-group-index/select-17bu.expected' |
1242 | --- src/test/resources/com/akiban/sql/optimizer/operator/coia-group-index/select-17bu.expected 2013-06-06 19:56:32 +0000 |
1243 | +++ src/test/resources/com/akiban/sql/optimizer/operator/coia-group-index/select-17bu.expected 2013-07-18 16:47:28 +0000 |
1244 | @@ -1,7 +1,7 @@ |
1245 | PhysicalSelect[name:varchar(32)[VARCHAR], quan:int[INT]] |
1246 | Project_Default(customers.name, items.quan) |
1247 | Sort_General(items.quan DESC) |
1248 | - Product_NestedLoops(customers - addresses x customers - orders - items) |
1249 | + Map_NestedLoops() |
1250 | Flatten_HKeyOrdered(customers INNER addresses) |
1251 | AncestorLookup_Default(Index(addresses.state) -> customers, addresses) |
1252 | UnionAll_Default() |
1253 | @@ -9,7 +9,8 @@ |
1254 | IndexScan_Default(Index(addresses.state), state = 'MA', cid ASC, aid) |
1255 | IndexScan_Default(Index(addresses.state), state = 'NY', cid ASC, aid) |
1256 | IndexScan_Default(Index(addresses.state), state = 'VT', cid ASC, aid) |
1257 | - Filter_Default(customers - orders - items) |
1258 | - Flatten_HKeyOrdered(customers - orders INNER items) |
1259 | - Flatten_HKeyOrdered(customers INNER orders) |
1260 | - BranchLookup_Nested(customers -> orders) |
1261 | \ No newline at end of file |
1262 | + Product_Nested(customers - addresses x customers - orders - items) |
1263 | + Filter_Default(customers - orders - items) |
1264 | + Flatten_HKeyOrdered(customers - orders INNER items) |
1265 | + Flatten_HKeyOrdered(customers INNER orders) |
1266 | + BranchLookup_Nested(customers -> orders) |
1267 | \ No newline at end of file |
1268 | |
1269 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2.expected' |
1270 | --- src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2.expected 2013-03-06 16:01:20 +0000 |
1271 | +++ src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2.expected 2013-07-18 16:47:28 +0000 |
1272 | @@ -1,11 +1,12 @@ |
1273 | PhysicalSelect[cid:int[INT], name:varchar(32)[VARCHAR], oid:int[INT], cid:int[INT], order_date:date[DATE], iid:int[INT], oid:int[INT], sku:varchar(32)[VARCHAR], quan:int[INT], aid:int[INT], cid:int[INT], state:char(2)[VARCHAR], city:varchar(100)[VARCHAR]] |
1274 | Project_Default(customers.cid, customers.name, orders.oid, orders.cid, orders.order_date, items.iid, items.oid, items.sku, items.quan, addresses.aid, addresses.cid, addresses.state, addresses.city) |
1275 | - Product_NestedLoops(customers - addresses x customers - orders - items) |
1276 | + Map_NestedLoops() |
1277 | Filter_Default(customers - addresses) |
1278 | Flatten_HKeyOrdered(customers INNER addresses) |
1279 | BranchLookup_Default(HKey -> customers) |
1280 | IndexScan_FullText(test.customers.cust_ft, +state:MA +sku:1234) |
1281 | - Filter_Default(customers - orders - items) |
1282 | - Flatten_HKeyOrdered(customers - orders INNER items) |
1283 | - Flatten_HKeyOrdered(customers INNER orders) |
1284 | - BranchLookup_Nested(customers -> orders) |
1285 | \ No newline at end of file |
1286 | + Product_Nested(customers - addresses x customers - orders - items) |
1287 | + Filter_Default(customers - orders - items) |
1288 | + Flatten_HKeyOrdered(customers - orders INNER items) |
1289 | + Flatten_HKeyOrdered(customers INNER orders) |
1290 | + BranchLookup_Nested(customers -> orders) |
1291 | \ No newline at end of file |
1292 | |
1293 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2n.expected' |
1294 | --- src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2n.expected 2013-03-06 16:01:20 +0000 |
1295 | +++ src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2n.expected 2013-07-18 16:47:28 +0000 |
1296 | @@ -1,11 +1,12 @@ |
1297 | PhysicalSelect[cid:int[INT], name:varchar(32)[VARCHAR], oid:int[INT], cid:int[INT], order_date:date[DATE], iid:int[INT], oid:int[INT], sku:varchar(32)[VARCHAR], quan:int[INT], aid:int[INT], cid:int[INT], state:char(2)[VARCHAR], city:varchar(100)[VARCHAR]] |
1298 | Project_Default(customers.cid, customers.name, orders.oid, orders.cid, orders.order_date, items.iid, items.oid, items.sku, items.quan, addresses.aid, addresses.cid, addresses.state, addresses.city) |
1299 | - Product_NestedLoops(customers - addresses x customers - orders - items) |
1300 | + Map_NestedLoops() |
1301 | Filter_Default(customers - addresses) |
1302 | Flatten_HKeyOrdered(customers INNER addresses) |
1303 | BranchLookup_Default(HKey -> customers) |
1304 | IndexScan_FullText(test.customers.cust_ft, -state:MA +sku:1234) |
1305 | - Filter_Default(customers - orders - items) |
1306 | - Flatten_HKeyOrdered(customers - orders INNER items) |
1307 | - Flatten_HKeyOrdered(customers INNER orders) |
1308 | - BranchLookup_Nested(customers -> orders) |
1309 | \ No newline at end of file |
1310 | + Product_Nested(customers - addresses x customers - orders - items) |
1311 | + Filter_Default(customers - orders - items) |
1312 | + Flatten_HKeyOrdered(customers - orders INNER items) |
1313 | + Flatten_HKeyOrdered(customers INNER orders) |
1314 | + BranchLookup_Nested(customers -> orders) |
1315 | \ No newline at end of file |
1316 | |
1317 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2v.expected' |
1318 | --- src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2v.expected 2013-03-06 16:01:20 +0000 |
1319 | +++ src/test/resources/com/akiban/sql/optimizer/operator/coia-text-index/full-text-2v.expected 2013-07-18 16:47:28 +0000 |
1320 | @@ -1,11 +1,12 @@ |
1321 | PhysicalSelect[CHAR(2) CHARACTER SET utf8 COLLATE utf8_bin, VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin][cid:int[INT], name:varchar(32)[VARCHAR], oid:int[INT], cid:int[INT], order_date:date[DATE], iid:int[INT], oid:int[INT], sku:varchar(32)[VARCHAR], quan:int[INT], aid:int[INT], cid:int[INT], state:char(2)[VARCHAR], city:varchar(100)[VARCHAR]] |
1322 | Project_Default(customers.cid, customers.name, orders.oid, orders.cid, orders.order_date, items.iid, items.oid, items.sku, items.quan, addresses.aid, addresses.cid, addresses.state, addresses.city) |
1323 | - Product_NestedLoops(customers - addresses x customers - orders - items) |
1324 | + Map_NestedLoops() |
1325 | Filter_Default(customers - addresses) |
1326 | Flatten_HKeyOrdered(customers INNER addresses) |
1327 | BranchLookup_Default(HKey -> customers) |
1328 | IndexScan_FullText(test.customers.cust_ft, TERM($1), TERM($2)) |
1329 | - Filter_Default(customers - orders - items) |
1330 | - Flatten_HKeyOrdered(customers - orders INNER items) |
1331 | - Flatten_HKeyOrdered(customers INNER orders) |
1332 | - BranchLookup_Nested(customers -> orders) |
1333 | \ No newline at end of file |
1334 | + Product_Nested(customers - addresses x customers - orders - items) |
1335 | + Filter_Default(customers - orders - items) |
1336 | + Flatten_HKeyOrdered(customers - orders INNER items) |
1337 | + Flatten_HKeyOrdered(customers INNER orders) |
1338 | + BranchLookup_Nested(customers -> orders) |
1339 | \ No newline at end of file |
1340 | |
1341 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/coia/select-2.expected' |
1342 | --- src/test/resources/com/akiban/sql/optimizer/operator/coia/select-2.expected 2012-08-26 04:29:21 +0000 |
1343 | +++ src/test/resources/com/akiban/sql/optimizer/operator/coia/select-2.expected 2013-07-18 16:47:28 +0000 |
1344 | @@ -1,9 +1,10 @@ |
1345 | PhysicalSelect[name:varchar(32)[VARCHAR], order_date:date[DATE], city:varchar(100)[VARCHAR]] |
1346 | Project_Default(customers.name, orders.order_date, addresses.city) |
1347 | - Product_NestedLoops(customers - addresses x customers - orders) |
1348 | + Map_NestedLoops() |
1349 | Flatten_HKeyOrdered(customers INNER addresses) |
1350 | AncestorLookup_Default(Index(addresses.state) -> customers, addresses) |
1351 | IndexScan_Default(Index(addresses.state), state = 'MA') |
1352 | - Filter_Default(customers - orders) |
1353 | - Flatten_HKeyOrdered(customers INNER orders) |
1354 | - BranchLookup_Nested(customers -> orders) |
1355 | \ No newline at end of file |
1356 | + Product_Nested(customers - addresses x customers - orders) |
1357 | + Filter_Default(customers - orders) |
1358 | + Flatten_HKeyOrdered(customers INNER orders) |
1359 | + BranchLookup_Nested(customers -> orders) |
1360 | \ No newline at end of file |
1361 | |
1362 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/coia/select-5.expected' |
1363 | --- src/test/resources/com/akiban/sql/optimizer/operator/coia/select-5.expected 2012-08-26 04:29:21 +0000 |
1364 | +++ src/test/resources/com/akiban/sql/optimizer/operator/coia/select-5.expected 2013-07-18 16:47:28 +0000 |
1365 | @@ -1,10 +1,11 @@ |
1366 | PhysicalSelect[name:varchar(32)[VARCHAR], order_date:date[DATE], state:char(2)[VARCHAR]] |
1367 | Project_Default(customers.name, orders.order_date, addresses.state) |
1368 | - Product_NestedLoops(customers - addresses x customers - orders) |
1369 | + Map_NestedLoops() |
1370 | Filter_Default(customers - addresses) |
1371 | Flatten_HKeyOrdered(customers INNER addresses) |
1372 | BranchLookup_Default(Index(customers.name) -> customers) |
1373 | IndexScan_Default(Index(customers.name), name = 'IBM') |
1374 | - Filter_Default(customers - orders) |
1375 | - Flatten_HKeyOrdered(customers INNER orders) |
1376 | - BranchLookup_Nested(customers -> orders) |
1377 | \ No newline at end of file |
1378 | + Product_Nested(customers - addresses x customers - orders) |
1379 | + Filter_Default(customers - orders) |
1380 | + Flatten_HKeyOrdered(customers INNER orders) |
1381 | + BranchLookup_Nested(customers -> orders) |
1382 | \ No newline at end of file |
1383 | |
1384 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/coia/select-6.expected' |
1385 | --- src/test/resources/com/akiban/sql/optimizer/operator/coia/select-6.expected 2012-08-26 04:29:21 +0000 |
1386 | +++ src/test/resources/com/akiban/sql/optimizer/operator/coia/select-6.expected 2013-07-18 16:47:28 +0000 |
1387 | @@ -1,9 +1,10 @@ |
1388 | PhysicalSelect[name:varchar(32)[VARCHAR], order_date:date[DATE], state:char(2)[VARCHAR]] |
1389 | Project_Default(customers.name, orders.order_date, addresses.state) |
1390 | - Product_NestedLoops(customers - orders x customers - addresses) |
1391 | + Map_NestedLoops() |
1392 | Flatten_HKeyOrdered(customers INNER orders) |
1393 | AncestorLookup_Default(Index(orders.order_date) -> customers, orders) |
1394 | IndexScan_Default(Index(orders.order_date), order_date > DATE '2011-01-01') |
1395 | - Filter_Default(customers - addresses) |
1396 | - Flatten_HKeyOrdered(customers INNER addresses) |
1397 | - BranchLookup_Nested(customers -> addresses) |
1398 | \ No newline at end of file |
1399 | + Product_Nested(customers - orders x customers - addresses) |
1400 | + Filter_Default(customers - addresses) |
1401 | + Flatten_HKeyOrdered(customers INNER addresses) |
1402 | + BranchLookup_Nested(customers -> addresses) |
1403 | \ No newline at end of file |
1404 | |
1405 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/coia/select-7.expected' |
1406 | --- src/test/resources/com/akiban/sql/optimizer/operator/coia/select-7.expected 2012-08-26 04:29:21 +0000 |
1407 | +++ src/test/resources/com/akiban/sql/optimizer/operator/coia/select-7.expected 2013-07-18 16:47:28 +0000 |
1408 | @@ -1,12 +1,13 @@ |
1409 | PhysicalSelect[name:varchar(32)[VARCHAR], order_date:date[DATE], sku:varchar(32)[VARCHAR], state:char(2)[VARCHAR]] |
1410 | Project_Default(customers.name, orders.order_date, items.sku, addresses.state) |
1411 | - Product_NestedLoops(customers - orders - items x customers - addresses) |
1412 | + Map_NestedLoops() |
1413 | Filter_Default(customers - orders - items) |
1414 | Flatten_HKeyOrdered(customers - orders INNER items) |
1415 | Flatten_HKeyOrdered(customers INNER orders) |
1416 | AncestorLookup_Default(orders -> customers) |
1417 | BranchLookup_Default(Index(orders.order_date) -> orders) |
1418 | IndexScan_Default(Index(orders.order_date), order_date > DATE '2011-01-01') |
1419 | - Filter_Default(customers - addresses) |
1420 | - Flatten_HKeyOrdered(customers INNER addresses) |
1421 | - BranchLookup_Nested(customers -> addresses) |
1422 | \ No newline at end of file |
1423 | + Product_Nested(customers - orders - items x customers - addresses) |
1424 | + Filter_Default(customers - addresses) |
1425 | + Flatten_HKeyOrdered(customers INNER addresses) |
1426 | + BranchLookup_Nested(customers -> addresses) |
1427 | \ No newline at end of file |
1428 | |
1429 | === modified file 'src/test/resources/com/akiban/sql/optimizer/operator/coia/select-8.expected' |
1430 | --- src/test/resources/com/akiban/sql/optimizer/operator/coia/select-8.expected 2012-08-26 04:29:21 +0000 |
1431 | +++ src/test/resources/com/akiban/sql/optimizer/operator/coia/select-8.expected 2013-07-18 16:47:28 +0000 |
1432 | @@ -1,10 +1,11 @@ |
1433 | PhysicalSelect[name:varchar(32)[VARCHAR], order_date:date[DATE], sku:varchar(32)[VARCHAR], quan:int[INT], state:char(2)[VARCHAR]] |
1434 | Project_Default(customers.name, orders.order_date, items.sku, items.quan, addresses.state) |
1435 | - Product_NestedLoops(customers - addresses x customers - orders - items) |
1436 | + Map_NestedLoops() |
1437 | Filter_Default(customers - addresses) |
1438 | Flatten_HKeyOrdered(customers INNER addresses) |
1439 | GroupScan_Default(customers) |
1440 | - Filter_Default(customers - orders - items) |
1441 | - Flatten_HKeyOrdered(customers - orders INNER items) |
1442 | - Flatten_HKeyOrdered(customers INNER orders) |
1443 | - BranchLookup_Nested(customers -> orders) |
1444 | \ No newline at end of file |
1445 | + Product_Nested(customers - addresses x customers - orders - items) |
1446 | + Filter_Default(customers - orders - items) |
1447 | + Flatten_HKeyOrdered(customers - orders INNER items) |
1448 | + Flatten_HKeyOrdered(customers INNER orders) |
1449 | + BranchLookup_Nested(customers -> orders) |
1450 | \ No newline at end of file |
1451 | |
1452 | === modified file 'src/test/resources/com/akiban/sql/optimizer/rule/operator/full-text-2.expected' |
1453 | --- src/test/resources/com/akiban/sql/optimizer/rule/operator/full-text-2.expected 2013-03-06 16:01:20 +0000 |
1454 | +++ src/test/resources/com/akiban/sql/optimizer/rule/operator/full-text-2.expected 2013-07-18 16:47:28 +0000 |
1455 | @@ -1,11 +1,12 @@ |
1456 | PhysicalSelect@2fc5027d[cid, name, oid, cid, order_date, iid, oid, sku, quan, price, aid, cid, state, city] |
1457 | Project_Default(Field(0), Field(1), Field(6), Field(7), Field(8), Field(9), Field(10), Field(11), Field(12), Field(13), Field(2), Field(3), Field(4), Field(5)) |
1458 | - Product_NestedLoops(test.customers - test.addresses x test.customers - test.orders - test.items) |
1459 | + Map_NestedLoops() |
1460 | Filter_Default(test.customers - test.addresses) |
1461 | Flatten_HKeyOrdered(test.customers INNER test.addresses) |
1462 | BranchLookup_Default(HKey -> test.customers) |
1463 | IndexScan_FullText(test.customers.cust_ft, +state:MA +sku:1234) |
1464 | - Filter_Default(test.customers - test.orders - test.items) |
1465 | - Flatten_HKeyOrdered(test.customers - test.orders INNER test.items) |
1466 | - Flatten_HKeyOrdered(test.customers INNER test.orders) |
1467 | - BranchLookup_Nested(test.customers -> test.orders) |
1468 | \ No newline at end of file |
1469 | + Product_Nested(test.customers - test.addresses x test.customers - test.orders - test.items) |
1470 | + Filter_Default(test.customers - test.orders - test.items) |
1471 | + Flatten_HKeyOrdered(test.customers - test.orders INNER test.items) |
1472 | + Flatten_HKeyOrdered(test.customers INNER test.orders) |
1473 | + BranchLookup_Nested(test.customers -> test.orders) |
1474 | \ No newline at end of file |
1475 | |
1476 | === modified file 'src/test/resources/com/akiban/sql/optimizer/rule/operator/select-5.expected' |
1477 | --- src/test/resources/com/akiban/sql/optimizer/rule/operator/select-5.expected 2012-08-26 04:55:19 +0000 |
1478 | +++ src/test/resources/com/akiban/sql/optimizer/rule/operator/select-5.expected 2013-07-18 16:47:28 +0000 |
1479 | @@ -1,10 +1,11 @@ |
1480 | PhysicalSelect@bd056de[name, order_date, state] |
1481 | Project_Default(Field(1), Field(8), Field(4)) |
1482 | - Product_NestedLoops(test.customers - test.addresses x test.customers - test.orders) |
1483 | + Map_NestedLoops() |
1484 | Filter_Default(test.customers - test.addresses) |
1485 | Flatten_HKeyOrdered(test.customers INNER test.addresses) |
1486 | BranchLookup_Default(Index(test.customers.name) -> test.customers) |
1487 | IndexScan_Default(Index(test.customers.name), name = 'IBM', cid ASC) |
1488 | - Filter_Default(test.customers - test.orders) |
1489 | - Flatten_HKeyOrdered(test.customers INNER test.orders) |
1490 | - BranchLookup_Nested(test.customers -> test.orders) |
1491 | \ No newline at end of file |
1492 | + Product_Nested(test.customers - test.addresses x test.customers - test.orders) |
1493 | + Filter_Default(test.customers - test.orders) |
1494 | + Flatten_HKeyOrdered(test.customers INNER test.orders) |
1495 | + BranchLookup_Nested(test.customers -> test.orders) |
1496 | \ No newline at end of file |
Minor nit: The Overview in the Javadoc for Product_Nested still references _NestedLoops.
Otherwise looks pretty good. Feel free to Big-A after.