Merge lp:~mmcm/akiban-server/pipeline-union-all into lp:~akiban-technologies/akiban-server/trunk

Proposed by Mike McMahon
Status: Merged
Approved by: Nathan Williams
Approved revision: 2710
Merged at revision: 2706
Proposed branch: lp:~mmcm/akiban-server/pipeline-union-all
Merge into: lp:~akiban-technologies/akiban-server/trunk
Prerequisite: lp:~mmcm/akiban-server/pipeline-spatial-index-scan
Diff against target: 440 lines (+128/-42)
7 files modified
src/main/java/com/akiban/qp/operator/API.java (+2/-2)
src/main/java/com/akiban/qp/operator/UnionAll_Default.java (+20/-5)
src/main/java/com/akiban/sql/optimizer/rule/OperatorAssembler.java (+1/-1)
src/test/java/com/akiban/qp/operator/UnionAll_DefaultOpenBothTest.java (+26/-0)
src/test/java/com/akiban/qp/operator/UnionAll_DefaultTest.java (+14/-9)
src/test/java/com/akiban/server/test/it/qp/UnionAll_DefaultIT.java (+34/-25)
src/test/java/com/akiban/server/test/it/qp/UnionAll_DefaultPipelineIT.java (+31/-0)
To merge this branch: bzr merge lp:~mmcm/akiban-server/pipeline-union-all
Reviewer Review Type Date Requested Status
Nathan Williams Approve
Review via email: mp+175675@code.launchpad.net

Description of the change

Optionally open both sides of UnionAll_Default.

This is not semantically necessary, unlike Union_Ordered, since the semantics can be satisfied by concatenating the two streams.

While here, rename the API entry to be consistent with everything else.

To post a comment you must log in.
Revision history for this message
Nathan Williams (nwilliams) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/main/java/com/akiban/qp/operator/API.java'
2--- src/main/java/com/akiban/qp/operator/API.java 2013-07-18 20:38:26 +0000
3+++ src/main/java/com/akiban/qp/operator/API.java 2013-07-18 20:38:26 +0000
4@@ -588,9 +588,9 @@
5
6 // Union
7
8- public static Operator unionAll(Operator input1, RowType input1RowType, Operator input2, RowType input2RowType)
9+ public static Operator unionAll_Default(Operator input1, RowType input1RowType, Operator input2, RowType input2RowType, boolean openBoth)
10 {
11- return new UnionAll_Default(input1, input1RowType, input2, input2RowType, USE_PVALUES);
12+ return new UnionAll_Default(input1, input1RowType, input2, input2RowType, USE_PVALUES, openBoth);
13 }
14
15 // Intersect
16
17=== modified file 'src/main/java/com/akiban/qp/operator/UnionAll_Default.java'
18--- src/main/java/com/akiban/qp/operator/UnionAll_Default.java 2013-07-15 22:01:49 +0000
19+++ src/main/java/com/akiban/qp/operator/UnionAll_Default.java 2013-07-18 20:38:26 +0000
20@@ -53,6 +53,7 @@
21 <li><b>RowType input1Type:</b> Type of rows in first input stream.
22 <li><b>Operator input2:</b> Source of second input stream.
23 <li><b>RowType input2Type:</b> Type of rows in second input stream.
24+ <li><b>boolean openBoth:</b> Whether to open both input cursors at the same time rather than as needed.
25
26 <h1>Behavior</h1>
27
28@@ -105,7 +106,7 @@
29 return new Execution(context, bindingsCursor);
30 }
31
32- UnionAll_Default(Operator input1, RowType input1Type, Operator input2, RowType input2Type, boolean usePValues) {
33+ UnionAll_Default(Operator input1, RowType input1Type, Operator input2, RowType input2Type, boolean usePValues, boolean openBoth) {
34 ArgumentValidation.notNull("first input", input1);
35 ArgumentValidation.notNull("first input type", input1Type);
36 ArgumentValidation.notNull("second input", input2);
37@@ -114,6 +115,7 @@
38 this.inputs = Arrays.asList(input1, input2);
39 this.inputTypes = Arrays.asList(input1Type, input2Type);
40 ArgumentValidation.isEQ("inputs.size", inputs.size(), "inputTypes.size", inputTypes.size());
41+ this.openBoth = openBoth;
42 }
43
44 // for use in this package (in ctor and unit tests)
45@@ -186,6 +188,7 @@
46 private final List<? extends Operator> inputs;
47 private final List<? extends RowType> inputTypes;
48 private final RowType outputRowType;
49+ private final boolean openBoth;
50
51 @Override
52 public CompoundExplainer getExplainer(ExplainContext context)
53@@ -202,6 +205,8 @@
54
55 att.put(Label.OUTPUT_TYPE, outputRowType.getExplainer(context));
56
57+ att.put(Label.PIPELINE, PrimitiveExplainer.getInstance(openBoth));
58+
59 return new CompoundExplainer(Type.UNION, att);
60 }
61
62@@ -213,8 +218,11 @@
63 try {
64 CursorLifecycle.checkIdle(this);
65 idle = false;
66- // TODO: Have a mode where all the cursors get opened
67- // so that they can start in parallel.
68+ if (openBoth) {
69+ for (int i = 0; i < cursors.length; i++) {
70+ cursors[i].open();
71+ }
72+ }
73 } finally {
74 TAP_OPEN.out();
75 }
76@@ -261,11 +269,16 @@
77 @Override
78 public void close() {
79 CursorLifecycle.checkIdleOrActive(this);
80- inputOperatorsIndex = -1;
81 if (currentCursor != null) {
82 currentCursor.close();
83 currentCursor = null;
84 }
85+ if (openBoth) {
86+ while (++inputOperatorsIndex < inputs.size()) {
87+ cursors[inputOperatorsIndex].close();
88+ }
89+ }
90+ inputOperatorsIndex = -1;
91 currentInputRowType = null;
92 rowHolder.release();
93 idle = true;
94@@ -355,7 +368,9 @@
95 private Row nextCursorFirstRow() {
96 while (++inputOperatorsIndex < inputs.size()) {
97 Cursor nextCursor = cursors[inputOperatorsIndex];
98- nextCursor.open();
99+ if (!openBoth) {
100+ nextCursor.open();
101+ }
102 Row nextRow = nextCursor.next();
103 if (nextRow == null) {
104 nextCursor.close();
105
106=== modified file 'src/main/java/com/akiban/sql/optimizer/rule/OperatorAssembler.java'
107--- src/main/java/com/akiban/sql/optimizer/rule/OperatorAssembler.java 2013-07-17 20:48:07 +0000
108+++ src/main/java/com/akiban/sql/optimizer/rule/OperatorAssembler.java 2013-07-18 20:38:26 +0000
109@@ -1243,7 +1243,7 @@
110 ascending, unionOrderedAll);
111 }
112 else {
113- stream.operator = API.unionAll(stream.operator, stream.rowType, scan, indexRowType);
114+ stream.operator = API.unionAll_Default(stream.operator, stream.rowType, scan, indexRowType, rulesContext.getPipelineConfiguration().isUnionAllOpenBoth());
115 stream.rowType = stream.operator.rowType();
116 }
117 }
118
119=== added file 'src/test/java/com/akiban/qp/operator/UnionAll_DefaultOpenBothTest.java'
120--- src/test/java/com/akiban/qp/operator/UnionAll_DefaultOpenBothTest.java 1970-01-01 00:00:00 +0000
121+++ src/test/java/com/akiban/qp/operator/UnionAll_DefaultOpenBothTest.java 2013-07-18 20:38:26 +0000
122@@ -0,0 +1,26 @@
123+/**
124+ * Copyright (C) 2009-2013 Akiban Technologies, Inc.
125+ *
126+ * This program is free software: you can redistribute it and/or modify
127+ * it under the terms of the GNU Affero General Public License as published by
128+ * the Free Software Foundation, either version 3 of the License, or
129+ * (at your option) any later version.
130+ *
131+ * This program is distributed in the hope that it will be useful,
132+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
133+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
134+ * GNU Affero General Public License for more details.
135+ *
136+ * You should have received a copy of the GNU Affero General Public License
137+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
138+ */
139+
140+package com.akiban.qp.operator;
141+
142+public class UnionAll_DefaultOpenBothTest extends UnionAll_DefaultTest
143+{
144+ @Override
145+ protected boolean openBoth() {
146+ return true;
147+ }
148+}
149
150=== modified file 'src/test/java/com/akiban/qp/operator/UnionAll_DefaultTest.java'
151--- src/test/java/com/akiban/qp/operator/UnionAll_DefaultTest.java 2013-03-22 20:05:57 +0000
152+++ src/test/java/com/akiban/qp/operator/UnionAll_DefaultTest.java 2013-07-18 20:38:26 +0000
153@@ -27,8 +27,12 @@
154 import static org.junit.Assert.assertEquals;
155 import static org.junit.Assert.assertSame;
156
157-public final class UnionAll_DefaultTest {
158+public class UnionAll_DefaultTest {
159
160+ protected boolean openBoth() {
161+ return false;
162+ }
163+
164 @Test
165 public void unionTwoNormal() {
166 DerivedTypesSchema schema = new DerivedTypesSchema();
167@@ -167,7 +171,7 @@
168 DerivedTypesSchema schema = new DerivedTypesSchema();
169 RowsBuilder first = new RowsBuilder(schema, AkType.LONG, AkType.VARCHAR);
170 RowsBuilder second = new RowsBuilder(schema, AkType.LONG, AkType.NULL);
171- new UnionAll_Default(null, first.rowType(), new TestOperator(second), second.rowType(), Types3Switch.ON);
172+ new UnionAll_Default(null, first.rowType(), new TestOperator(second), second.rowType(), Types3Switch.ON, openBoth());
173 }
174
175 @Test(expected = IllegalArgumentException.class)
176@@ -175,7 +179,7 @@
177 DerivedTypesSchema schema = new DerivedTypesSchema();
178 RowsBuilder first = new RowsBuilder(schema, AkType.LONG, AkType.VARCHAR);
179 RowsBuilder second = new RowsBuilder(schema, AkType.LONG, AkType.NULL);
180- new UnionAll_Default(new TestOperator(first), null, new TestOperator(second), second.rowType(), Types3Switch.ON);
181+ new UnionAll_Default(new TestOperator(first), null, new TestOperator(second), second.rowType(), Types3Switch.ON, openBoth());
182 }
183
184 @Test(expected = IllegalArgumentException.class)
185@@ -183,7 +187,7 @@
186 DerivedTypesSchema schema = new DerivedTypesSchema();
187 RowsBuilder first = new RowsBuilder(schema, AkType.LONG, AkType.VARCHAR);
188 RowsBuilder second = new RowsBuilder(schema, AkType.LONG, AkType.NULL);
189- new UnionAll_Default(new TestOperator(first), first.rowType(), null, second.rowType(), Types3Switch.ON);
190+ new UnionAll_Default(new TestOperator(first), first.rowType(), null, second.rowType(), Types3Switch.ON, openBoth());
191 }
192
193 @Test(expected = IllegalArgumentException.class)
194@@ -191,7 +195,7 @@
195 DerivedTypesSchema schema = new DerivedTypesSchema();
196 RowsBuilder first = new RowsBuilder(schema, AkType.LONG, AkType.VARCHAR);
197 RowsBuilder second = new RowsBuilder(schema, AkType.LONG, AkType.NULL);
198- new UnionAll_Default(new TestOperator(first), first.rowType(), new TestOperator(second), null, Types3Switch.ON);
199+ new UnionAll_Default(new TestOperator(first), first.rowType(), new TestOperator(second), null, Types3Switch.ON, openBoth());
200 }
201
202 /**
203@@ -213,7 +217,7 @@
204 OperatorTestHelper.execute(union);
205 }
206
207- private static void check(Operator union, RowsBuilder expected) {
208+ private void check(Operator union, RowsBuilder expected) {
209 final RowType outputRowType = union.rowType();
210 checkRowTypes(expected.rowType(), outputRowType);
211
212@@ -225,7 +229,7 @@
213 });
214 }
215
216- private static void check(RowsBuilder rb1, RowsBuilder rb2, RowsBuilder expected) {
217+ private void check(RowsBuilder rb1, RowsBuilder rb2, RowsBuilder expected) {
218 check(union(rb1, rb2), expected);
219 }
220
221@@ -239,13 +243,14 @@
222 }
223 }
224
225- private static Operator union(RowsBuilder rb1, RowsBuilder rb2) {
226+ private Operator union(RowsBuilder rb1, RowsBuilder rb2) {
227 return new UnionAll_Default(
228 new TestOperator(rb1),
229 rb1.rowType(),
230 new TestOperator(rb2),
231 rb2.rowType(),
232- Types3Switch.ON
233+ Types3Switch.ON,
234+ openBoth()
235 );
236 }
237 }
238
239=== modified file 'src/test/java/com/akiban/server/test/it/qp/UnionAll_DefaultIT.java'
240--- src/test/java/com/akiban/server/test/it/qp/UnionAll_DefaultIT.java 2013-07-13 19:25:25 +0000
241+++ src/test/java/com/akiban/server/test/it/qp/UnionAll_DefaultIT.java 2013-07-18 20:38:26 +0000
242@@ -70,30 +70,34 @@
243 use(db);
244 }
245
246+ protected boolean openBoth() {
247+ return false;
248+ }
249+
250 // Test argument validation
251
252 @Test(expected = IllegalArgumentException.class)
253 public void testNullInput1()
254 {
255- unionAll(null, tRowType, groupScan_Default(groupTable), tRowType);
256+ unionAll_Default(null, tRowType, groupScan_Default(groupTable), tRowType, false);
257 }
258
259 @Test(expected = IllegalArgumentException.class)
260 public void testNullInput1Type()
261 {
262- unionAll(groupScan_Default(groupTable), null, groupScan_Default(groupTable), tRowType);
263+ unionAll_Default(groupScan_Default(groupTable), null, groupScan_Default(groupTable), tRowType, false);
264 }
265
266 @Test(expected = IllegalArgumentException.class)
267 public void testNullInput2()
268 {
269- unionAll(groupScan_Default(groupTable), tRowType, null, tRowType);
270+ unionAll_Default(groupScan_Default(groupTable), tRowType, null, tRowType, false);
271 }
272
273 @Test(expected = IllegalArgumentException.class)
274 public void testNullInput2Type()
275 {
276- unionAll(groupScan_Default(groupTable), tRowType, groupScan_Default(groupTable), null);
277+ unionAll_Default(groupScan_Default(groupTable), tRowType, groupScan_Default(groupTable), null, false);
278 }
279
280 // Test operator execution
281@@ -102,17 +106,18 @@
282 public void testBothEmpty()
283 {
284 Operator plan =
285- unionAll(
286- select_HKeyOrdered(
287- groupScan_Default(groupTable),
288- tRowType,
289- ExpressionGenerators.literal(false)),
290- tRowType,
291- select_HKeyOrdered(
292- groupScan_Default(groupTable),
293- tRowType,
294- ExpressionGenerators.literal(false)),
295- tRowType);
296+ unionAll_Default(
297+ select_HKeyOrdered(
298+ groupScan_Default(groupTable),
299+ tRowType,
300+ ExpressionGenerators.literal(false)),
301+ tRowType,
302+ select_HKeyOrdered(
303+ groupScan_Default(groupTable),
304+ tRowType,
305+ ExpressionGenerators.literal(false)),
306+ tRowType,
307+ openBoth());
308 RowBase[] expected = new RowBase[]{};
309 compareRows(expected, cursor(plan, queryContext, queryBindings));
310 }
311@@ -121,7 +126,7 @@
312 public void testLeftEmpty()
313 {
314 Operator plan =
315- unionAll(
316+ unionAll_Default(
317 select_HKeyOrdered(
318 groupScan_Default(groupTable),
319 tRowType,
320@@ -134,7 +139,8 @@
321 ExpressionGenerators.field(tRowType, 1),
322 Comparison.EQ,
323 ExpressionGenerators.literal(9), castResolver())),
324- tRowType);
325+ tRowType,
326+ openBoth());
327 RowBase[] expected = new RowBase[]{
328 row(tRowType, 1001L, 9L),
329 row(tRowType, 1003L, 9L),
330@@ -148,7 +154,7 @@
331 public void testRightEmpty()
332 {
333 Operator plan =
334- unionAll(
335+ unionAll_Default(
336 select_HKeyOrdered(
337 groupScan_Default(groupTable),
338 tRowType,
339@@ -161,7 +167,8 @@
340 groupScan_Default(groupTable),
341 tRowType,
342 ExpressionGenerators.literal(false)),
343- tRowType);
344+ tRowType,
345+ openBoth());
346 RowBase[] expected = new RowBase[]{
347 row(tRowType, 1000L, 8L),
348 row(tRowType, 1002L, 8L),
349@@ -175,7 +182,7 @@
350 public void testBothNonEmpty()
351 {
352 Operator plan =
353- unionAll(
354+ unionAll_Default(
355 select_HKeyOrdered(
356 groupScan_Default(groupTable),
357 tRowType,
358@@ -191,7 +198,8 @@
359 ExpressionGenerators.field(tRowType, 1),
360 Comparison.EQ,
361 ExpressionGenerators.literal(9), castResolver())),
362- tRowType);
363+ tRowType,
364+ openBoth());
365 RowBase[] expected = new RowBase[]{
366 row(tRowType, 1000L, 8L),
367 row(tRowType, 1002L, 8L),
368@@ -209,7 +217,7 @@
369 public void testCursor()
370 {
371 Operator plan =
372- unionAll(
373+ unionAll_Default(
374 select_HKeyOrdered(
375 groupScan_Default(groupTable),
376 tRowType,
377@@ -225,7 +233,8 @@
378 ExpressionGenerators.field(tRowType, 1),
379 Comparison.EQ,
380 ExpressionGenerators.literal(9), castResolver())),
381- tRowType);
382+ tRowType,
383+ openBoth());
384 CursorLifecycleTestCase testCase = new CursorLifecycleTestCase()
385 {
386 @Override
387@@ -261,7 +270,7 @@
388 limit_Default(
389 groupScan_Default(groupTable),
390 2),
391- unionAll(
392+ unionAll_Default(
393 indexScan_Default(txIndexRowType,
394 xEQ8Range,
395 ordering),
396@@ -269,7 +278,7 @@
397 indexScan_Default(txIndexRowType,
398 xEQ9Range,
399 ordering),
400- txIndexRowType),
401+ txIndexRowType, openBoth()),
402 0, pipelineMap(), 1);
403 String[] expected = new String[]{
404 hKey(1000),
405
406=== added file 'src/test/java/com/akiban/server/test/it/qp/UnionAll_DefaultPipelineIT.java'
407--- src/test/java/com/akiban/server/test/it/qp/UnionAll_DefaultPipelineIT.java 1970-01-01 00:00:00 +0000
408+++ src/test/java/com/akiban/server/test/it/qp/UnionAll_DefaultPipelineIT.java 2013-07-18 20:38:26 +0000
409@@ -0,0 +1,31 @@
410+/**
411+ * Copyright (C) 2009-2013 Akiban Technologies, Inc.
412+ *
413+ * This program is free software: you can redistribute it and/or modify
414+ * it under the terms of the GNU Affero General Public License as published by
415+ * the Free Software Foundation, either version 3 of the License, or
416+ * (at your option) any later version.
417+ *
418+ * This program is distributed in the hope that it will be useful,
419+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
420+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
421+ * GNU Affero General Public License for more details.
422+ *
423+ * You should have received a copy of the GNU Affero General Public License
424+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
425+ */
426+
427+package com.akiban.server.test.it.qp;
428+
429+public class UnionAll_DefaultPipelineIT extends UnionAll_DefaultIT
430+{
431+ @Override
432+ protected boolean pipelineMap() {
433+ return true;
434+ }
435+
436+ @Override
437+ protected boolean openBoth() {
438+ return true;
439+ }
440+}

Subscribers

People subscribed via source and target branches