Merge lp:~mmcm/akiban-server/query-bindings-cursor into lp:~akiban-technologies/akiban-server/trunk
- query-bindings-cursor
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Nathan Williams |
Approved revision: | 2716 |
Merged at revision: | 2692 |
Proposed branch: | lp:~mmcm/akiban-server/query-bindings-cursor |
Merge into: | lp:~akiban-technologies/akiban-server/trunk |
Prerequisite: | lp:~mmcm/akiban-server/query-bindings |
Diff against target: |
6940 lines (+1597/-1012) 136 files modified
src/main/java/com/akiban/qp/loadableplan/std/DumpGroupLoadablePlan.java (+2/-2) src/main/java/com/akiban/qp/memoryadapter/MemoryAdapter.java (+3/-2) src/main/java/com/akiban/qp/operator/API.java (+6/-2) src/main/java/com/akiban/qp/operator/Aggregate_Partial.java (+22/-6) src/main/java/com/akiban/qp/operator/AncestorLookup_Default.java (+5/-25) src/main/java/com/akiban/qp/operator/AncestorLookup_Nested.java (+5/-5) src/main/java/com/akiban/qp/operator/BindingsAwareCursor.java (+23/-0) src/main/java/com/akiban/qp/operator/BranchLookup_Default.java (+10/-12) src/main/java/com/akiban/qp/operator/BranchLookup_Nested.java (+5/-5) src/main/java/com/akiban/qp/operator/ChainedCursor.java (+20/-3) src/main/java/com/akiban/qp/operator/Count_Default.java (+5/-13) src/main/java/com/akiban/qp/operator/Count_TableStatus.java (+5/-5) src/main/java/com/akiban/qp/operator/Cursor.java (+31/-0) src/main/java/com/akiban/qp/operator/CursorBase.java (+36/-0) src/main/java/com/akiban/qp/operator/Delete_Default.java (+6/-5) src/main/java/com/akiban/qp/operator/Delete_Returning.java (+11/-22) src/main/java/com/akiban/qp/operator/Distinct_Partial.java (+5/-7) src/main/java/com/akiban/qp/operator/EmitBoundRow_Nested.java (+5/-28) src/main/java/com/akiban/qp/operator/ExecutionBase.java (+1/-3) src/main/java/com/akiban/qp/operator/Filter_Default.java (+5/-19) src/main/java/com/akiban/qp/operator/Flatten_HKeyOrdered.java (+5/-13) src/main/java/com/akiban/qp/operator/GroupCursor.java (+1/-1) src/main/java/com/akiban/qp/operator/GroupScan_Default.java (+68/-18) src/main/java/com/akiban/qp/operator/HKeyUnion_Ordered.java (+34/-7) src/main/java/com/akiban/qp/operator/IfEmpty_Default.java (+5/-13) src/main/java/com/akiban/qp/operator/IndexScan_Default.java (+15/-7) src/main/java/com/akiban/qp/operator/Insert_Default.java (+6/-5) src/main/java/com/akiban/qp/operator/Insert_Returning.java (+12/-23) src/main/java/com/akiban/qp/operator/Intersect_Ordered.java (+34/-7) src/main/java/com/akiban/qp/operator/LeafCursor.java (+45/-0) src/main/java/com/akiban/qp/operator/Limit_Default.java (+4/-4) src/main/java/com/akiban/qp/operator/Map_NestedLoops.java (+30/-9) src/main/java/com/akiban/qp/operator/MultipleQueryBindingsCursor.java (+121/-0) src/main/java/com/akiban/qp/operator/Operator.java (+1/-1) src/main/java/com/akiban/qp/operator/OperatorCursor.java (+42/-0) src/main/java/com/akiban/qp/operator/OperatorExecutionBase.java (+2/-2) src/main/java/com/akiban/qp/operator/Product_NestedLoops.java (+31/-11) src/main/java/com/akiban/qp/operator/Project_Default.java (+12/-17) src/main/java/com/akiban/qp/operator/QueryBindingsCursor.java (+33/-0) src/main/java/com/akiban/qp/operator/RowCursor.java (+1/-1) src/main/java/com/akiban/qp/operator/RowOrientedCursorBase.java (+0/-76) src/main/java/com/akiban/qp/operator/Select_BloomFilter.java (+30/-10) src/main/java/com/akiban/qp/operator/Select_HKeyOrdered.java (+5/-13) src/main/java/com/akiban/qp/operator/SingletonQueryBindingsCursor.java (+61/-0) src/main/java/com/akiban/qp/operator/Sort_General.java (+6/-8) src/main/java/com/akiban/qp/operator/Sort_InsertionLimited.java (+6/-8) src/main/java/com/akiban/qp/operator/SorterToCursorAdapter.java (+5/-5) src/main/java/com/akiban/qp/operator/StoreAdapter.java (+7/-8) src/main/java/com/akiban/qp/operator/UnionAll_Default.java (+40/-14) src/main/java/com/akiban/qp/operator/Union_Ordered.java (+34/-7) src/main/java/com/akiban/qp/operator/Update_Default.java (+6/-5) src/main/java/com/akiban/qp/operator/Update_Returning.java (+12/-23) src/main/java/com/akiban/qp/operator/Using_BloomFilter.java (+8/-35) src/main/java/com/akiban/qp/operator/ValuesScan_Default.java (+5/-5) src/main/java/com/akiban/qp/persistitadapter/OperatorBasedRowCollector.java (+1/-1) src/main/java/com/akiban/qp/persistitadapter/PersistitAdapter.java (+2/-3) src/main/java/com/akiban/qp/persistitadapter/PersistitIndexCursor.java (+8/-5) src/main/java/com/akiban/qp/persistitadapter/Sorter.java (+2/-2) src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursor.java (+15/-11) src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorMixedOrder.java (+2/-5) src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorSpatial_InBox.java (+12/-6) src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorSpatial_NearPoint.java (+16/-9) src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorUnidirectional.java (+4/-8) src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorUnidirectionalLexicographic.java (+2/-5) src/main/java/com/akiban/qp/persistitadapter/indexcursor/MemorySorter.java (+5/-5) src/main/java/com/akiban/qp/persistitadapter/indexcursor/PersistitSorter.java (+8/-6) src/main/java/com/akiban/qp/util/MultiCursor.java (+20/-6) src/main/java/com/akiban/server/expression/subquery/ResultSetSubqueryExpression.java (+1/-1) src/main/java/com/akiban/server/expression/subquery/SubqueryExpressionEvaluation.java (+2/-2) src/main/java/com/akiban/server/service/dxl/BasicDDLFunctions.java (+4/-4) src/main/java/com/akiban/server/service/externaldata/JsonRowWriter.java (+11/-2) src/main/java/com/akiban/server/service/restdml/DeleteProcessor.java (+3/-2) src/main/java/com/akiban/server/service/restdml/ModelBuilder.java (+5/-5) src/main/java/com/akiban/server/service/restdml/RestDMLServiceImpl.java (+2/-1) src/main/java/com/akiban/server/service/restdml/SQLOutputCursor.java (+2/-2) src/main/java/com/akiban/server/service/restdml/UpsertProcessor.java (+1/-1) src/main/java/com/akiban/server/service/text/FullTextCursor.java (+2/-2) src/main/java/com/akiban/server/service/text/FullTextIndexService.java (+3/-2) src/main/java/com/akiban/server/service/text/FullTextIndexServiceImpl.java (+2/-3) src/main/java/com/akiban/server/service/text/FullTextQueryBuilder.java (+30/-0) src/main/java/com/akiban/server/service/text/FullTextQueryExpression.java (+1/-0) src/main/java/com/akiban/server/service/text/IndexScan_FullText.java (+88/-5) src/main/java/com/akiban/server/service/text/RowIndexer.java (+2/-2) src/main/java/com/akiban/server/service/text/Searcher.java (+3/-3) src/main/java/com/akiban/server/store/AbstractStore.java (+5/-3) src/main/java/com/akiban/server/store/StoreGIMaintenance.java (+2/-2) src/main/java/com/akiban/server/types3/texpressions/ResultSetSubqueryTExpression.java (+1/-1) src/main/java/com/akiban/server/types3/texpressions/SubqueryTEvaluateble.java (+2/-2) src/main/java/com/akiban/sql/embedded/ExecutableModifyOperatorStatement.java (+4/-3) src/main/java/com/akiban/sql/embedded/ExecutableQueryOperatorStatement.java (+1/-1) src/main/java/com/akiban/sql/embedded/ExecuteResults.java (+5/-5) src/main/java/com/akiban/sql/embedded/JDBCResultSet.java (+6/-6) src/main/java/com/akiban/sql/pg/PostgresModifyOperatorStatement.java (+1/-1) src/main/java/com/akiban/sql/pg/PostgresOperatorStatement.java (+1/-1) src/test/java/com/akiban/qp/operator/OperatorTestHelper.java (+4/-4) src/test/java/com/akiban/qp/operator/TimeOperator.java (+5/-34) src/test/java/com/akiban/server/test/costmodel/DistinctCT.java (+1/-1) src/test/java/com/akiban/server/test/costmodel/FlattenCT.java (+1/-1) src/test/java/com/akiban/server/test/costmodel/HKeyUnionCT.java (+1/-1) src/test/java/com/akiban/server/test/costmodel/IntersectCT.java (+1/-1) src/test/java/com/akiban/server/test/costmodel/MapCT.java (+1/-1) src/test/java/com/akiban/server/test/costmodel/ProductCT.java (+3/-3) src/test/java/com/akiban/server/test/costmodel/ProjectCT.java (+1/-1) src/test/java/com/akiban/server/test/costmodel/SelectCT.java (+1/-1) src/test/java/com/akiban/server/test/costmodel/Select_BloomFilterCT.java (+1/-1) src/test/java/com/akiban/server/test/costmodel/SortCT.java (+2/-2) src/test/java/com/akiban/server/test/costmodel/SortWithLimitCT.java (+1/-1) src/test/java/com/akiban/server/test/costmodel/TreeScanCT.java (+3/-3) src/test/java/com/akiban/server/test/it/ITBase.java (+20/-8) src/test/java/com/akiban/server/test/it/qp/GroupIndexScanIT.java (+2/-2) src/test/java/com/akiban/server/test/it/qp/GroupScanIT.java (+1/-1) src/test/java/com/akiban/server/test/it/qp/IndexScanIT.java (+1/-1) src/test/java/com/akiban/server/test/it/qp/IndexScanJumpBoundedIT.java (+130/-130) src/test/java/com/akiban/server/test/it/qp/IndexScanJumpUnboundedIT.java (+32/-32) src/test/java/com/akiban/server/test/it/qp/MultiCursorIT.java (+11/-11) src/test/java/com/akiban/server/test/it/qp/NWaySkipScanIT.java (+1/-1) src/test/java/com/akiban/server/test/it/qp/OperatorITBase.java (+25/-12) src/test/java/com/akiban/server/test/it/qp/QueryTimeoutIT.java (+5/-5) src/test/java/com/akiban/server/test/it/qp/SkipScanPerformanceIT.java (+2/-2) src/test/java/com/akiban/server/test/it/qp/SpatialLatLonGroupIndexScanIT.java (+3/-3) src/test/java/com/akiban/server/test/it/qp/SpatialLatLonTableIndexScanIT.java (+7/-7) src/test/java/com/akiban/server/test/it/qp/UniqueIndexJumpUnboundedCompositeKeyIT.java (+2/-2) src/test/java/com/akiban/server/test/it/qp/UniqueIndexScanJumpBoundedUnboundedWithNulls2IT.java (+2/-2) src/test/java/com/akiban/server/test/it/qp/UniqueIndexScanJumpBoundedWithNullsIT.java (+2/-2) src/test/java/com/akiban/server/test/it/qp/UniqueIndexScanJumpUnboundedIT.java (+32/-32) src/test/java/com/akiban/server/test/it/qp/UniqueIndexScanJumpUnboundedWithNullsIT.java (+2/-2) src/test/java/com/akiban/server/test/it/qp/UniqueIndexUpdateIT.java (+5/-5) src/test/java/com/akiban/server/test/it/sort/PersistitSorterOverflowIT.java (+4/-3) src/test/java/com/akiban/server/test/it/sort/SorterITBase.java (+3/-2) src/test/java/com/akiban/server/test/pt/AggregatePT.java (+41/-25) src/test/java/com/akiban/server/test/pt/gi/GIUpdateProfilePT.java (+1/-1) src/test/java/com/akiban/server/test/pt/qp/GroupScanProfilePT.java (+2/-2) src/test/java/com/akiban/server/test/pt/qp/IndexScanPT.java (+2/-2) src/test/java/com/akiban/server/test/pt/qp/QPProfilePTBase.java (+4/-4) src/test/java/com/akiban/server/test/pt/qp/SimpleJoinPT.java (+2/-2) src/test/java/com/akiban/server/test/pt/qp/SortPT.java (+2/-2) |
To merge this branch: | bzr merge lp:~mmcm/akiban-server/query-bindings-cursor |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nathan Williams | Approve | ||
Review via email: mp+173848@code.launchpad.net |
Commit message
Description of the change
Add QueryBindingCursor, which is a stream of QueryBindings.
These methods are then added to Cursor, making it a combined stream of rows and bindings, with the additional contract that the row cursor lifecycle is within a a set of bindings, fixed at open() time.
Since there are still internal streams of rows that are not streams of bindings, such as index and sort cursors, formalize a RowCursor interface for just that.
At top level, when a plan is constructed, a QueryBindingsCursor is supplied for the whole query. In almost all cases, this is a singleton over a set of QueryBindings (holding any parameter passed to the query). This stream is passed to the Operator's cursor method to construct the combined stream cursors. An operator with an input just passes it along to its child's constructor. A leaf operator remembers the stream so that it can implement the new bindings methods using it.
An operator like Union or Intersection that has multiple children that run at the same time needs to multiplex the stream, for which a new helper class is added.
An operator like Map_NestedLoops or Select_BloomFilter that has a slow loop and faster inside loop passes the root stream to the outer loop and arranges for the inner loop to have a stream driven by the outer loop. At present, this means a singleton on the outer loop's bindings, because we are still opening the inner loop each time. That will change when pipelining it added in upcoming branches.
The top-level idea is to have all the operators written to obey the bindings stream protocol, maintaining their state based on it. But there is still only one set of bindings for the whole query, that gets passed along in these various ways. Realistically, that means that the tests find places that would get a NPE from failing to maintin it, but not actual isolation between bindings in the stream. That will have to come with some non-singleton cases.
This would have been a little easier if Types 2 were gone, but obviously I didn't do that here.
This is made somewhat harder by mostly gratuitous differnces in how the various operators are implemented. I made that a tiny bit better, by introducing some classes for the common cases of extends OperatorExecuti
This would have been a little easier without UpdatePlannable, whose run() isn't very cursor-like / prepare friendly, but I think I kept those working.
One of the messier things is the difference between open() and openTopLevel(). The latter means open the bindings stream, get the first (only) bindings, and then open the cursor. It's usually what you want. Except that RowCursor doesn't support it. And some tests on Cursor still want the more limited one when they are testing lifecycle within a bindings. I think I got everything calling the right method, but I am definitely open to suggestions on a different approach to that distinction.
As with the prereq branch, there is no urgency in getting this in, if we want to wait until the latency hiding that will actually make use of it all is working.
- 2716. By Mike McMahon
-
Merge from trunk.
Preview Diff
1 | === modified file 'src/main/java/com/akiban/qp/loadableplan/std/DumpGroupLoadablePlan.java' |
2 | --- src/main/java/com/akiban/qp/loadableplan/std/DumpGroupLoadablePlan.java 2013-07-05 21:35:32 +0000 |
3 | +++ src/main/java/com/akiban/qp/loadableplan/std/DumpGroupLoadablePlan.java 2013-07-10 21:47:26 +0000 |
4 | @@ -23,7 +23,7 @@ |
5 | import com.akiban.qp.loadableplan.DirectObjectPlan; |
6 | import com.akiban.qp.loadableplan.LoadableDirectObjectPlan; |
7 | import com.akiban.qp.operator.BindingNotSetException; |
8 | -import com.akiban.qp.operator.Cursor; |
9 | +import com.akiban.qp.operator.RowCursor; |
10 | import com.akiban.qp.operator.QueryBindings; |
11 | import com.akiban.qp.operator.QueryContext; |
12 | import com.akiban.qp.row.Row; |
13 | @@ -68,7 +68,7 @@ |
14 | private final QueryContext context; |
15 | private final QueryBindings bindings; |
16 | private UserTable rootTable; |
17 | - private Cursor cursor; |
18 | + private RowCursor cursor; |
19 | private Map<UserTable,Integer> tableSizes; |
20 | private StringBuilder buffer; |
21 | private GroupRowFormatter formatter; |
22 | |
23 | === modified file 'src/main/java/com/akiban/qp/memoryadapter/MemoryAdapter.java' |
24 | --- src/main/java/com/akiban/qp/memoryadapter/MemoryAdapter.java 2013-07-08 15:56:07 +0000 |
25 | +++ src/main/java/com/akiban/qp/memoryadapter/MemoryAdapter.java 2013-07-10 21:47:26 +0000 |
26 | @@ -28,6 +28,7 @@ |
27 | import com.akiban.qp.operator.IndexScanSelector; |
28 | import com.akiban.qp.operator.QueryBindings; |
29 | import com.akiban.qp.operator.QueryContext; |
30 | +import com.akiban.qp.operator.RowCursor; |
31 | import com.akiban.qp.operator.StoreAdapter; |
32 | import com.akiban.qp.operator.API.Ordering; |
33 | import com.akiban.qp.operator.API.SortOption; |
34 | @@ -72,7 +73,7 @@ |
35 | } |
36 | |
37 | @Override |
38 | - public Cursor newIndexCursor(QueryContext context, QueryBindings bindings, Index index, |
39 | + public RowCursor newIndexCursor(QueryContext context, Index index, |
40 | IndexKeyRange keyRange, Ordering ordering, |
41 | IndexScanSelector scanSelector, boolean usePValues) { |
42 | |
43 | @@ -93,7 +94,7 @@ |
44 | } |
45 | |
46 | @Override |
47 | - public Sorter createSorter(QueryContext context, QueryBindings bindings, Cursor input, RowType rowType, |
48 | + public Sorter createSorter(QueryContext context, QueryBindings bindings, RowCursor input, RowType rowType, |
49 | Ordering ordering, SortOption sortOption, InOutTap loadTap) { |
50 | throw new UnsupportedOperationException(); |
51 | } |
52 | |
53 | === modified file 'src/main/java/com/akiban/qp/operator/API.java' |
54 | --- src/main/java/com/akiban/qp/operator/API.java 2013-07-05 21:35:32 +0000 |
55 | +++ src/main/java/com/akiban/qp/operator/API.java 2013-07-10 21:47:26 +0000 |
56 | @@ -738,10 +738,14 @@ |
57 | |
58 | // Execution interface |
59 | |
60 | + public static Cursor cursor(Operator root, QueryContext context, QueryBindingsCursor bindingsCursor) |
61 | + { |
62 | + return new ChainedCursor(context, root.cursor(context, bindingsCursor)); |
63 | + } |
64 | + |
65 | public static Cursor cursor(Operator root, QueryContext context, QueryBindings bindings) |
66 | { |
67 | - // if all they need is the wrapped cursor, create it directly |
68 | - return new ChainedCursor(context, bindings, root.cursor(context, bindings)); |
69 | + return cursor(root, context, new SingletonQueryBindingsCursor(bindings)); |
70 | } |
71 | |
72 | // Options |
73 | |
74 | === modified file 'src/main/java/com/akiban/qp/operator/Aggregate_Partial.java' |
75 | --- src/main/java/com/akiban/qp/operator/Aggregate_Partial.java 2013-07-05 21:35:32 +0000 |
76 | +++ src/main/java/com/akiban/qp/operator/Aggregate_Partial.java 2013-07-10 21:47:26 +0000 |
77 | @@ -165,7 +165,7 @@ |
78 | // Operator interface |
79 | |
80 | @Override |
81 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) { |
82 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) { |
83 | final List<Aggregator> aggregators; |
84 | if (aggregatorFactories != null) { |
85 | aggregators = new ArrayList<>(); |
86 | @@ -182,7 +182,7 @@ |
87 | aggregators = null; |
88 | } |
89 | return new AggregateCursor( |
90 | - context, bindings, |
91 | + context, bindingsCursor, |
92 | aggregators |
93 | ); |
94 | } |
95 | @@ -369,7 +369,7 @@ |
96 | |
97 | // nested classes |
98 | |
99 | - private class AggregateCursor extends OperatorExecutionBase implements Cursor |
100 | + private class AggregateCursor extends OperatorCursor |
101 | { |
102 | |
103 | // Cursor interface |
104 | @@ -487,6 +487,22 @@ |
105 | return cursorState == CursorState.DESTROYED; |
106 | } |
107 | |
108 | + |
109 | + @Override |
110 | + public void openBindings() { |
111 | + inputCursor.openBindings(); |
112 | + } |
113 | + |
114 | + @Override |
115 | + public QueryBindings nextBindings() { |
116 | + return inputCursor.nextBindings(); |
117 | + } |
118 | + |
119 | + @Override |
120 | + public void closeBindings() { |
121 | + inputCursor.closeBindings(); |
122 | + } |
123 | + |
124 | // for use in this class |
125 | |
126 | private void aggregate(Row input) { |
127 | @@ -641,10 +657,10 @@ |
128 | |
129 | // AggregateCursor interface |
130 | |
131 | - private AggregateCursor(QueryContext context, QueryBindings bindings, |
132 | + private AggregateCursor(QueryContext context, QueryBindingsCursor bindingsCursor, |
133 | List<Aggregator> aggregators) { |
134 | - super(context, bindings); |
135 | - this.inputCursor = inputOperator.cursor(context, bindings); |
136 | + super(context); |
137 | + this.inputCursor = inputOperator.cursor(context, bindingsCursor); |
138 | this.aggregators = aggregators; |
139 | if (aggregators != null) { |
140 | keyValues = new ArrayList<>(); |
141 | |
142 | === modified file 'src/main/java/com/akiban/qp/operator/AncestorLookup_Default.java' |
143 | --- src/main/java/com/akiban/qp/operator/AncestorLookup_Default.java 2013-07-05 21:35:32 +0000 |
144 | +++ src/main/java/com/akiban/qp/operator/AncestorLookup_Default.java 2013-07-10 21:47:26 +0000 |
145 | @@ -131,9 +131,9 @@ |
146 | } |
147 | |
148 | @Override |
149 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
150 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
151 | { |
152 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
153 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
154 | } |
155 | |
156 | @Override |
157 | @@ -252,7 +252,7 @@ |
158 | |
159 | // Inner classes |
160 | |
161 | - private class Execution extends OperatorExecutionBase implements Cursor |
162 | + private class Execution extends ChainedCursor |
163 | { |
164 | // Cursor interface |
165 | |
166 | @@ -313,30 +313,11 @@ |
167 | input.destroy(); |
168 | } |
169 | |
170 | - @Override |
171 | - public boolean isIdle() |
172 | - { |
173 | - return input.isIdle(); |
174 | - } |
175 | - |
176 | - @Override |
177 | - public boolean isActive() |
178 | - { |
179 | - return input.isActive(); |
180 | - } |
181 | - |
182 | - @Override |
183 | - public boolean isDestroyed() |
184 | - { |
185 | - return input.isDestroyed(); |
186 | - } |
187 | - |
188 | // Execution interface |
189 | |
190 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
191 | + Execution(QueryContext context, Cursor input) |
192 | { |
193 | - super(context, bindings); |
194 | - this.input = input; |
195 | + super(context, input); |
196 | // Why + 1: Because the input row (whose ancestors get discovered) also goes into pending. |
197 | this.pending = new PendingRows(ancestors.size() + 1); |
198 | this.ancestorCursor = adapter().newGroupCursor(group); |
199 | @@ -391,7 +372,6 @@ |
200 | |
201 | // Object state |
202 | |
203 | - private final Cursor input; |
204 | private final ShareHolder<Row> inputRow = new ShareHolder<>(); |
205 | private final GroupCursor ancestorCursor; |
206 | private final ShareHolder<Row> ancestorRow = new ShareHolder<>(); |
207 | |
208 | === modified file 'src/main/java/com/akiban/qp/operator/AncestorLookup_Nested.java' |
209 | --- src/main/java/com/akiban/qp/operator/AncestorLookup_Nested.java 2013-07-05 21:35:32 +0000 |
210 | +++ src/main/java/com/akiban/qp/operator/AncestorLookup_Nested.java 2013-07-10 21:47:26 +0000 |
211 | @@ -129,9 +129,9 @@ |
212 | } |
213 | |
214 | @Override |
215 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
216 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
217 | { |
218 | - return new Execution(context, bindings); |
219 | + return new Execution(context, bindingsCursor); |
220 | } |
221 | |
222 | @Override |
223 | @@ -235,7 +235,7 @@ |
224 | |
225 | // Inner classes |
226 | |
227 | - private class Execution extends OperatorExecutionBase implements Cursor |
228 | + private class Execution extends LeafCursor |
229 | { |
230 | // Cursor interface |
231 | |
232 | @@ -320,9 +320,9 @@ |
233 | |
234 | // Execution interface |
235 | |
236 | - Execution(QueryContext context, QueryBindings bindings) |
237 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
238 | { |
239 | - super(context, bindings); |
240 | + super(context, bindingsCursor); |
241 | this.pending = new PendingRows(ancestors.size() + 1); |
242 | this.ancestorCursor = adapter().newGroupCursor(group); |
243 | } |
244 | |
245 | === added file 'src/main/java/com/akiban/qp/operator/BindingsAwareCursor.java' |
246 | --- src/main/java/com/akiban/qp/operator/BindingsAwareCursor.java 1970-01-01 00:00:00 +0000 |
247 | +++ src/main/java/com/akiban/qp/operator/BindingsAwareCursor.java 2013-07-10 21:47:26 +0000 |
248 | @@ -0,0 +1,23 @@ |
249 | +/** |
250 | + * Copyright (C) 2009-2013 Akiban Technologies, Inc. |
251 | + * |
252 | + * This program is free software: you can redistribute it and/or modify |
253 | + * it under the terms of the GNU Affero General Public License as published by |
254 | + * the Free Software Foundation, either version 3 of the License, or |
255 | + * (at your option) any later version. |
256 | + * |
257 | + * This program is distributed in the hope that it will be useful, |
258 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
259 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
260 | + * GNU Affero General Public License for more details. |
261 | + * |
262 | + * You should have received a copy of the GNU Affero General Public License |
263 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
264 | + */ |
265 | + |
266 | +package com.akiban.qp.operator; |
267 | + |
268 | +public interface BindingsAwareCursor extends RowCursor |
269 | +{ |
270 | + public void rebind(QueryBindings bindings); |
271 | +} |
272 | |
273 | === modified file 'src/main/java/com/akiban/qp/operator/BranchLookup_Default.java' |
274 | --- src/main/java/com/akiban/qp/operator/BranchLookup_Default.java 2013-07-05 21:35:32 +0000 |
275 | +++ src/main/java/com/akiban/qp/operator/BranchLookup_Default.java 2013-07-10 21:47:26 +0000 |
276 | @@ -162,9 +162,9 @@ |
277 | } |
278 | |
279 | @Override |
280 | - public Cursor cursor(QueryContext context, QueryBindings bindings) |
281 | + public Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
282 | { |
283 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
284 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
285 | } |
286 | |
287 | @Override |
288 | @@ -300,7 +300,7 @@ |
289 | return new LookUpOperatorExplainer(getName(), atts, inputRowType, keepInput, inputOperator, context); |
290 | } |
291 | |
292 | - private class Execution extends OperatorExecutionBase implements Cursor |
293 | + private class Execution extends ChainedCursor |
294 | { |
295 | // Cursor interface |
296 | |
297 | @@ -310,7 +310,7 @@ |
298 | TAP_OPEN.in(); |
299 | try { |
300 | CursorLifecycle.checkIdle(this); |
301 | - inputCursor.open(); |
302 | + input.open(); |
303 | advanceInput(); |
304 | idle = false; |
305 | } finally { |
306 | @@ -371,7 +371,7 @@ |
307 | { |
308 | CursorLifecycle.checkIdleOrActive(this); |
309 | if (!idle) { |
310 | - inputCursor.close(); |
311 | + input.close(); |
312 | inputRow.release(); |
313 | lookupCursor.close(); |
314 | lookupRow.release(); |
315 | @@ -383,7 +383,7 @@ |
316 | public void destroy() |
317 | { |
318 | close(); |
319 | - inputCursor.destroy(); |
320 | + input.destroy(); |
321 | lookupCursor.destroy(); |
322 | } |
323 | |
324 | @@ -402,15 +402,14 @@ |
325 | @Override |
326 | public boolean isDestroyed() |
327 | { |
328 | - return inputCursor.isDestroyed(); |
329 | + return input.isDestroyed(); |
330 | } |
331 | |
332 | // Execution interface |
333 | |
334 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
335 | + Execution(QueryContext context, Cursor input) |
336 | { |
337 | - super(context, bindings); |
338 | - this.inputCursor = input; |
339 | + super(context, input); |
340 | this.lookupCursor = adapter().newGroupCursor(group); |
341 | this.lookupRowHKey = adapter().newHKey(outputRowType.hKey()); |
342 | } |
343 | @@ -439,7 +438,7 @@ |
344 | lookupState = LookupState.BEFORE; |
345 | lookupRow.release(); |
346 | lookupCursor.close(); |
347 | - Row currentInputRow = inputCursor.next(); |
348 | + Row currentInputRow = input.next(); |
349 | if (currentInputRow != null) { |
350 | if (currentInputRow.rowType() == inputRowType) { |
351 | lookupRow.release(); |
352 | @@ -464,7 +463,6 @@ |
353 | |
354 | // Object state |
355 | |
356 | - private final Cursor inputCursor; |
357 | private final ShareHolder<Row> inputRow = new ShareHolder<>(); |
358 | private final GroupCursor lookupCursor; |
359 | private final ShareHolder<Row> lookupRow = new ShareHolder<>(); |
360 | |
361 | === modified file 'src/main/java/com/akiban/qp/operator/BranchLookup_Nested.java' |
362 | --- src/main/java/com/akiban/qp/operator/BranchLookup_Nested.java 2013-07-05 21:35:32 +0000 |
363 | +++ src/main/java/com/akiban/qp/operator/BranchLookup_Nested.java 2013-07-10 21:47:26 +0000 |
364 | @@ -148,9 +148,9 @@ |
365 | } |
366 | |
367 | @Override |
368 | - public Cursor cursor(QueryContext context, QueryBindings bindings) |
369 | + public Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
370 | { |
371 | - return new Execution(context, bindings); |
372 | + return new Execution(context, bindingsCursor); |
373 | } |
374 | |
375 | @Override |
376 | @@ -285,7 +285,7 @@ |
377 | |
378 | // Inner classes |
379 | |
380 | - private class Execution extends OperatorExecutionBase implements Cursor |
381 | + private class Execution extends LeafCursor |
382 | { |
383 | // Cursor interface |
384 | |
385 | @@ -383,9 +383,9 @@ |
386 | |
387 | // Execution interface |
388 | |
389 | - Execution(QueryContext context, QueryBindings bindings) |
390 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
391 | { |
392 | - super(context, bindings); |
393 | + super(context, bindingsCursor); |
394 | this.cursor = adapter().newGroupCursor(group); |
395 | this.hKey = adapter().newHKey(outputRowType.hKey()); |
396 | } |
397 | |
398 | === modified file 'src/main/java/com/akiban/qp/operator/ChainedCursor.java' |
399 | --- src/main/java/com/akiban/qp/operator/ChainedCursor.java 2013-07-05 21:35:32 +0000 |
400 | +++ src/main/java/com/akiban/qp/operator/ChainedCursor.java 2013-07-10 21:47:26 +0000 |
401 | @@ -20,12 +20,13 @@ |
402 | import com.akiban.qp.row.Row; |
403 | import com.akiban.server.api.dml.ColumnSelector; |
404 | |
405 | -public class ChainedCursor extends OperatorExecutionBase implements Cursor |
406 | +public class ChainedCursor extends OperatorCursor |
407 | { |
408 | protected final Cursor input; |
409 | + protected QueryBindings bindings; |
410 | |
411 | - protected ChainedCursor(QueryContext context, QueryBindings bindings, Cursor input) { |
412 | - super(context, bindings); |
413 | + protected ChainedCursor(QueryContext context, Cursor input) { |
414 | + super(context); |
415 | this.input = input; |
416 | } |
417 | |
418 | @@ -74,4 +75,20 @@ |
419 | { |
420 | return input.isDestroyed(); |
421 | } |
422 | + |
423 | + @Override |
424 | + public void openBindings() { |
425 | + input.openBindings(); |
426 | + } |
427 | + |
428 | + @Override |
429 | + public QueryBindings nextBindings() { |
430 | + bindings = input.nextBindings(); |
431 | + return bindings; |
432 | + } |
433 | + |
434 | + @Override |
435 | + public void closeBindings() { |
436 | + input.closeBindings(); |
437 | + } |
438 | } |
439 | |
440 | === modified file 'src/main/java/com/akiban/qp/operator/Count_Default.java' |
441 | --- src/main/java/com/akiban/qp/operator/Count_Default.java 2013-07-05 21:35:32 +0000 |
442 | +++ src/main/java/com/akiban/qp/operator/Count_Default.java 2013-07-10 21:47:26 +0000 |
443 | @@ -93,9 +93,9 @@ |
444 | } |
445 | |
446 | @Override |
447 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
448 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
449 | { |
450 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
451 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
452 | } |
453 | |
454 | @Override |
455 | @@ -151,7 +151,7 @@ |
456 | |
457 | // Inner classes |
458 | |
459 | - private class Execution extends OperatorExecutionBase implements Cursor |
460 | + private class Execution extends ChainedCursor |
461 | { |
462 | // Cursor interface |
463 | |
464 | @@ -233,23 +233,15 @@ |
465 | return !closed; |
466 | } |
467 | |
468 | - @Override |
469 | - public boolean isDestroyed() |
470 | - { |
471 | - return input.isDestroyed(); |
472 | - } |
473 | - |
474 | // Execution interface |
475 | |
476 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
477 | + Execution(QueryContext context, Cursor input) |
478 | { |
479 | - super(context, bindings); |
480 | - this.input = input; |
481 | + super(context, input); |
482 | } |
483 | |
484 | // Object state |
485 | |
486 | - private final Cursor input; |
487 | private long count; |
488 | private boolean closed = true; |
489 | } |
490 | |
491 | === modified file 'src/main/java/com/akiban/qp/operator/Count_TableStatus.java' |
492 | --- src/main/java/com/akiban/qp/operator/Count_TableStatus.java 2013-07-05 21:35:32 +0000 |
493 | +++ src/main/java/com/akiban/qp/operator/Count_TableStatus.java 2013-07-10 21:47:26 +0000 |
494 | @@ -86,9 +86,9 @@ |
495 | // Operator interface |
496 | |
497 | @Override |
498 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
499 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
500 | { |
501 | - return new Execution(context, bindings); |
502 | + return new Execution(context, bindingsCursor); |
503 | } |
504 | |
505 | @Override |
506 | @@ -137,7 +137,7 @@ |
507 | |
508 | // Inner classes |
509 | |
510 | - private class Execution extends OperatorExecutionBase implements Cursor |
511 | + private class Execution extends LeafCursor |
512 | { |
513 | // Cursor interface |
514 | |
515 | @@ -219,9 +219,9 @@ |
516 | |
517 | // Execution interface |
518 | |
519 | - Execution(QueryContext context, QueryBindings bindings) |
520 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
521 | { |
522 | - super(context, bindings); |
523 | + super(context, bindingsCursor); |
524 | } |
525 | |
526 | // Object state |
527 | |
528 | === added file 'src/main/java/com/akiban/qp/operator/Cursor.java' |
529 | --- src/main/java/com/akiban/qp/operator/Cursor.java 1970-01-01 00:00:00 +0000 |
530 | +++ src/main/java/com/akiban/qp/operator/Cursor.java 2013-07-10 21:47:26 +0000 |
531 | @@ -0,0 +1,31 @@ |
532 | +/** |
533 | + * Copyright (C) 2009-2013 Akiban Technologies, Inc. |
534 | + * |
535 | + * This program is free software: you can redistribute it and/or modify |
536 | + * it under the terms of the GNU Affero General Public License as published by |
537 | + * the Free Software Foundation, either version 3 of the License, or |
538 | + * (at your option) any later version. |
539 | + * |
540 | + * This program is distributed in the hope that it will be useful, |
541 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
542 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
543 | + * GNU Affero General Public License for more details. |
544 | + * |
545 | + * You should have received a copy of the GNU Affero General Public License |
546 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
547 | + */ |
548 | + |
549 | +package com.akiban.qp.operator; |
550 | + |
551 | +public interface Cursor extends RowCursor, QueryBindingsCursor |
552 | +{ |
553 | + /** Open this cursor for top-level execution: opens the bindings |
554 | + * stream and then the cursor within the only bindings. |
555 | + */ |
556 | + public QueryBindings openTopLevel(); |
557 | + |
558 | + /** Close top-level execution: check that there are no further |
559 | + * bindings and close cursor and bindings. |
560 | + */ |
561 | + public void closeTopLevel(); |
562 | +} |
563 | |
564 | === modified file 'src/main/java/com/akiban/qp/operator/CursorBase.java' |
565 | --- src/main/java/com/akiban/qp/operator/CursorBase.java 2013-03-22 20:05:57 +0000 |
566 | +++ src/main/java/com/akiban/qp/operator/CursorBase.java 2013-07-10 21:47:26 +0000 |
567 | @@ -17,6 +17,42 @@ |
568 | |
569 | package com.akiban.qp.operator; |
570 | |
571 | +/* |
572 | + |
573 | +A Cursor is used to scan a sequence of rows resulting from the execution of an operator. |
574 | +The same cursor may be used for multiple executions of the operator, possibly with different bindings. |
575 | + |
576 | +A Cursor is always in one of three states: |
577 | + |
578 | +- IDLE: The cursor is not currently involved in a scan. The cursor is in this state when one |
579 | + of the following is true: |
580 | + - open() has never been called. |
581 | + - The most recent method invocation was to next(), which returned null. |
582 | + - The most recent method invocation was to close(). |
583 | + |
584 | +- ACTIVE: The cursor is currently involved in a scan. The cursor is in this state when one |
585 | + of the following is true: |
586 | + - The most recent method invocation was to open(). |
587 | + - The most recent method invocation was to next(), which returned a non-null value. |
588 | + |
589 | +- DESTROYED: The cursor has been destroyed. Invocations of open, next, or close on such a cursor |
590 | + will raise an exception. The only way to get into this state is to call destroy(). |
591 | + |
592 | +The Cursor lifecycle is as follows: |
593 | + |
594 | + next/jump == null next/jump != null |
595 | + +-+ +-+ |
596 | + | | | | |
597 | + | V open | V destroy |
598 | + --> IDLE ----------> ACTIVE ----------> DESTROYED |
599 | + | <---------- ^ |
600 | + | next/jump = null, | |
601 | + | close | |
602 | + | | |
603 | + +--------------------------------------+ |
604 | + destroy |
605 | + */ |
606 | + |
607 | public interface CursorBase<T> |
608 | { |
609 | /** |
610 | |
611 | === modified file 'src/main/java/com/akiban/qp/operator/Delete_Default.java' |
612 | --- src/main/java/com/akiban/qp/operator/Delete_Default.java 2013-07-05 21:35:32 +0000 |
613 | +++ src/main/java/com/akiban/qp/operator/Delete_Default.java 2013-07-10 21:47:26 +0000 |
614 | @@ -118,7 +118,8 @@ |
615 | |
616 | @Override |
617 | public UpdateResult run(QueryContext context, QueryBindings bindings) { |
618 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)).run(); |
619 | + QueryBindingsCursor bindingsCursor = new SingletonQueryBindingsCursor(bindings); |
620 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)).run(); |
621 | } |
622 | |
623 | @Override |
624 | @@ -152,7 +153,7 @@ |
625 | DELETE_TAP.in(); |
626 | } |
627 | try { |
628 | - input.open(); |
629 | + input.openTopLevel(); |
630 | Row oldRow; |
631 | while ((oldRow = input.next()) != null) { |
632 | checkQueryCancelation(); |
633 | @@ -165,7 +166,7 @@ |
634 | } |
635 | } finally { |
636 | if (input != null) { |
637 | - input.close(); |
638 | + input.destroy(); |
639 | } |
640 | if (TAP_NEXT_ENABLED) { |
641 | DELETE_TAP.out(); |
642 | @@ -174,9 +175,9 @@ |
643 | return new StandardUpdateResult(seen, modified); |
644 | } |
645 | |
646 | - protected Execution(QueryContext queryContext, QueryBindings bindings, Cursor input) |
647 | + protected Execution(QueryContext queryContext, Cursor input) |
648 | { |
649 | - super(queryContext, bindings); |
650 | + super(queryContext); |
651 | this.input = input; |
652 | } |
653 | |
654 | |
655 | === modified file 'src/main/java/com/akiban/qp/operator/Delete_Returning.java' |
656 | --- src/main/java/com/akiban/qp/operator/Delete_Returning.java 2013-07-05 21:35:32 +0000 |
657 | +++ src/main/java/com/akiban/qp/operator/Delete_Returning.java 2013-07-10 21:47:26 +0000 |
658 | @@ -84,8 +84,8 @@ |
659 | |
660 | |
661 | @Override |
662 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) { |
663 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
664 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) { |
665 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
666 | } |
667 | |
668 | @Override |
669 | @@ -125,7 +125,7 @@ |
670 | private final boolean cascadeDelete; |
671 | |
672 | // Inner classes |
673 | - private class Execution extends OperatorExecutionBase implements Cursor |
674 | + private class Execution extends ChainedCursor |
675 | { |
676 | |
677 | // Cursor interface |
678 | @@ -183,42 +183,31 @@ |
679 | @Override |
680 | public void destroy() |
681 | { |
682 | - if (input != null) { |
683 | - close(); |
684 | - input.destroy(); |
685 | - input = null; |
686 | - } |
687 | + close(); |
688 | + input.destroy(); |
689 | } |
690 | |
691 | @Override |
692 | public boolean isIdle() |
693 | { |
694 | - return input != null && idle; |
695 | + return !input.isDestroyed() && idle; |
696 | } |
697 | |
698 | @Override |
699 | public boolean isActive() |
700 | { |
701 | - return input != null && !idle; |
702 | - } |
703 | - |
704 | - @Override |
705 | - public boolean isDestroyed() |
706 | - { |
707 | - return input == null; |
708 | - } |
709 | - |
710 | + return !input.isDestroyed() && !idle; |
711 | + } |
712 | + |
713 | // Execution interface |
714 | |
715 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
716 | + Execution(QueryContext context, Cursor input) |
717 | { |
718 | - super(context, bindings); |
719 | - this.input = input; |
720 | + super(context, input); |
721 | } |
722 | |
723 | // Object state |
724 | |
725 | - private Cursor input; // input = null indicates destroyed. |
726 | private boolean idle = true; |
727 | } |
728 | |
729 | |
730 | === modified file 'src/main/java/com/akiban/qp/operator/Distinct_Partial.java' |
731 | --- src/main/java/com/akiban/qp/operator/Distinct_Partial.java 2013-07-05 21:35:32 +0000 |
732 | +++ src/main/java/com/akiban/qp/operator/Distinct_Partial.java 2013-07-10 21:47:26 +0000 |
733 | @@ -102,9 +102,9 @@ |
734 | } |
735 | |
736 | @Override |
737 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
738 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
739 | { |
740 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings), usePValue); |
741 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor), usePValue); |
742 | } |
743 | |
744 | @Override |
745 | @@ -158,7 +158,7 @@ |
746 | |
747 | // Inner classes |
748 | |
749 | - private class Execution extends OperatorExecutionBase implements Cursor |
750 | + private class Execution extends ChainedCursor |
751 | { |
752 | // Cursor interface |
753 | |
754 | @@ -240,10 +240,9 @@ |
755 | |
756 | // Execution interface |
757 | |
758 | - Execution(QueryContext context, QueryBindings bindings, Cursor input, boolean usePValue) |
759 | + Execution(QueryContext context, Cursor input, boolean usePValue) |
760 | { |
761 | - super(context, bindings); |
762 | - this.input = input; |
763 | + super(context, input); |
764 | |
765 | nfields = distinctType.nFields(); |
766 | if (!usePValue) { |
767 | @@ -346,7 +345,6 @@ |
768 | |
769 | // Object state |
770 | |
771 | - private final Cursor input; |
772 | private final ShareHolder<Row> currentRow = new ShareHolder<>(); |
773 | private final int nfields; |
774 | // currentValues contains copies of the first nvalid of currentRow's fields, |
775 | |
776 | === modified file 'src/main/java/com/akiban/qp/operator/EmitBoundRow_Nested.java' |
777 | --- src/main/java/com/akiban/qp/operator/EmitBoundRow_Nested.java 2013-07-05 21:35:32 +0000 |
778 | +++ src/main/java/com/akiban/qp/operator/EmitBoundRow_Nested.java 2013-07-10 21:47:26 +0000 |
779 | @@ -92,9 +92,9 @@ |
780 | } |
781 | |
782 | @Override |
783 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
784 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
785 | { |
786 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
787 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
788 | } |
789 | |
790 | @Override |
791 | @@ -163,7 +163,7 @@ |
792 | |
793 | // Inner classes |
794 | |
795 | - private class Execution extends OperatorExecutionBase implements Cursor |
796 | + private class Execution extends ChainedCursor |
797 | { |
798 | // Cursor interface |
799 | |
800 | @@ -236,34 +236,11 @@ |
801 | input.destroy(); |
802 | } |
803 | |
804 | - @Override |
805 | - public boolean isIdle() |
806 | - { |
807 | - return input.isIdle(); |
808 | - } |
809 | - |
810 | - @Override |
811 | - public boolean isActive() |
812 | - { |
813 | - return input.isActive(); |
814 | - } |
815 | - |
816 | - @Override |
817 | - public boolean isDestroyed() |
818 | - { |
819 | - return input.isDestroyed(); |
820 | - } |
821 | - |
822 | // Execution interface |
823 | |
824 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
825 | + Execution(QueryContext context, Cursor input) |
826 | { |
827 | - super(context, bindings); |
828 | - this.input = input; |
829 | + super(context, input); |
830 | } |
831 | - |
832 | - // Object state |
833 | - |
834 | - private final Cursor input; |
835 | } |
836 | } |
837 | |
838 | === modified file 'src/main/java/com/akiban/qp/operator/ExecutionBase.java' |
839 | --- src/main/java/com/akiban/qp/operator/ExecutionBase.java 2013-07-05 21:35:32 +0000 |
840 | +++ src/main/java/com/akiban/qp/operator/ExecutionBase.java 2013-07-10 21:47:26 +0000 |
841 | @@ -36,14 +36,12 @@ |
842 | context.checkQueryCancelation(); |
843 | } |
844 | |
845 | - public ExecutionBase(QueryContext context, QueryBindings bindings) |
846 | + public ExecutionBase(QueryContext context) |
847 | { |
848 | this.context = context; |
849 | - this.bindings = bindings; |
850 | } |
851 | |
852 | protected QueryContext context; |
853 | - protected QueryBindings bindings; |
854 | |
855 | protected static final boolean LOG_EXECUTION = false; |
856 | protected static final boolean TAP_NEXT_ENABLED = false; |
857 | |
858 | === modified file 'src/main/java/com/akiban/qp/operator/Filter_Default.java' |
859 | --- src/main/java/com/akiban/qp/operator/Filter_Default.java 2013-07-05 21:35:32 +0000 |
860 | +++ src/main/java/com/akiban/qp/operator/Filter_Default.java 2013-07-10 21:47:26 +0000 |
861 | @@ -93,9 +93,9 @@ |
862 | } |
863 | |
864 | @Override |
865 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
866 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
867 | { |
868 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
869 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
870 | } |
871 | |
872 | @Override |
873 | @@ -132,7 +132,7 @@ |
874 | |
875 | // Inner classes |
876 | |
877 | - private class Execution extends OperatorExecutionBase implements Cursor |
878 | + private class Execution extends ChainedCursor |
879 | { |
880 | // Cursor interface |
881 | |
882 | @@ -191,12 +191,6 @@ |
883 | } |
884 | |
885 | @Override |
886 | - public void destroy() |
887 | - { |
888 | - input.destroy(); |
889 | - } |
890 | - |
891 | - @Override |
892 | public boolean isIdle() |
893 | { |
894 | return closed; |
895 | @@ -208,23 +202,15 @@ |
896 | return !closed; |
897 | } |
898 | |
899 | - @Override |
900 | - public boolean isDestroyed() |
901 | - { |
902 | - return input.isDestroyed(); |
903 | - } |
904 | - |
905 | // Execution interface |
906 | |
907 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
908 | + Execution(QueryContext context, Cursor input) |
909 | { |
910 | - super(context, bindings); |
911 | - this.input = input; |
912 | + super(context, input); |
913 | } |
914 | |
915 | // Object state |
916 | |
917 | - private final Cursor input; |
918 | private boolean closed = true; |
919 | } |
920 | } |
921 | |
922 | === modified file 'src/main/java/com/akiban/qp/operator/Flatten_HKeyOrdered.java' |
923 | --- src/main/java/com/akiban/qp/operator/Flatten_HKeyOrdered.java 2013-07-05 21:35:32 +0000 |
924 | +++ src/main/java/com/akiban/qp/operator/Flatten_HKeyOrdered.java 2013-07-10 21:47:26 +0000 |
925 | @@ -179,9 +179,9 @@ |
926 | // Operator interface |
927 | |
928 | @Override |
929 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
930 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
931 | { |
932 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
933 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
934 | } |
935 | |
936 | @Override |
937 | @@ -292,7 +292,7 @@ |
938 | |
939 | // Inner classes |
940 | |
941 | - private class Execution extends OperatorExecutionBase implements Cursor |
942 | + private class Execution extends ChainedCursor |
943 | { |
944 | // Cursor interface |
945 | |
946 | @@ -402,18 +402,11 @@ |
947 | return !idle; |
948 | } |
949 | |
950 | - @Override |
951 | - public boolean isDestroyed() |
952 | - { |
953 | - return input.isDestroyed(); |
954 | - } |
955 | - |
956 | // Execution interface |
957 | |
958 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
959 | + Execution(QueryContext context, Cursor input) |
960 | { |
961 | - super(context, bindings); |
962 | - this.input = input; |
963 | + super(context, input); |
964 | this.leftJoinHKey = adapter().newHKey(childType.hKey()); |
965 | } |
966 | |
967 | @@ -503,7 +496,6 @@ |
968 | |
969 | // Object state |
970 | |
971 | - private final Cursor input; |
972 | private final ShareHolder<Row> parent = new ShareHolder<>(); |
973 | private final PendingRows pending = new PendingRows(MAX_PENDING); |
974 | private final HKey leftJoinHKey; |
975 | |
976 | === modified file 'src/main/java/com/akiban/qp/operator/GroupCursor.java' |
977 | --- src/main/java/com/akiban/qp/operator/GroupCursor.java 2013-03-22 20:05:57 +0000 |
978 | +++ src/main/java/com/akiban/qp/operator/GroupCursor.java 2013-07-10 21:47:26 +0000 |
979 | @@ -19,6 +19,6 @@ |
980 | |
981 | import com.akiban.qp.row.HKey; |
982 | |
983 | -public interface GroupCursor extends Cursor { |
984 | +public interface GroupCursor extends RowCursor { |
985 | void rebind(HKey hKey, boolean deep); |
986 | } |
987 | |
988 | === modified file 'src/main/java/com/akiban/qp/operator/GroupScan_Default.java' |
989 | --- src/main/java/com/akiban/qp/operator/GroupScan_Default.java 2013-07-05 21:35:32 +0000 |
990 | +++ src/main/java/com/akiban/qp/operator/GroupScan_Default.java 2013-07-10 21:47:26 +0000 |
991 | @@ -22,6 +22,7 @@ |
992 | import com.akiban.ais.model.UserTable; |
993 | import com.akiban.qp.row.HKey; |
994 | import com.akiban.qp.row.Row; |
995 | +import com.akiban.server.api.dml.ColumnSelector; |
996 | import com.akiban.server.explain.*; |
997 | import com.akiban.util.ArgumentValidation; |
998 | import com.akiban.util.tap.InOutTap; |
999 | @@ -88,9 +89,9 @@ |
1000 | // Operator interface |
1001 | |
1002 | @Override |
1003 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
1004 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
1005 | { |
1006 | - return new Execution(context, bindings, cursorCreator); |
1007 | + return new Execution(context, bindingsCursor, cursorCreator); |
1008 | } |
1009 | |
1010 | // GroupScan_Default interface |
1011 | @@ -126,7 +127,7 @@ |
1012 | |
1013 | // Inner classes |
1014 | |
1015 | - private static class Execution extends OperatorExecutionBase implements Cursor |
1016 | + private static class Execution extends LeafCursor |
1017 | { |
1018 | |
1019 | // Cursor interface |
1020 | @@ -196,22 +197,30 @@ |
1021 | return cursor.isDestroyed(); |
1022 | } |
1023 | |
1024 | + @Override |
1025 | + public QueryBindings nextBindings() { |
1026 | + QueryBindings bindings = super.nextBindings(); |
1027 | + if (cursor instanceof BindingsAwareCursor) |
1028 | + ((BindingsAwareCursor)cursor).rebind(bindings); |
1029 | + return bindings; |
1030 | + } |
1031 | + |
1032 | // Execution interface |
1033 | |
1034 | - Execution(QueryContext context, QueryBindings bindings, GroupCursorCreator cursorCreator) |
1035 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor, GroupCursorCreator cursorCreator) |
1036 | { |
1037 | - super(context, bindings); |
1038 | - this.cursor = cursorCreator.cursor(context, bindings); |
1039 | + super(context, bindingsCursor); |
1040 | + this.cursor = cursorCreator.cursor(context); |
1041 | } |
1042 | |
1043 | // Object state |
1044 | |
1045 | - private final Cursor cursor; |
1046 | + private final RowCursor cursor; |
1047 | } |
1048 | |
1049 | static interface GroupCursorCreator |
1050 | { |
1051 | - Cursor cursor(QueryContext context, QueryBindings bindings); |
1052 | + RowCursor cursor(QueryContext context); |
1053 | |
1054 | Group group(); |
1055 | |
1056 | @@ -254,7 +263,7 @@ |
1057 | // GroupCursorCreator interface |
1058 | |
1059 | @Override |
1060 | - public Cursor cursor(QueryContext context, QueryBindings bindings) |
1061 | + public RowCursor cursor(QueryContext context) |
1062 | { |
1063 | return context.getStore(group().getRoot()).newGroupCursor(group()); |
1064 | } |
1065 | @@ -281,9 +290,9 @@ |
1066 | // GroupCursorCreator interface |
1067 | |
1068 | @Override |
1069 | - public Cursor cursor(QueryContext context, QueryBindings bindings) |
1070 | + public RowCursor cursor(QueryContext context) |
1071 | { |
1072 | - return new HKeyBoundCursor(context, bindings, |
1073 | + return new HKeyBoundCursor(context, |
1074 | context.getStore(group().getRoot()).newGroupCursor(group()), |
1075 | hKeyBindingPosition, |
1076 | deep, |
1077 | @@ -329,7 +338,7 @@ |
1078 | private final UserTable hKeyType; |
1079 | } |
1080 | |
1081 | - private static class HKeyBoundCursor extends ChainedCursor |
1082 | + private static class HKeyBoundCursor implements BindingsAwareCursor |
1083 | { |
1084 | |
1085 | @Override |
1086 | @@ -342,12 +351,12 @@ |
1087 | |
1088 | @Override |
1089 | public Row next() { |
1090 | - // If we've ever seen a row, just defer to super |
1091 | + // If we've ever seen a row, just defer to input |
1092 | if (sawOne) { |
1093 | - return super.next(); |
1094 | + return input.next(); |
1095 | } |
1096 | - Row result = super.next(); |
1097 | - // If we saw a row, mark it as such and defer to super |
1098 | + Row result = input.next(); |
1099 | + // If we saw a row, mark it as such and defer to input |
1100 | if (result != null) { |
1101 | sawOne = true; |
1102 | return result; |
1103 | @@ -366,15 +375,54 @@ |
1104 | return next(); |
1105 | } |
1106 | |
1107 | + @Override |
1108 | + public void jump(Row row, ColumnSelector columnSelector) |
1109 | + { |
1110 | + input.jump(row, columnSelector); |
1111 | + } |
1112 | + |
1113 | + @Override |
1114 | + public void close() { |
1115 | + input.close(); |
1116 | + } |
1117 | + |
1118 | + @Override |
1119 | + public void destroy() |
1120 | + { |
1121 | + input.destroy(); |
1122 | + } |
1123 | + |
1124 | + @Override |
1125 | + public boolean isIdle() |
1126 | + { |
1127 | + return input.isIdle(); |
1128 | + } |
1129 | + |
1130 | + @Override |
1131 | + public boolean isActive() |
1132 | + { |
1133 | + return input.isActive(); |
1134 | + } |
1135 | + |
1136 | + @Override |
1137 | + public boolean isDestroyed() |
1138 | + { |
1139 | + return input.isDestroyed(); |
1140 | + } |
1141 | + |
1142 | + @Override |
1143 | + public void rebind(QueryBindings bindings) { |
1144 | + this.bindings = bindings; |
1145 | + } |
1146 | + |
1147 | HKeyBoundCursor(QueryContext context, |
1148 | - QueryBindings bindings, |
1149 | GroupCursor input, |
1150 | int hKeyBindingPosition, |
1151 | boolean deep, |
1152 | UserTable hKeyType, |
1153 | UserTable shortenUntil) |
1154 | { |
1155 | - super(context, bindings, input); |
1156 | + this.context = context; |
1157 | this.input = input; |
1158 | this.hKeyBindingPosition = hKeyBindingPosition; |
1159 | this.deep = deep; |
1160 | @@ -386,11 +434,13 @@ |
1161 | return bindings.getHKey(hKeyBindingPosition); |
1162 | } |
1163 | |
1164 | + private final QueryContext context; |
1165 | private final GroupCursor input; |
1166 | private final int hKeyBindingPosition; |
1167 | private final boolean deep; |
1168 | private UserTable atTable; |
1169 | private final UserTable stopSearchTable; |
1170 | private boolean sawOne = false; |
1171 | + private QueryBindings bindings; |
1172 | } |
1173 | } |
1174 | |
1175 | === modified file 'src/main/java/com/akiban/qp/operator/HKeyUnion_Ordered.java' |
1176 | --- src/main/java/com/akiban/qp/operator/HKeyUnion_Ordered.java 2013-07-05 21:35:32 +0000 |
1177 | +++ src/main/java/com/akiban/qp/operator/HKeyUnion_Ordered.java 2013-07-10 21:47:26 +0000 |
1178 | @@ -86,9 +86,9 @@ |
1179 | // Operator interface |
1180 | |
1181 | @Override |
1182 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
1183 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
1184 | { |
1185 | - return new Execution(context, bindings); |
1186 | + return new Execution(context, bindingsCursor); |
1187 | } |
1188 | |
1189 | @Override |
1190 | @@ -194,7 +194,7 @@ |
1191 | |
1192 | // Inner classes |
1193 | |
1194 | - private class Execution extends OperatorExecutionBase implements Cursor |
1195 | + private class Execution extends OperatorCursor |
1196 | { |
1197 | // Cursor interface |
1198 | |
1199 | @@ -308,13 +308,39 @@ |
1200 | return leftInput.isDestroyed(); |
1201 | } |
1202 | |
1203 | + @Override |
1204 | + public void openBindings() { |
1205 | + bindingsCursor.openBindings(); |
1206 | + leftInput.openBindings(); |
1207 | + rightInput.openBindings(); |
1208 | + } |
1209 | + |
1210 | + @Override |
1211 | + public QueryBindings nextBindings() { |
1212 | + QueryBindings bindings = bindingsCursor.nextBindings(); |
1213 | + QueryBindings other = leftInput.nextBindings(); |
1214 | + assert (bindings == other); |
1215 | + other = rightInput.nextBindings(); |
1216 | + assert (bindings == other); |
1217 | + return bindings; |
1218 | + } |
1219 | + |
1220 | + @Override |
1221 | + public void closeBindings() { |
1222 | + bindingsCursor.closeBindings(); |
1223 | + leftInput.closeBindings(); |
1224 | + rightInput.closeBindings(); |
1225 | + } |
1226 | + |
1227 | // Execution interface |
1228 | |
1229 | - Execution(QueryContext context, QueryBindings bindings) |
1230 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
1231 | { |
1232 | - super(context, bindings); |
1233 | - leftInput = left.cursor(context, bindings); |
1234 | - rightInput = right.cursor(context, bindings); |
1235 | + super(context); |
1236 | + MultipleQueryBindingsCursor multiple = new MultipleQueryBindingsCursor(bindingsCursor); |
1237 | + this.bindingsCursor = multiple; |
1238 | + this.leftInput = left.cursor(context, multiple.newCursor()); |
1239 | + this.rightInput = right.cursor(context, multiple.newCursor()); |
1240 | hKeyCache = new HKeyCache<>(context.getStore()); |
1241 | } |
1242 | |
1243 | @@ -366,6 +392,7 @@ |
1244 | // Rows from each input stream are bound to the QueryContext. However, QueryContext doesn't use |
1245 | // ShareHolders, so they are needed here. |
1246 | |
1247 | + private final QueryBindingsCursor bindingsCursor; |
1248 | private final Cursor leftInput; |
1249 | private final Cursor rightInput; |
1250 | private final ShareHolder<Row> leftRow = new ShareHolder<>(); |
1251 | |
1252 | === modified file 'src/main/java/com/akiban/qp/operator/IfEmpty_Default.java' |
1253 | --- src/main/java/com/akiban/qp/operator/IfEmpty_Default.java 2013-07-08 18:56:18 +0000 |
1254 | +++ src/main/java/com/akiban/qp/operator/IfEmpty_Default.java 2013-07-10 21:47:26 +0000 |
1255 | @@ -116,9 +116,9 @@ |
1256 | // Operator interface |
1257 | |
1258 | @Override |
1259 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
1260 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
1261 | { |
1262 | - return new Execution(context, bindings); |
1263 | + return new Execution(context, bindingsCursor); |
1264 | } |
1265 | |
1266 | @Override |
1267 | @@ -213,7 +213,7 @@ |
1268 | UNKNOWN, DONE, ECHO_INPUT |
1269 | } |
1270 | |
1271 | - private class Execution extends OperatorExecutionBase implements Cursor |
1272 | + private class Execution extends ChainedCursor |
1273 | { |
1274 | // Cursor interface |
1275 | |
1276 | @@ -310,18 +310,11 @@ |
1277 | return !closed; |
1278 | } |
1279 | |
1280 | - @Override |
1281 | - public boolean isDestroyed() |
1282 | - { |
1283 | - return input.isDestroyed(); |
1284 | - } |
1285 | - |
1286 | // Execution interface |
1287 | |
1288 | - Execution(QueryContext context, QueryBindings bindings) |
1289 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
1290 | { |
1291 | - super(context, bindings); |
1292 | - this.input = inputOperator.cursor(context, bindings); |
1293 | + super(context, inputOperator.cursor(context, bindingsCursor)); |
1294 | if (pExpressions != null) { |
1295 | this.oEvaluations = null; |
1296 | this.pEvaluations = new ArrayList<>(pExpressions.size()); |
1297 | @@ -378,7 +371,6 @@ |
1298 | |
1299 | // Object state |
1300 | |
1301 | - private final Cursor input; |
1302 | private final List<ExpressionEvaluation> oEvaluations; |
1303 | private final List<TEvaluatableExpression> pEvaluations; |
1304 | private final ShareHolder<ValuesHolderRow> emptySubstitute = new ShareHolder<>(); |
1305 | |
1306 | === modified file 'src/main/java/com/akiban/qp/operator/IndexScan_Default.java' |
1307 | --- src/main/java/com/akiban/qp/operator/IndexScan_Default.java 2013-07-05 21:35:32 +0000 |
1308 | +++ src/main/java/com/akiban/qp/operator/IndexScan_Default.java 2013-07-10 21:47:26 +0000 |
1309 | @@ -163,9 +163,9 @@ |
1310 | // Operator interface |
1311 | |
1312 | @Override |
1313 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
1314 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
1315 | { |
1316 | - return new Execution(context, bindings); |
1317 | + return new Execution(context, bindingsCursor); |
1318 | } |
1319 | |
1320 | // IndexScan_Default interface |
1321 | @@ -277,7 +277,7 @@ |
1322 | |
1323 | // Inner classes |
1324 | |
1325 | - private class Execution extends OperatorExecutionBase implements Cursor |
1326 | + private class Execution extends LeafCursor |
1327 | { |
1328 | // Cursor interface |
1329 | |
1330 | @@ -351,17 +351,25 @@ |
1331 | return cursor.isDestroyed(); |
1332 | } |
1333 | |
1334 | + @Override |
1335 | + public QueryBindings nextBindings() { |
1336 | + QueryBindings bindings = super.nextBindings(); |
1337 | + if (cursor instanceof BindingsAwareCursor) |
1338 | + ((BindingsAwareCursor)cursor).rebind(bindings); |
1339 | + return bindings; |
1340 | + } |
1341 | + |
1342 | // Execution interface |
1343 | |
1344 | - Execution(QueryContext context, QueryBindings bindings) |
1345 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
1346 | { |
1347 | - super(context, bindings); |
1348 | + super(context, bindingsCursor); |
1349 | UserTable table = (UserTable)index.rootMostTable(); |
1350 | - this.cursor = adapter(table).newIndexCursor(context, bindings, index, indexKeyRange, ordering, scanSelector, usePValues); |
1351 | + this.cursor = adapter(table).newIndexCursor(context, index, indexKeyRange, ordering, scanSelector, usePValues); |
1352 | } |
1353 | |
1354 | // Object state |
1355 | |
1356 | - private final Cursor cursor; |
1357 | + private final RowCursor cursor; |
1358 | } |
1359 | } |
1360 | |
1361 | === modified file 'src/main/java/com/akiban/qp/operator/Insert_Default.java' |
1362 | --- src/main/java/com/akiban/qp/operator/Insert_Default.java 2013-07-08 15:56:07 +0000 |
1363 | +++ src/main/java/com/akiban/qp/operator/Insert_Default.java 2013-07-10 21:47:26 +0000 |
1364 | @@ -86,7 +86,8 @@ |
1365 | |
1366 | @Override |
1367 | public UpdateResult run(QueryContext context, QueryBindings bindings) { |
1368 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)).run(); |
1369 | + QueryBindingsCursor bindingsCursor = new SingletonQueryBindingsCursor(bindings); |
1370 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)).run(); |
1371 | } |
1372 | |
1373 | @Override |
1374 | @@ -139,7 +140,7 @@ |
1375 | INSERT_TAP.in(); |
1376 | } |
1377 | try { |
1378 | - input.open(); |
1379 | + input.openTopLevel(); |
1380 | Row row; |
1381 | while ((row = input.next()) != null) { |
1382 | // LOG.warn("About to insert {}: {}", row.rowType().userTable(), row); |
1383 | @@ -154,7 +155,7 @@ |
1384 | } |
1385 | } finally { |
1386 | if (input != null) { |
1387 | - input.close(); |
1388 | + input.destroy(); |
1389 | } |
1390 | if (TAP_NEXT_ENABLED) { |
1391 | INSERT_TAP.out(); |
1392 | @@ -163,9 +164,9 @@ |
1393 | return new StandardUpdateResult(seen, modified); |
1394 | } |
1395 | |
1396 | - protected Execution(QueryContext queryContext, QueryBindings queryBindings, Cursor input) |
1397 | + protected Execution(QueryContext queryContext, Cursor input) |
1398 | { |
1399 | - super(queryContext, queryBindings); |
1400 | + super(queryContext); |
1401 | this.input = input; |
1402 | } |
1403 | |
1404 | |
1405 | === modified file 'src/main/java/com/akiban/qp/operator/Insert_Returning.java' |
1406 | --- src/main/java/com/akiban/qp/operator/Insert_Returning.java 2013-07-08 15:56:07 +0000 |
1407 | +++ src/main/java/com/akiban/qp/operator/Insert_Returning.java 2013-07-10 21:47:26 +0000 |
1408 | @@ -82,8 +82,8 @@ |
1409 | public class Insert_Returning extends Operator { |
1410 | |
1411 | @Override |
1412 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) { |
1413 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
1414 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) { |
1415 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
1416 | } |
1417 | |
1418 | @Override |
1419 | @@ -125,7 +125,7 @@ |
1420 | private final boolean usePValues; |
1421 | |
1422 | // Inner classes |
1423 | - private class Execution extends OperatorExecutionBase implements Cursor |
1424 | + private class Execution extends ChainedCursor |
1425 | { |
1426 | |
1427 | // Cursor interface |
1428 | @@ -187,42 +187,31 @@ |
1429 | @Override |
1430 | public void destroy() |
1431 | { |
1432 | - if (input != null) { |
1433 | - close(); |
1434 | - input.destroy(); |
1435 | - input = null; |
1436 | - } |
1437 | + close(); |
1438 | + input.destroy(); |
1439 | } |
1440 | |
1441 | @Override |
1442 | public boolean isIdle() |
1443 | { |
1444 | - return input != null && idle; |
1445 | + return !input.isDestroyed() && idle; |
1446 | } |
1447 | |
1448 | @Override |
1449 | public boolean isActive() |
1450 | { |
1451 | - return input != null && !idle; |
1452 | - } |
1453 | - |
1454 | - @Override |
1455 | - public boolean isDestroyed() |
1456 | - { |
1457 | - return input == null; |
1458 | - } |
1459 | - |
1460 | + return !input.isDestroyed() && !idle; |
1461 | + } |
1462 | + |
1463 | // Execution interface |
1464 | |
1465 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
1466 | + Execution(QueryContext context, Cursor input) |
1467 | { |
1468 | - super(context, bindings); |
1469 | - this.input = input; |
1470 | + super(context, input); |
1471 | } |
1472 | |
1473 | // Object state |
1474 | - |
1475 | - private Cursor input; // input = null indicates destroyed. |
1476 | + |
1477 | private boolean idle = true; |
1478 | } |
1479 | } |
1480 | |
1481 | === modified file 'src/main/java/com/akiban/qp/operator/Intersect_Ordered.java' |
1482 | --- src/main/java/com/akiban/qp/operator/Intersect_Ordered.java 2013-07-05 21:35:32 +0000 |
1483 | +++ src/main/java/com/akiban/qp/operator/Intersect_Ordered.java 2013-07-10 21:47:26 +0000 |
1484 | @@ -118,9 +118,9 @@ |
1485 | // Operator interface |
1486 | |
1487 | @Override |
1488 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
1489 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
1490 | { |
1491 | - return new Execution(context, bindings); |
1492 | + return new Execution(context, bindingsCursor); |
1493 | } |
1494 | |
1495 | @Override |
1496 | @@ -260,7 +260,7 @@ |
1497 | |
1498 | // Inner classes |
1499 | |
1500 | - private class Execution extends OperatorExecutionBase implements Cursor |
1501 | + private class Execution extends OperatorCursor |
1502 | { |
1503 | // Cursor interface |
1504 | |
1505 | @@ -407,13 +407,39 @@ |
1506 | return leftInput.isDestroyed(); |
1507 | } |
1508 | |
1509 | + @Override |
1510 | + public void openBindings() { |
1511 | + bindingsCursor.openBindings(); |
1512 | + leftInput.openBindings(); |
1513 | + rightInput.openBindings(); |
1514 | + } |
1515 | + |
1516 | + @Override |
1517 | + public QueryBindings nextBindings() { |
1518 | + QueryBindings bindings = bindingsCursor.nextBindings(); |
1519 | + QueryBindings other = leftInput.nextBindings(); |
1520 | + assert (bindings == other); |
1521 | + other = rightInput.nextBindings(); |
1522 | + assert (bindings == other); |
1523 | + return bindings; |
1524 | + } |
1525 | + |
1526 | + @Override |
1527 | + public void closeBindings() { |
1528 | + bindingsCursor.closeBindings(); |
1529 | + leftInput.closeBindings(); |
1530 | + rightInput.closeBindings(); |
1531 | + } |
1532 | + |
1533 | // Execution interface |
1534 | |
1535 | - Execution(QueryContext context, QueryBindings bindings) |
1536 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
1537 | { |
1538 | - super(context, bindings); |
1539 | - leftInput = left.cursor(context, bindings); |
1540 | - rightInput = right.cursor(context, bindings); |
1541 | + super(context); |
1542 | + MultipleQueryBindingsCursor multiple = new MultipleQueryBindingsCursor(bindingsCursor); |
1543 | + this.bindingsCursor = multiple; |
1544 | + this.leftInput = left.cursor(context, multiple.newCursor()); |
1545 | + this.rightInput = right.cursor(context, multiple.newCursor()); |
1546 | } |
1547 | |
1548 | // For use by this class |
1549 | @@ -592,6 +618,7 @@ |
1550 | // ShareHolders, so they are needed here. |
1551 | |
1552 | private boolean closed = true; |
1553 | + private final QueryBindingsCursor bindingsCursor; |
1554 | private final Cursor leftInput; |
1555 | private final Cursor rightInput; |
1556 | private final ShareHolder<Row> leftRow = new ShareHolder<>(); |
1557 | |
1558 | === added file 'src/main/java/com/akiban/qp/operator/LeafCursor.java' |
1559 | --- src/main/java/com/akiban/qp/operator/LeafCursor.java 1970-01-01 00:00:00 +0000 |
1560 | +++ src/main/java/com/akiban/qp/operator/LeafCursor.java 2013-07-10 21:47:26 +0000 |
1561 | @@ -0,0 +1,45 @@ |
1562 | +/** |
1563 | + * Copyright (C) 2009-2013 Akiban Technologies, Inc. |
1564 | + * |
1565 | + * This program is free software: you can redistribute it and/or modify |
1566 | + * it under the terms of the GNU Affero General Public License as published by |
1567 | + * the Free Software Foundation, either version 3 of the License, or |
1568 | + * (at your option) any later version. |
1569 | + * |
1570 | + * This program is distributed in the hope that it will be useful, |
1571 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1572 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1573 | + * GNU Affero General Public License for more details. |
1574 | + * |
1575 | + * You should have received a copy of the GNU Affero General Public License |
1576 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1577 | + */ |
1578 | + |
1579 | +package com.akiban.qp.operator; |
1580 | + |
1581 | +public class LeafCursor extends OperatorCursor |
1582 | +{ |
1583 | + protected final QueryBindingsCursor bindingsCursor; |
1584 | + protected QueryBindings bindings; |
1585 | + |
1586 | + protected LeafCursor(QueryContext context, QueryBindingsCursor bindingsCursor) { |
1587 | + super(context); |
1588 | + this.bindingsCursor = bindingsCursor; |
1589 | + } |
1590 | + |
1591 | + @Override |
1592 | + public void openBindings() { |
1593 | + bindingsCursor.openBindings(); |
1594 | + } |
1595 | + |
1596 | + @Override |
1597 | + public QueryBindings nextBindings() { |
1598 | + bindings = bindingsCursor.nextBindings(); |
1599 | + return bindings; |
1600 | + } |
1601 | + |
1602 | + @Override |
1603 | + public void closeBindings() { |
1604 | + bindingsCursor.closeBindings(); |
1605 | + } |
1606 | +} |
1607 | |
1608 | === modified file 'src/main/java/com/akiban/qp/operator/Limit_Default.java' |
1609 | --- src/main/java/com/akiban/qp/operator/Limit_Default.java 2013-07-05 21:35:32 +0000 |
1610 | +++ src/main/java/com/akiban/qp/operator/Limit_Default.java 2013-07-10 21:47:26 +0000 |
1611 | @@ -87,8 +87,8 @@ |
1612 | // Operator interface |
1613 | |
1614 | @Override |
1615 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) { |
1616 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
1617 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) { |
1618 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
1619 | } |
1620 | |
1621 | // Plannable interface |
1622 | @@ -326,8 +326,8 @@ |
1623 | } |
1624 | |
1625 | // Execution interface |
1626 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) { |
1627 | - super(context, bindings, input); |
1628 | + Execution(QueryContext context, Cursor input) { |
1629 | + super(context, input); |
1630 | } |
1631 | |
1632 | // object state |
1633 | |
1634 | === modified file 'src/main/java/com/akiban/qp/operator/Map_NestedLoops.java' |
1635 | --- src/main/java/com/akiban/qp/operator/Map_NestedLoops.java 2013-07-05 21:35:32 +0000 |
1636 | +++ src/main/java/com/akiban/qp/operator/Map_NestedLoops.java 2013-07-10 21:47:26 +0000 |
1637 | @@ -85,9 +85,9 @@ |
1638 | // Operator interface |
1639 | |
1640 | @Override |
1641 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
1642 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
1643 | { |
1644 | - return new Execution(context, bindings); |
1645 | + return new Execution(context, bindingsCursor); |
1646 | } |
1647 | |
1648 | @Override |
1649 | @@ -150,7 +150,7 @@ |
1650 | |
1651 | // Inner classes |
1652 | |
1653 | - private class Execution extends OperatorExecutionBase implements Cursor |
1654 | + private class Execution extends OperatorCursor |
1655 | { |
1656 | // Cursor interface |
1657 | |
1658 | @@ -242,13 +242,31 @@ |
1659 | return outerInput.isDestroyed(); |
1660 | } |
1661 | |
1662 | + @Override |
1663 | + public void openBindings() { |
1664 | + outerInput.openBindings(); |
1665 | + } |
1666 | + |
1667 | + @Override |
1668 | + public QueryBindings nextBindings() { |
1669 | + outerBindings = outerInput.nextBindings(); |
1670 | + return outerBindings; |
1671 | + } |
1672 | + |
1673 | + @Override |
1674 | + public void closeBindings() { |
1675 | + outerInput.closeBindings(); |
1676 | + } |
1677 | + |
1678 | // Execution interface |
1679 | |
1680 | - Execution(QueryContext context, QueryBindings bindings) |
1681 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
1682 | { |
1683 | - super(context, bindings); |
1684 | - this.outerInput = outerInputOperator.cursor(context, bindings); |
1685 | - this.innerInput = innerInputOperator.cursor(context, bindings); |
1686 | + super(context); |
1687 | + this.outerInput = outerInputOperator.cursor(context, bindingsCursor); |
1688 | + // For now, the inside sees whatever bindings the outside currently has. |
1689 | + this.innerBindingsCursor = new SingletonQueryBindingsCursor(null); |
1690 | + this.innerInput = innerInputOperator.cursor(context, innerBindingsCursor); |
1691 | } |
1692 | |
1693 | // For use by this class |
1694 | @@ -276,8 +294,9 @@ |
1695 | private void startNewInnerLoop(Row row) |
1696 | { |
1697 | innerInput.close(); |
1698 | - bindings.setRow(inputBindingPosition, row); |
1699 | - innerInput.open(); |
1700 | + outerBindings.setRow(inputBindingPosition, row); |
1701 | + innerBindingsCursor.reset(outerBindings); |
1702 | + innerInput.openTopLevel(); |
1703 | } |
1704 | |
1705 | // Object state |
1706 | @@ -286,5 +305,7 @@ |
1707 | private final Cursor innerInput; |
1708 | private final ShareHolder<Row> outerRow = new ShareHolder<>(); |
1709 | private boolean closed = true; |
1710 | + private QueryBindings outerBindings; |
1711 | + private final SingletonQueryBindingsCursor innerBindingsCursor; |
1712 | } |
1713 | } |
1714 | |
1715 | === added file 'src/main/java/com/akiban/qp/operator/MultipleQueryBindingsCursor.java' |
1716 | --- src/main/java/com/akiban/qp/operator/MultipleQueryBindingsCursor.java 1970-01-01 00:00:00 +0000 |
1717 | +++ src/main/java/com/akiban/qp/operator/MultipleQueryBindingsCursor.java 2013-07-10 21:47:26 +0000 |
1718 | @@ -0,0 +1,121 @@ |
1719 | +/** |
1720 | + * Copyright (C) 2009-2013 Akiban Technologies, Inc. |
1721 | + * |
1722 | + * This program is free software: you can redistribute it and/or modify |
1723 | + * it under the terms of the GNU Affero General Public License as published by |
1724 | + * the Free Software Foundation, either version 3 of the License, or |
1725 | + * (at your option) any later version. |
1726 | + * |
1727 | + * This program is distributed in the hope that it will be useful, |
1728 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1729 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1730 | + * GNU Affero General Public License for more details. |
1731 | + * |
1732 | + * You should have received a copy of the GNU Affero General Public License |
1733 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1734 | + */ |
1735 | + |
1736 | +package com.akiban.qp.operator; |
1737 | + |
1738 | +import java.util.ArrayList; |
1739 | +import java.util.List; |
1740 | + |
1741 | +/** |
1742 | + * A generator of {@link QueryBindingsCursor}s from a common source. |
1743 | + */ |
1744 | +public class MultipleQueryBindingsCursor implements QueryBindingsCursor |
1745 | +{ |
1746 | + private final QueryBindingsCursor input; |
1747 | + private final List<QueryBindings> buffer = new ArrayList<QueryBindings>(); |
1748 | + private final List<SubCursor> cursors = new ArrayList<SubCursor>(); |
1749 | + private boolean exhausted; |
1750 | + private int offset; |
1751 | + |
1752 | + public MultipleQueryBindingsCursor(QueryBindingsCursor input) { |
1753 | + this.input = input; |
1754 | + newCursor(); |
1755 | + } |
1756 | + |
1757 | + @Override |
1758 | + public void openBindings() { |
1759 | + input.openBindings(); |
1760 | + exhausted = false; |
1761 | + buffer.clear(); |
1762 | + offset = 0; |
1763 | + cursors.get(0).openBindings(); |
1764 | + for (int i = 1; i < cursors.size(); i++) { |
1765 | + cursors.get(i).closeBindings(); |
1766 | + } |
1767 | + } |
1768 | + |
1769 | + @Override |
1770 | + public QueryBindings nextBindings() { |
1771 | + return cursors.get(0).nextBindings(); |
1772 | + } |
1773 | + |
1774 | + @Override |
1775 | + public void closeBindings() { |
1776 | + cursors.get(0).closeBindings(); |
1777 | + } |
1778 | + |
1779 | + public QueryBindingsCursor newCursor() { |
1780 | + assert (offset == 0); |
1781 | + SubCursor cursor = new SubCursor(); |
1782 | + cursors.add(cursor); |
1783 | + return cursor; |
1784 | + } |
1785 | + |
1786 | + protected void shrink() { |
1787 | + int minIndex = cursors.get(0).index; |
1788 | + for (int i = 1; i < cursors.size(); i++) { |
1789 | + SubCursor cursor = cursors.get(i); |
1790 | + if (!cursor.open) continue; |
1791 | + if (minIndex > cursor.index) { |
1792 | + minIndex = cursor.index; |
1793 | + } |
1794 | + } |
1795 | + while (offset < minIndex) { |
1796 | + buffer.remove(0); |
1797 | + offset++; |
1798 | + } |
1799 | + } |
1800 | + |
1801 | + class SubCursor implements QueryBindingsCursor { |
1802 | + boolean open; |
1803 | + int index; |
1804 | + |
1805 | + @Override |
1806 | + public void openBindings() { |
1807 | + assert (offset == 0); |
1808 | + open = true; |
1809 | + index = 0; |
1810 | + } |
1811 | + |
1812 | + @Override |
1813 | + public QueryBindings nextBindings() { |
1814 | + assert (open && (index >= offset)); |
1815 | + while (index - offset >= buffer.size()) { |
1816 | + if (exhausted) { |
1817 | + return null; |
1818 | + } |
1819 | + else { |
1820 | + QueryBindings bindings = input.nextBindings(); |
1821 | + if (bindings == null) { |
1822 | + exhausted = true; |
1823 | + return null; |
1824 | + } |
1825 | + buffer.add(bindings); |
1826 | + } |
1827 | + } |
1828 | + QueryBindings bindings = buffer.get(index - offset); |
1829 | + index++; |
1830 | + shrink(); |
1831 | + return bindings; |
1832 | + } |
1833 | + |
1834 | + @Override |
1835 | + public void closeBindings() { |
1836 | + open = false; |
1837 | + } |
1838 | + } |
1839 | +} |
1840 | |
1841 | === modified file 'src/main/java/com/akiban/qp/operator/Operator.java' |
1842 | --- src/main/java/com/akiban/qp/operator/Operator.java 2013-07-05 21:35:32 +0000 |
1843 | +++ src/main/java/com/akiban/qp/operator/Operator.java 2013-07-10 21:47:26 +0000 |
1844 | @@ -69,7 +69,7 @@ |
1845 | return Collections.emptyList(); |
1846 | } |
1847 | |
1848 | - protected abstract Cursor cursor(QueryContext context, QueryBindings bindings); |
1849 | + protected abstract Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor); |
1850 | |
1851 | @Override |
1852 | public String describePlan() |
1853 | |
1854 | === added file 'src/main/java/com/akiban/qp/operator/OperatorCursor.java' |
1855 | --- src/main/java/com/akiban/qp/operator/OperatorCursor.java 1970-01-01 00:00:00 +0000 |
1856 | +++ src/main/java/com/akiban/qp/operator/OperatorCursor.java 2013-07-10 21:47:26 +0000 |
1857 | @@ -0,0 +1,42 @@ |
1858 | +/** |
1859 | + * Copyright (C) 2009-2013 Akiban Technologies, Inc. |
1860 | + * |
1861 | + * This program is free software: you can redistribute it and/or modify |
1862 | + * it under the terms of the GNU Affero General Public License as published by |
1863 | + * the Free Software Foundation, either version 3 of the License, or |
1864 | + * (at your option) any later version. |
1865 | + * |
1866 | + * This program is distributed in the hope that it will be useful, |
1867 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1868 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1869 | + * GNU Affero General Public License for more details. |
1870 | + * |
1871 | + * You should have received a copy of the GNU Affero General Public License |
1872 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1873 | + */ |
1874 | + |
1875 | +package com.akiban.qp.operator; |
1876 | + |
1877 | +public abstract class OperatorCursor extends OperatorExecutionBase implements Cursor |
1878 | +{ |
1879 | + protected OperatorCursor(QueryContext context) { |
1880 | + super(context); |
1881 | + } |
1882 | + |
1883 | + @Override |
1884 | + public QueryBindings openTopLevel() { |
1885 | + openBindings(); |
1886 | + QueryBindings bindings = nextBindings(); |
1887 | + assert (bindings != null); |
1888 | + open(); |
1889 | + return bindings; |
1890 | + } |
1891 | + |
1892 | + @Override |
1893 | + public void closeTopLevel() { |
1894 | + close(); |
1895 | + QueryBindings bindings = nextBindings(); |
1896 | + assert (bindings == null); |
1897 | + closeBindings(); |
1898 | + } |
1899 | +} |
1900 | |
1901 | === modified file 'src/main/java/com/akiban/qp/operator/OperatorExecutionBase.java' |
1902 | --- src/main/java/com/akiban/qp/operator/OperatorExecutionBase.java 2013-07-05 21:35:32 +0000 |
1903 | +++ src/main/java/com/akiban/qp/operator/OperatorExecutionBase.java 2013-07-10 21:47:26 +0000 |
1904 | @@ -81,8 +81,8 @@ |
1905 | } |
1906 | } |
1907 | |
1908 | - protected OperatorExecutionBase(QueryContext context, QueryBindings bindings) |
1909 | + protected OperatorExecutionBase(QueryContext context) |
1910 | { |
1911 | - super(context, bindings); |
1912 | + super(context); |
1913 | } |
1914 | } |
1915 | |
1916 | === modified file 'src/main/java/com/akiban/qp/operator/Product_NestedLoops.java' |
1917 | --- src/main/java/com/akiban/qp/operator/Product_NestedLoops.java 2013-07-05 21:35:32 +0000 |
1918 | +++ src/main/java/com/akiban/qp/operator/Product_NestedLoops.java 2013-07-10 21:47:26 +0000 |
1919 | @@ -123,9 +123,9 @@ |
1920 | // Operator interface |
1921 | |
1922 | @Override |
1923 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
1924 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
1925 | { |
1926 | - return new Execution(context, bindings); |
1927 | + return new Execution(context, bindingsCursor); |
1928 | } |
1929 | |
1930 | @Override |
1931 | @@ -198,7 +198,7 @@ |
1932 | |
1933 | // Inner classes |
1934 | |
1935 | - private class Execution extends OperatorExecutionBase implements Cursor |
1936 | + private class Execution extends OperatorCursor |
1937 | { |
1938 | // Cursor interface |
1939 | |
1940 | @@ -301,13 +301,29 @@ |
1941 | return outerInput.isDestroyed(); |
1942 | } |
1943 | |
1944 | + @Override |
1945 | + public void openBindings() { |
1946 | + outerInput.openBindings(); |
1947 | + } |
1948 | + |
1949 | + @Override |
1950 | + public QueryBindings nextBindings() { |
1951 | + outerBindings = outerInput.nextBindings(); |
1952 | + return outerBindings; |
1953 | + } |
1954 | + |
1955 | + @Override |
1956 | + public void closeBindings() { |
1957 | + outerInput.closeBindings(); |
1958 | + } |
1959 | + |
1960 | // Execution interface |
1961 | |
1962 | - Execution(QueryContext context, QueryBindings bindings) |
1963 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
1964 | { |
1965 | - super(context, bindings); |
1966 | - this.outerInput = outerInputOperator.cursor(context, bindings); |
1967 | - this.innerRows = new InnerRows(innerInputOperator.cursor(context, bindings)); |
1968 | + super(context); |
1969 | + this.outerInput = outerInputOperator.cursor(context, bindingsCursor); |
1970 | + this.innerRows = new InnerRows(context, bindingsCursor); |
1971 | } |
1972 | |
1973 | // For use by this class |
1974 | @@ -345,14 +361,16 @@ |
1975 | private final ShareHolder<Row> outerBranchRow = new ShareHolder<>(); |
1976 | private final InnerRows innerRows; |
1977 | private boolean closed = true; |
1978 | + private QueryBindings outerBindings; |
1979 | |
1980 | // Inner classes |
1981 | |
1982 | private class InnerRows |
1983 | { |
1984 | - public InnerRows(Cursor innerInput) |
1985 | + public InnerRows(QueryContext context, QueryBindingsCursor bindingsCursor) |
1986 | { |
1987 | - this.innerInput = innerInput; |
1988 | + this.innerBindingsCursor = new SingletonQueryBindingsCursor(null); |
1989 | + this.innerInput = innerInputOperator.cursor(context, innerBindingsCursor); |
1990 | } |
1991 | |
1992 | public Row next() |
1993 | @@ -368,8 +386,9 @@ |
1994 | public void newBranchRow(Row branchRow) |
1995 | { |
1996 | close(); |
1997 | - bindings.setRow(inputBindingPosition, branchRow); |
1998 | - innerInput.open(); |
1999 | + outerBindings.setRow(inputBindingPosition, branchRow); |
2000 | + innerBindingsCursor.reset(outerBindings); |
2001 | + innerInput.openTopLevel(); |
2002 | rows.clear(); |
2003 | Row row; |
2004 | while ((row = innerInput.next()) != null) { |
2005 | @@ -392,6 +411,7 @@ |
2006 | private final Cursor innerInput; |
2007 | private final RowList rows = new RowList(); |
2008 | private final RowList.Scan scan = rows.scan(); |
2009 | + private final SingletonQueryBindingsCursor innerBindingsCursor; |
2010 | } |
2011 | } |
2012 | } |
2013 | |
2014 | === modified file 'src/main/java/com/akiban/qp/operator/Project_Default.java' |
2015 | --- src/main/java/com/akiban/qp/operator/Project_Default.java 2013-07-05 21:35:32 +0000 |
2016 | +++ src/main/java/com/akiban/qp/operator/Project_Default.java 2013-07-10 21:47:26 +0000 |
2017 | @@ -88,9 +88,9 @@ |
2018 | // Operator interface |
2019 | |
2020 | @Override |
2021 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
2022 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
2023 | { |
2024 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
2025 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
2026 | } |
2027 | |
2028 | @Override |
2029 | @@ -204,7 +204,7 @@ |
2030 | |
2031 | // Inner classes |
2032 | |
2033 | - private class Execution extends OperatorExecutionBase implements Cursor |
2034 | + private class Execution extends ChainedCursor |
2035 | { |
2036 | // Cursor interface |
2037 | |
2038 | @@ -268,47 +268,42 @@ |
2039 | @Override |
2040 | public void destroy() |
2041 | { |
2042 | - if (input != null) { |
2043 | - close(); |
2044 | - input.destroy(); |
2045 | - input = null; |
2046 | - pEvalExpr = null; |
2047 | - } |
2048 | + close(); |
2049 | + input.destroy(); |
2050 | + pEvalExpr = null; |
2051 | } |
2052 | |
2053 | @Override |
2054 | public boolean isIdle() |
2055 | { |
2056 | - return input != null && idle; |
2057 | + return !input.isDestroyed() && idle; |
2058 | } |
2059 | |
2060 | @Override |
2061 | public boolean isActive() |
2062 | { |
2063 | - return input != null && !idle; |
2064 | + return !input.isDestroyed() && !idle; |
2065 | } |
2066 | |
2067 | @Override |
2068 | public boolean isDestroyed() |
2069 | { |
2070 | - return input == null; |
2071 | + return input.isDestroyed(); |
2072 | } |
2073 | |
2074 | // Execution interface |
2075 | |
2076 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
2077 | + Execution(QueryContext context, Cursor input) |
2078 | { |
2079 | - super(context, bindings); |
2080 | - this.input = input; |
2081 | + super(context, input); |
2082 | // one list of evaluatables per execution |
2083 | if (pExpressions != null) |
2084 | - pEvalExpr = ProjectedRow.createTEvaluatableExpressions(pExpressions); |
2085 | + pEvalExpr = ProjectedRow.createTEvaluatableExpressions(pExpressions); |
2086 | else |
2087 | pEvalExpr = null; |
2088 | } |
2089 | |
2090 | // Object state |
2091 | - private Cursor input; // input = null indicates destroyed. |
2092 | private boolean idle = true; |
2093 | private List<TEvaluatableExpression> pEvalExpr = null; |
2094 | } |
2095 | |
2096 | === added file 'src/main/java/com/akiban/qp/operator/QueryBindingsCursor.java' |
2097 | --- src/main/java/com/akiban/qp/operator/QueryBindingsCursor.java 1970-01-01 00:00:00 +0000 |
2098 | +++ src/main/java/com/akiban/qp/operator/QueryBindingsCursor.java 2013-07-10 21:47:26 +0000 |
2099 | @@ -0,0 +1,33 @@ |
2100 | +/** |
2101 | + * Copyright (C) 2009-2013 Akiban Technologies, Inc. |
2102 | + * |
2103 | + * This program is free software: you can redistribute it and/or modify |
2104 | + * it under the terms of the GNU Affero General Public License as published by |
2105 | + * the Free Software Foundation, either version 3 of the License, or |
2106 | + * (at your option) any later version. |
2107 | + * |
2108 | + * This program is distributed in the hope that it will be useful, |
2109 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2110 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2111 | + * GNU Affero General Public License for more details. |
2112 | + * |
2113 | + * You should have received a copy of the GNU Affero General Public License |
2114 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2115 | + */ |
2116 | + |
2117 | +package com.akiban.qp.operator; |
2118 | + |
2119 | +/** |
2120 | + * A stream of {@link QueryBindings}. |
2121 | + */ |
2122 | +public interface QueryBindingsCursor |
2123 | +{ |
2124 | + /** Open stream of bindings. */ |
2125 | + public void openBindings(); |
2126 | + |
2127 | + /** Get (and make current for <code>open</code>) the next set of bindings. */ |
2128 | + public QueryBindings nextBindings(); |
2129 | + |
2130 | + /** Close stream of bindings. */ |
2131 | + public void closeBindings(); |
2132 | +} |
2133 | |
2134 | === renamed file 'src/main/java/com/akiban/qp/operator/Cursor.java' => 'src/main/java/com/akiban/qp/operator/RowCursor.java' |
2135 | --- src/main/java/com/akiban/qp/operator/Cursor.java 2013-03-22 20:05:57 +0000 |
2136 | +++ src/main/java/com/akiban/qp/operator/RowCursor.java 2013-07-10 21:47:26 +0000 |
2137 | @@ -19,6 +19,6 @@ |
2138 | |
2139 | import com.akiban.qp.row.Row; |
2140 | |
2141 | -public interface Cursor extends RowOrientedCursorBase<Row> |
2142 | +public interface RowCursor extends RowOrientedCursorBase<Row> |
2143 | { |
2144 | } |
2145 | |
2146 | === modified file 'src/main/java/com/akiban/qp/operator/RowOrientedCursorBase.java' |
2147 | --- src/main/java/com/akiban/qp/operator/RowOrientedCursorBase.java 2013-03-22 20:05:57 +0000 |
2148 | +++ src/main/java/com/akiban/qp/operator/RowOrientedCursorBase.java 2013-07-10 21:47:26 +0000 |
2149 | @@ -17,60 +17,12 @@ |
2150 | |
2151 | package com.akiban.qp.operator; |
2152 | |
2153 | -/* |
2154 | - |
2155 | -A Cursor is used to scan a sequence of rows resulting from the execution of an operator. |
2156 | -The same cursor may be used for multiple executions of the operator, possibly with different bindings. |
2157 | - |
2158 | -A Cursor is always in one of three states: |
2159 | - |
2160 | -- IDLE: The cursor is not currently involved in a scan. The cursor is in this state when one |
2161 | - of the following is true: |
2162 | - - open() has never been called. |
2163 | - - The most recent method invocation was to next(), which returned null. |
2164 | - - The most recent method invocation was to close(). |
2165 | - |
2166 | -- ACTIVE: The cursor is currently involved in a scan. The cursor is in this state when one |
2167 | - of the following is true: |
2168 | - - The most recent method invocation was to open(). |
2169 | - - The most recent method invocation was to next(), which returned a non-null value. |
2170 | - |
2171 | -- DESTROYED: The cursor has been destroyed. Invocations of open, next, or close on such a cursor |
2172 | - will raise an exception. The only way to get into this state is to call destroy(). |
2173 | - |
2174 | -The Cursor lifecycle is as follows: |
2175 | - |
2176 | - next/jump == null next/jump != null |
2177 | - +-+ +-+ |
2178 | - | | | | |
2179 | - | V open | V destroy |
2180 | - --> IDLE ----------> ACTIVE ----------> DESTROYED |
2181 | - | <---------- ^ |
2182 | - | next/jump = null, | |
2183 | - | close | |
2184 | - | | |
2185 | - +--------------------------------------+ |
2186 | - destroy |
2187 | - */ |
2188 | - |
2189 | - |
2190 | import com.akiban.qp.expression.BoundExpressions; |
2191 | import com.akiban.server.api.dml.ColumnSelector; |
2192 | |
2193 | public interface RowOrientedCursorBase<T extends BoundExpressions> extends CursorBase<T> |
2194 | { |
2195 | /** |
2196 | - * Starts a cursor scan. |
2197 | - */ |
2198 | - void open(); |
2199 | - |
2200 | - /** |
2201 | - * Advances to and returns the next row. |
2202 | - * @return The next object, or <code>null</code> if at the end. |
2203 | - */ |
2204 | - T next(); |
2205 | - |
2206 | - /** |
2207 | * Advances to the first row, r, such that r.compareTo(row) >= 0. (Call next to get the row.) |
2208 | * |
2209 | * @param row |
2210 | @@ -78,32 +30,4 @@ |
2211 | * @return |
2212 | */ |
2213 | void jump(T row, ColumnSelector columnSelector); |
2214 | - |
2215 | - /** |
2216 | - * Terminates the current cursor scan. |
2217 | - */ |
2218 | - void close(); |
2219 | - |
2220 | - /** |
2221 | - * Destroys the cursor. No further operations on the cursor are permitted. |
2222 | - */ |
2223 | - void destroy(); |
2224 | - |
2225 | - /** |
2226 | - * Indicates whether the cursor is in the IDLE state. |
2227 | - * @return true iff the cursor is IDLE. |
2228 | - */ |
2229 | - boolean isIdle(); |
2230 | - |
2231 | - /** |
2232 | - * Indicates whether the cursor is in the ACTIVE state. |
2233 | - * @return true iff the cursor is ACTIVE. |
2234 | - */ |
2235 | - boolean isActive(); |
2236 | - |
2237 | - /** |
2238 | - * Indicates whether the cursor is in the DESTROYED state. |
2239 | - * @return true iff the cursor is DESTROYED. |
2240 | - */ |
2241 | - boolean isDestroyed(); |
2242 | } |
2243 | |
2244 | === modified file 'src/main/java/com/akiban/qp/operator/Select_BloomFilter.java' |
2245 | --- src/main/java/com/akiban/qp/operator/Select_BloomFilter.java 2013-07-05 21:35:32 +0000 |
2246 | +++ src/main/java/com/akiban/qp/operator/Select_BloomFilter.java 2013-07-10 21:47:26 +0000 |
2247 | @@ -101,12 +101,12 @@ |
2248 | } |
2249 | |
2250 | @Override |
2251 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
2252 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
2253 | { |
2254 | if (tFields == null) |
2255 | - return new Execution<>(context, bindings, fields, oldExpressionsAdapater); |
2256 | + return new Execution<>(context, bindingsCursor, fields, oldExpressionsAdapater); |
2257 | else |
2258 | - return new Execution<>(context, bindings, tFields, newExpressionsAdapter); |
2259 | + return new Execution<>(context, bindingsCursor, tFields, newExpressionsAdapter); |
2260 | } |
2261 | |
2262 | @Override |
2263 | @@ -233,7 +233,7 @@ |
2264 | } |
2265 | }; |
2266 | |
2267 | - private class Execution<E> extends OperatorExecutionBase implements Cursor |
2268 | + private class Execution<E> extends OperatorCursor |
2269 | { |
2270 | // Cursor interface |
2271 | |
2272 | @@ -322,14 +322,31 @@ |
2273 | return destroyed; |
2274 | } |
2275 | |
2276 | + @Override |
2277 | + public void openBindings() { |
2278 | + inputCursor.openBindings(); |
2279 | + } |
2280 | + |
2281 | + @Override |
2282 | + public QueryBindings nextBindings() { |
2283 | + bindings = inputCursor.nextBindings(); |
2284 | + return bindings; |
2285 | + } |
2286 | + |
2287 | + @Override |
2288 | + public void closeBindings() { |
2289 | + inputCursor.closeBindings(); |
2290 | + } |
2291 | + |
2292 | // Execution interface |
2293 | |
2294 | - <EXPR> Execution(QueryContext context, QueryBindings bindings, |
2295 | + <EXPR> Execution(QueryContext context, QueryBindingsCursor bindingsCursor, |
2296 | List<? extends EXPR> expressions, ExpressionAdapter<EXPR,E> adapter) |
2297 | { |
2298 | - super(context, bindings); |
2299 | - this.inputCursor = input.cursor(context, bindings); |
2300 | - this.onPositiveCursor = onPositive.cursor(context, bindings); |
2301 | + super(context); |
2302 | + this.inputCursor = input.cursor(context, bindingsCursor); |
2303 | + this.onPositiveBindingsCursor = new SingletonQueryBindingsCursor(null); |
2304 | + this.onPositiveCursor = onPositive.cursor(context, onPositiveBindingsCursor); |
2305 | this.adapter = adapter; |
2306 | for (EXPR field : expressions) { |
2307 | E eval = adapter.evaluate(field, context); |
2308 | @@ -360,11 +377,12 @@ |
2309 | TAP_CHECK.in(); |
2310 | try { |
2311 | bindings.setRow(bindingPosition, row); |
2312 | - onPositiveCursor.open(); |
2313 | + onPositiveBindingsCursor.reset(bindings); |
2314 | + onPositiveCursor.openTopLevel(); |
2315 | try { |
2316 | return onPositiveCursor.next() != null; |
2317 | } finally { |
2318 | - onPositiveCursor.close(); |
2319 | + onPositiveCursor.closeTopLevel(); |
2320 | bindings.setRow(bindingPosition, null); |
2321 | } |
2322 | } finally { |
2323 | @@ -376,6 +394,8 @@ |
2324 | |
2325 | private final Cursor inputCursor; |
2326 | private final Cursor onPositiveCursor; |
2327 | + private final SingletonQueryBindingsCursor onPositiveBindingsCursor; |
2328 | + private QueryBindings bindings; |
2329 | private BloomFilter filter; |
2330 | private final List<E> fieldEvals = new ArrayList<>(); |
2331 | private final ExpressionAdapter<?, E> adapter; |
2332 | |
2333 | === modified file 'src/main/java/com/akiban/qp/operator/Select_HKeyOrdered.java' |
2334 | --- src/main/java/com/akiban/qp/operator/Select_HKeyOrdered.java 2013-07-08 18:56:18 +0000 |
2335 | +++ src/main/java/com/akiban/qp/operator/Select_HKeyOrdered.java 2013-07-10 21:47:26 +0000 |
2336 | @@ -102,9 +102,9 @@ |
2337 | } |
2338 | |
2339 | @Override |
2340 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
2341 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
2342 | { |
2343 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
2344 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
2345 | } |
2346 | |
2347 | @Override |
2348 | @@ -177,7 +177,7 @@ |
2349 | |
2350 | // Inner classes |
2351 | |
2352 | - private class Execution extends OperatorExecutionBase implements Cursor |
2353 | + private class Execution extends ChainedCursor |
2354 | { |
2355 | // Cursor interface |
2356 | |
2357 | @@ -298,18 +298,11 @@ |
2358 | return !input.isDestroyed() && !idle; |
2359 | } |
2360 | |
2361 | - @Override |
2362 | - public boolean isDestroyed() |
2363 | - { |
2364 | - return input.isDestroyed(); |
2365 | - } |
2366 | - |
2367 | // Execution interface |
2368 | |
2369 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
2370 | + Execution(QueryContext context, Cursor input) |
2371 | { |
2372 | - super(context, bindings); |
2373 | - this.input = input; |
2374 | + super(context, input); |
2375 | if (predicate == null) { |
2376 | this.evaluation = null; |
2377 | this.pEvaluation = pPredicate.build(); |
2378 | @@ -322,7 +315,6 @@ |
2379 | |
2380 | // Object state |
2381 | |
2382 | - private final Cursor input; |
2383 | private final ShareHolder<Row> selectedRow = new ShareHolder<>(); // The last input row with type = predicateRowType. |
2384 | private final ExpressionEvaluation evaluation; |
2385 | private final TEvaluatableExpression pEvaluation; |
2386 | |
2387 | === added file 'src/main/java/com/akiban/qp/operator/SingletonQueryBindingsCursor.java' |
2388 | --- src/main/java/com/akiban/qp/operator/SingletonQueryBindingsCursor.java 1970-01-01 00:00:00 +0000 |
2389 | +++ src/main/java/com/akiban/qp/operator/SingletonQueryBindingsCursor.java 2013-07-10 21:47:26 +0000 |
2390 | @@ -0,0 +1,61 @@ |
2391 | +/** |
2392 | + * Copyright (C) 2009-2013 Akiban Technologies, Inc. |
2393 | + * |
2394 | + * This program is free software: you can redistribute it and/or modify |
2395 | + * it under the terms of the GNU Affero General Public License as published by |
2396 | + * the Free Software Foundation, either version 3 of the License, or |
2397 | + * (at your option) any later version. |
2398 | + * |
2399 | + * This program is distributed in the hope that it will be useful, |
2400 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2401 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2402 | + * GNU Affero General Public License for more details. |
2403 | + * |
2404 | + * You should have received a copy of the GNU Affero General Public License |
2405 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2406 | + */ |
2407 | + |
2408 | +package com.akiban.qp.operator; |
2409 | + |
2410 | +/** |
2411 | + * A single {@link QueryBindings} stream. |
2412 | + */ |
2413 | +public class SingletonQueryBindingsCursor implements QueryBindingsCursor |
2414 | +{ |
2415 | + enum State { CLOSED, PENDING, EXHAUSTED }; |
2416 | + private QueryBindings bindings; |
2417 | + private State state; |
2418 | + |
2419 | + public SingletonQueryBindingsCursor(QueryBindings bindings) { |
2420 | + reset(bindings); |
2421 | + } |
2422 | + |
2423 | + @Override |
2424 | + public void openBindings() { |
2425 | + state = State.PENDING; |
2426 | + } |
2427 | + |
2428 | + @Override |
2429 | + public QueryBindings nextBindings() { |
2430 | + switch (state) { |
2431 | + case CLOSED: |
2432 | + throw new IllegalStateException("Bindings cursor not open"); |
2433 | + case PENDING: |
2434 | + state = State.EXHAUSTED; |
2435 | + return bindings; |
2436 | + case EXHAUSTED: |
2437 | + default: |
2438 | + return null; |
2439 | + } |
2440 | + } |
2441 | + |
2442 | + @Override |
2443 | + public void closeBindings() { |
2444 | + state = State.CLOSED; |
2445 | + } |
2446 | + |
2447 | + public void reset(QueryBindings bindings) { |
2448 | + this.bindings = bindings; |
2449 | + this.state = State.CLOSED; |
2450 | + } |
2451 | +} |
2452 | |
2453 | === modified file 'src/main/java/com/akiban/qp/operator/Sort_General.java' |
2454 | --- src/main/java/com/akiban/qp/operator/Sort_General.java 2013-07-05 21:35:32 +0000 |
2455 | +++ src/main/java/com/akiban/qp/operator/Sort_General.java 2013-07-10 21:47:26 +0000 |
2456 | @@ -92,9 +92,9 @@ |
2457 | } |
2458 | |
2459 | @Override |
2460 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
2461 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
2462 | { |
2463 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
2464 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
2465 | } |
2466 | |
2467 | @Override |
2468 | @@ -153,7 +153,7 @@ |
2469 | |
2470 | // Inner classes |
2471 | |
2472 | - private class Execution extends OperatorExecutionBase implements Cursor |
2473 | + private class Execution extends ChainedCursor |
2474 | { |
2475 | // Cursor interface |
2476 | |
2477 | @@ -243,16 +243,14 @@ |
2478 | |
2479 | // Execution interface |
2480 | |
2481 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
2482 | + Execution(QueryContext context, Cursor input) |
2483 | { |
2484 | - super(context, bindings); |
2485 | - this.input = input; |
2486 | + super(context, input); |
2487 | } |
2488 | |
2489 | // Object state |
2490 | |
2491 | - private final Cursor input; |
2492 | - private Cursor output; |
2493 | + private RowCursor output; |
2494 | private boolean destroyed = false; |
2495 | } |
2496 | } |
2497 | |
2498 | === modified file 'src/main/java/com/akiban/qp/operator/Sort_InsertionLimited.java' |
2499 | --- src/main/java/com/akiban/qp/operator/Sort_InsertionLimited.java 2013-07-08 18:56:18 +0000 |
2500 | +++ src/main/java/com/akiban/qp/operator/Sort_InsertionLimited.java 2013-07-10 21:47:26 +0000 |
2501 | @@ -104,9 +104,9 @@ |
2502 | } |
2503 | |
2504 | @Override |
2505 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
2506 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
2507 | { |
2508 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
2509 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
2510 | } |
2511 | |
2512 | @Override |
2513 | @@ -173,7 +173,7 @@ |
2514 | |
2515 | private enum State { CLOSED, FILLING, EMPTYING, DESTROYED } |
2516 | |
2517 | - private class Execution extends OperatorExecutionBase implements Cursor |
2518 | + private class Execution extends ChainedCursor |
2519 | { |
2520 | // Cursor interface |
2521 | |
2522 | @@ -326,7 +326,7 @@ |
2523 | { |
2524 | return state == State.DESTROYED; |
2525 | } |
2526 | - |
2527 | + |
2528 | // private methods |
2529 | |
2530 | private boolean usingPValues() { |
2531 | @@ -335,10 +335,9 @@ |
2532 | |
2533 | // Execution interface |
2534 | |
2535 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
2536 | + Execution(QueryContext context, Cursor input) |
2537 | { |
2538 | - super(context, bindings); |
2539 | - this.input = input; |
2540 | + super(context, input); |
2541 | int nsort = ordering.sortColumns(); |
2542 | tEvaluations = new ArrayList<>(nsort); |
2543 | for (int i = 0; i < nsort; ++i) { |
2544 | @@ -349,7 +348,6 @@ |
2545 | |
2546 | // Object state |
2547 | |
2548 | - private final Cursor input; |
2549 | private final List<TEvaluatableExpression> tEvaluations; |
2550 | private State state = State.CLOSED; |
2551 | private SortedSet<Holder> sorted; |
2552 | |
2553 | === modified file 'src/main/java/com/akiban/qp/operator/SorterToCursorAdapter.java' |
2554 | --- src/main/java/com/akiban/qp/operator/SorterToCursorAdapter.java 2013-07-05 21:35:32 +0000 |
2555 | +++ src/main/java/com/akiban/qp/operator/SorterToCursorAdapter.java 2013-07-10 21:47:26 +0000 |
2556 | @@ -27,9 +27,9 @@ |
2557 | * Cursors are reusable but Sorters are not. |
2558 | * This class creates a new Sorter each time a new cursor scan is started. |
2559 | */ |
2560 | -class SorterToCursorAdapter implements Cursor |
2561 | +class SorterToCursorAdapter implements RowCursor |
2562 | { |
2563 | - // Cursor interface |
2564 | + // RowCursor interface |
2565 | |
2566 | @Override |
2567 | public void open() |
2568 | @@ -99,7 +99,7 @@ |
2569 | public SorterToCursorAdapter(StoreAdapter adapter, |
2570 | QueryContext context, |
2571 | QueryBindings bindings, |
2572 | - Cursor input, |
2573 | + RowCursor input, |
2574 | RowType rowType, |
2575 | API.Ordering ordering, |
2576 | API.SortOption sortOption, |
2577 | @@ -118,12 +118,12 @@ |
2578 | private final StoreAdapter adapter; |
2579 | private final QueryContext context; |
2580 | private final QueryBindings bindings; |
2581 | - private final Cursor input; |
2582 | + private final RowCursor input; |
2583 | private final RowType rowType; |
2584 | private final API.Ordering ordering; |
2585 | private final API.SortOption sortOption; |
2586 | private final InOutTap loadTap; |
2587 | private Sorter sorter; |
2588 | - private Cursor cursor; |
2589 | + private RowCursor cursor; |
2590 | private boolean destroyed = false; |
2591 | } |
2592 | |
2593 | === modified file 'src/main/java/com/akiban/qp/operator/StoreAdapter.java' |
2594 | --- src/main/java/com/akiban/qp/operator/StoreAdapter.java 2013-07-08 15:56:07 +0000 |
2595 | +++ src/main/java/com/akiban/qp/operator/StoreAdapter.java 2013-07-10 21:47:26 +0000 |
2596 | @@ -52,13 +52,12 @@ |
2597 | { |
2598 | public abstract GroupCursor newGroupCursor(Group group); |
2599 | |
2600 | - public abstract Cursor newIndexCursor(QueryContext context, |
2601 | - QueryBindings bindings, |
2602 | - Index index, |
2603 | - IndexKeyRange keyRange, |
2604 | - API.Ordering ordering, |
2605 | - IndexScanSelector scanSelector, |
2606 | - boolean usePValues); |
2607 | + public abstract RowCursor newIndexCursor(QueryContext context, |
2608 | + Index index, |
2609 | + IndexKeyRange keyRange, |
2610 | + API.Ordering ordering, |
2611 | + IndexScanSelector scanSelector, |
2612 | + boolean usePValues); |
2613 | |
2614 | public abstract <HKEY extends com.akiban.qp.row.HKey> HKEY newHKey(HKey hKeyMetadata); |
2615 | |
2616 | @@ -75,7 +74,7 @@ |
2617 | |
2618 | public abstract Sorter createSorter(QueryContext context, |
2619 | QueryBindings bindings, |
2620 | - Cursor input, |
2621 | + RowCursor input, |
2622 | RowType rowType, |
2623 | API.Ordering ordering, |
2624 | API.SortOption sortOption, |
2625 | |
2626 | === modified file 'src/main/java/com/akiban/qp/operator/UnionAll_Default.java' |
2627 | --- src/main/java/com/akiban/qp/operator/UnionAll_Default.java 2013-07-05 21:35:32 +0000 |
2628 | +++ src/main/java/com/akiban/qp/operator/UnionAll_Default.java 2013-07-10 21:47:26 +0000 |
2629 | @@ -101,8 +101,8 @@ |
2630 | } |
2631 | |
2632 | @Override |
2633 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) { |
2634 | - return new Execution(context, bindings); |
2635 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) { |
2636 | + return new Execution(context, bindingsCursor); |
2637 | } |
2638 | |
2639 | UnionAll_Default(Operator input1, RowType input1Type, Operator input2, RowType input2Type, boolean usePValues) { |
2640 | @@ -205,7 +205,7 @@ |
2641 | return new CompoundExplainer(Type.UNION, att); |
2642 | } |
2643 | |
2644 | - private class Execution extends OperatorExecutionBase implements Cursor { |
2645 | + private class Execution extends OperatorCursor { |
2646 | |
2647 | @Override |
2648 | public void open() { |
2649 | @@ -213,6 +213,8 @@ |
2650 | try { |
2651 | CursorLifecycle.checkIdle(this); |
2652 | idle = false; |
2653 | + // TODO: Have a mode where all the cursors get opened |
2654 | + // so that they can start in parallel. |
2655 | } finally { |
2656 | TAP_OPEN.out(); |
2657 | } |
2658 | @@ -299,10 +301,41 @@ |
2659 | return destroyed; |
2660 | } |
2661 | |
2662 | - private Execution(QueryContext context, QueryBindings bindings) |
2663 | + @Override |
2664 | + public void openBindings() { |
2665 | + bindingsCursor.openBindings(); |
2666 | + for (int i = 0; i < cursors.length; i++) { |
2667 | + cursors[i].openBindings(); |
2668 | + } |
2669 | + } |
2670 | + |
2671 | + @Override |
2672 | + public QueryBindings nextBindings() { |
2673 | + QueryBindings bindings = bindingsCursor.nextBindings(); |
2674 | + for (int i = 0; i < cursors.length; i++) { |
2675 | + QueryBindings other = cursors[i].nextBindings(); |
2676 | + assert (bindings == other); |
2677 | + } |
2678 | + return bindings; |
2679 | + } |
2680 | + |
2681 | + @Override |
2682 | + public void closeBindings() { |
2683 | + bindingsCursor.closeBindings(); |
2684 | + for (int i = 0; i < cursors.length; i++) { |
2685 | + cursors[i].closeBindings(); |
2686 | + } |
2687 | + } |
2688 | + |
2689 | + private Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
2690 | { |
2691 | - super(context, bindings); |
2692 | + super(context); |
2693 | + MultipleQueryBindingsCursor multiple = new MultipleQueryBindingsCursor(bindingsCursor); |
2694 | + this.bindingsCursor = multiple; |
2695 | cursors = new Cursor[inputs.size()]; |
2696 | + for (int i = 0; i < cursors.length; i++) { |
2697 | + cursors[i] = inputs.get(i).cursor(context, multiple.newCursor()); |
2698 | + } |
2699 | } |
2700 | |
2701 | /** |
2702 | @@ -313,7 +346,7 @@ |
2703 | */ |
2704 | private Row nextCursorFirstRow() { |
2705 | while (++inputOperatorsIndex < inputs.size()) { |
2706 | - Cursor nextCursor = cursor(inputOperatorsIndex); |
2707 | + Cursor nextCursor = cursors[inputOperatorsIndex]; |
2708 | nextCursor.open(); |
2709 | Row nextRow = nextCursor.next(); |
2710 | if (nextRow == null) { |
2711 | @@ -350,15 +383,8 @@ |
2712 | return row; |
2713 | } |
2714 | |
2715 | - private Cursor cursor(int i) |
2716 | - { |
2717 | - if (cursors[i] == null) { |
2718 | - cursors[i] = inputs.get(i).cursor(context, bindings); |
2719 | - } |
2720 | - return cursors[i]; |
2721 | - } |
2722 | - |
2723 | private final ShareHolder<MasqueradingRow> rowHolder = new ShareHolder<>(); |
2724 | + private final QueryBindingsCursor bindingsCursor; |
2725 | private int inputOperatorsIndex = -1; // right before the first operator |
2726 | private Cursor[] cursors; |
2727 | private Cursor currentCursor; |
2728 | |
2729 | === modified file 'src/main/java/com/akiban/qp/operator/Union_Ordered.java' |
2730 | --- src/main/java/com/akiban/qp/operator/Union_Ordered.java 2013-07-05 21:35:32 +0000 |
2731 | +++ src/main/java/com/akiban/qp/operator/Union_Ordered.java 2013-07-10 21:47:26 +0000 |
2732 | @@ -95,9 +95,9 @@ |
2733 | // Operator interface |
2734 | |
2735 | @Override |
2736 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
2737 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
2738 | { |
2739 | - return new Execution(context, bindings); |
2740 | + return new Execution(context, bindingsCursor); |
2741 | } |
2742 | |
2743 | @Override |
2744 | @@ -194,7 +194,7 @@ |
2745 | |
2746 | // Inner classes |
2747 | |
2748 | - private class Execution extends OperatorExecutionBase implements Cursor |
2749 | + private class Execution extends OperatorCursor |
2750 | { |
2751 | // Cursor interface |
2752 | |
2753 | @@ -309,13 +309,39 @@ |
2754 | return leftInput.isDestroyed(); |
2755 | } |
2756 | |
2757 | + @Override |
2758 | + public void openBindings() { |
2759 | + bindingsCursor.openBindings(); |
2760 | + leftInput.openBindings(); |
2761 | + rightInput.openBindings(); |
2762 | + } |
2763 | + |
2764 | + @Override |
2765 | + public QueryBindings nextBindings() { |
2766 | + QueryBindings bindings = bindingsCursor.nextBindings(); |
2767 | + QueryBindings other = leftInput.nextBindings(); |
2768 | + assert (bindings == other); |
2769 | + other = rightInput.nextBindings(); |
2770 | + assert (bindings == other); |
2771 | + return bindings; |
2772 | + } |
2773 | + |
2774 | + @Override |
2775 | + public void closeBindings() { |
2776 | + bindingsCursor.closeBindings(); |
2777 | + leftInput.closeBindings(); |
2778 | + rightInput.closeBindings(); |
2779 | + } |
2780 | + |
2781 | // Execution interface |
2782 | |
2783 | - Execution(QueryContext context, QueryBindings bindings) |
2784 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
2785 | { |
2786 | - super(context, bindings); |
2787 | - leftInput = left.cursor(context, bindings); |
2788 | - rightInput = right.cursor(context, bindings); |
2789 | + super(context); |
2790 | + MultipleQueryBindingsCursor multiple = new MultipleQueryBindingsCursor(bindingsCursor); |
2791 | + this.bindingsCursor = multiple; |
2792 | + this.leftInput = left.cursor(context, multiple.newCursor()); |
2793 | + this.rightInput = right.cursor(context, multiple.newCursor()); |
2794 | } |
2795 | |
2796 | // For use by this class |
2797 | @@ -474,6 +500,7 @@ |
2798 | // ShareHolders, so they are needed here. |
2799 | |
2800 | private boolean closed = true; |
2801 | + private final QueryBindingsCursor bindingsCursor; |
2802 | private final Cursor leftInput; |
2803 | private final Cursor rightInput; |
2804 | private final ShareHolder<Row> leftRow = new ShareHolder<>(); |
2805 | |
2806 | === modified file 'src/main/java/com/akiban/qp/operator/Update_Default.java' |
2807 | --- src/main/java/com/akiban/qp/operator/Update_Default.java 2013-07-08 18:56:18 +0000 |
2808 | +++ src/main/java/com/akiban/qp/operator/Update_Default.java 2013-07-10 21:47:26 +0000 |
2809 | @@ -110,7 +110,8 @@ |
2810 | |
2811 | @Override |
2812 | public UpdateResult run(QueryContext context, QueryBindings bindings) { |
2813 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)).run(); |
2814 | + QueryBindingsCursor bindingsCursor = new SingletonQueryBindingsCursor(bindings); |
2815 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)).run(); |
2816 | } |
2817 | |
2818 | // Plannable interface |
2819 | @@ -167,7 +168,7 @@ |
2820 | UPDATE_TAP.in(); |
2821 | } |
2822 | try { |
2823 | - input.open(); |
2824 | + QueryBindings bindings = input.openTopLevel(); |
2825 | Row oldRow; |
2826 | while ((oldRow = input.next()) != null) { |
2827 | checkQueryCancelation(); |
2828 | @@ -184,7 +185,7 @@ |
2829 | } |
2830 | } finally { |
2831 | if (input != null) { |
2832 | - input.close(); |
2833 | + input.destroy(); |
2834 | } |
2835 | if (TAP_NEXT_ENABLED) { |
2836 | UPDATE_TAP.out(); |
2837 | @@ -193,9 +194,9 @@ |
2838 | return new StandardUpdateResult(seen, modified); |
2839 | } |
2840 | |
2841 | - public Execution(QueryContext queryContext, QueryBindings bindings, Cursor input) |
2842 | + public Execution(QueryContext queryContext, Cursor input) |
2843 | { |
2844 | - super(queryContext, bindings); |
2845 | + super(queryContext); |
2846 | this.input = input; |
2847 | } |
2848 | |
2849 | |
2850 | === modified file 'src/main/java/com/akiban/qp/operator/Update_Returning.java' |
2851 | --- src/main/java/com/akiban/qp/operator/Update_Returning.java 2013-07-08 18:56:18 +0000 |
2852 | +++ src/main/java/com/akiban/qp/operator/Update_Returning.java 2013-07-10 21:47:26 +0000 |
2853 | @@ -94,8 +94,8 @@ |
2854 | } |
2855 | |
2856 | @Override |
2857 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) { |
2858 | - return new Execution(context, bindings, inputOperator.cursor(context, bindings)); |
2859 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) { |
2860 | + return new Execution(context, inputOperator.cursor(context, bindingsCursor)); |
2861 | } |
2862 | |
2863 | public Update_Returning (Operator inputOperator, UpdateFunction updateFunction, boolean usePvals) { |
2864 | @@ -120,7 +120,7 @@ |
2865 | private static final Logger LOG = LoggerFactory.getLogger(Update_Returning.class); |
2866 | |
2867 | // Inner classes |
2868 | - private class Execution extends OperatorExecutionBase implements Cursor |
2869 | + private class Execution extends ChainedCursor |
2870 | { |
2871 | |
2872 | // Cursor interface |
2873 | @@ -181,42 +181,31 @@ |
2874 | @Override |
2875 | public void destroy() |
2876 | { |
2877 | - if (input != null) { |
2878 | - close(); |
2879 | - input.destroy(); |
2880 | - input = null; |
2881 | - } |
2882 | + close(); |
2883 | + input.destroy(); |
2884 | } |
2885 | |
2886 | @Override |
2887 | public boolean isIdle() |
2888 | { |
2889 | - return input != null && idle; |
2890 | + return !input.isDestroyed() && idle; |
2891 | } |
2892 | |
2893 | @Override |
2894 | public boolean isActive() |
2895 | { |
2896 | - return input != null && !idle; |
2897 | - } |
2898 | - |
2899 | - @Override |
2900 | - public boolean isDestroyed() |
2901 | - { |
2902 | - return input == null; |
2903 | - } |
2904 | - |
2905 | + return !input.isDestroyed() && !idle; |
2906 | + } |
2907 | + |
2908 | // Execution interface |
2909 | |
2910 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
2911 | + Execution(QueryContext context, Cursor input) |
2912 | { |
2913 | - super(context, bindings); |
2914 | - this.input = input; |
2915 | + super(context, input); |
2916 | } |
2917 | |
2918 | // Object state |
2919 | - |
2920 | - private Cursor input; // input = null indicates destroyed. |
2921 | + |
2922 | private boolean idle = true; |
2923 | } |
2924 | |
2925 | |
2926 | === modified file 'src/main/java/com/akiban/qp/operator/Using_BloomFilter.java' |
2927 | --- src/main/java/com/akiban/qp/operator/Using_BloomFilter.java 2013-07-05 21:35:32 +0000 |
2928 | +++ src/main/java/com/akiban/qp/operator/Using_BloomFilter.java 2013-07-10 21:47:26 +0000 |
2929 | @@ -95,9 +95,9 @@ |
2930 | } |
2931 | |
2932 | @Override |
2933 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
2934 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
2935 | { |
2936 | - return new Execution(context, bindings, streamInput.cursor(context, bindings)); |
2937 | + return new Execution(context, streamInput.cursor(context, bindingsCursor)); |
2938 | } |
2939 | |
2940 | @Override |
2941 | @@ -174,7 +174,7 @@ |
2942 | |
2943 | // Inner classes |
2944 | |
2945 | - private class Execution extends OperatorExecutionBase implements Cursor |
2946 | + private class Execution extends ChainedCursor |
2947 | { |
2948 | // Cursor interface |
2949 | |
2950 | @@ -211,12 +211,6 @@ |
2951 | } |
2952 | |
2953 | @Override |
2954 | - public void close() |
2955 | - { |
2956 | - input.close(); |
2957 | - } |
2958 | - |
2959 | - @Override |
2960 | public void destroy() |
2961 | { |
2962 | close(); |
2963 | @@ -224,30 +218,11 @@ |
2964 | bindings.setBloomFilter(filterBindingPosition, null); |
2965 | } |
2966 | |
2967 | - @Override |
2968 | - public boolean isIdle() |
2969 | - { |
2970 | - return input.isIdle(); |
2971 | - } |
2972 | - |
2973 | - @Override |
2974 | - public boolean isActive() |
2975 | - { |
2976 | - return input.isActive(); |
2977 | - } |
2978 | - |
2979 | - @Override |
2980 | - public boolean isDestroyed() |
2981 | - { |
2982 | - return input.isDestroyed(); |
2983 | - } |
2984 | - |
2985 | // Execution interface |
2986 | |
2987 | - Execution(QueryContext context, QueryBindings bindings, Cursor input) |
2988 | + Execution(QueryContext context, Cursor input) |
2989 | { |
2990 | - super(context, bindings); |
2991 | - this.input = input; |
2992 | + super(context, input); |
2993 | } |
2994 | |
2995 | // For use by this class |
2996 | @@ -268,8 +243,9 @@ |
2997 | { |
2998 | int fields = filterRowType.nFields(); |
2999 | int rows = 0; |
3000 | - Cursor loadCursor = filterInput.cursor(context, bindings); |
3001 | - loadCursor.open(); |
3002 | + QueryBindingsCursor bindingsCursor = new SingletonQueryBindingsCursor(bindings); |
3003 | + Cursor loadCursor = filterInput.cursor(context, bindingsCursor); |
3004 | + loadCursor.openTopLevel(); |
3005 | Row row; |
3006 | while ((row = loadCursor.next()) != null) { |
3007 | int h = 0; |
3008 | @@ -290,8 +266,5 @@ |
3009 | return rows; |
3010 | } |
3011 | |
3012 | - // Object state |
3013 | - |
3014 | - private final Cursor input; |
3015 | } |
3016 | } |
3017 | |
3018 | === modified file 'src/main/java/com/akiban/qp/operator/ValuesScan_Default.java' |
3019 | --- src/main/java/com/akiban/qp/operator/ValuesScan_Default.java 2013-07-08 18:56:18 +0000 |
3020 | +++ src/main/java/com/akiban/qp/operator/ValuesScan_Default.java 2013-07-10 21:47:26 +0000 |
3021 | @@ -77,8 +77,8 @@ |
3022 | } |
3023 | |
3024 | @Override |
3025 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) { |
3026 | - return new Execution(context, bindings, rows); |
3027 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) { |
3028 | + return new Execution(context, bindingsCursor, rows); |
3029 | } |
3030 | |
3031 | @Override |
3032 | @@ -117,14 +117,14 @@ |
3033 | return new CompoundExplainer(Type.SCAN_OPERATOR, att); |
3034 | } |
3035 | |
3036 | - private static class Execution extends OperatorExecutionBase implements Cursor |
3037 | + private static class Execution extends LeafCursor |
3038 | { |
3039 | private final Collection<? extends BindableRow> rows; |
3040 | private Iterator<? extends BindableRow> iter; |
3041 | private boolean destroyed = false; |
3042 | |
3043 | - public Execution (QueryContext context, QueryBindings bindings, Collection<? extends BindableRow> rows) { |
3044 | - super(context, bindings); |
3045 | + public Execution (QueryContext context, QueryBindingsCursor bindingsCursor, Collection<? extends BindableRow> rows) { |
3046 | + super(context, bindingsCursor); |
3047 | this.rows = rows; |
3048 | } |
3049 | |
3050 | |
3051 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/OperatorBasedRowCollector.java' |
3052 | --- src/main/java/com/akiban/qp/persistitadapter/OperatorBasedRowCollector.java 2013-07-08 16:06:08 +0000 |
3053 | +++ src/main/java/com/akiban/qp/persistitadapter/OperatorBasedRowCollector.java 2013-07-10 21:47:26 +0000 |
3054 | @@ -70,7 +70,7 @@ |
3055 | QueryContext context = new SimpleQueryContext(adapter); |
3056 | QueryBindings bindings = context.createBindings(); |
3057 | cursor = cursor(operator, context, bindings); |
3058 | - cursor.open(); |
3059 | + cursor.openTopLevel(); |
3060 | // closed was initialized to true, because hasMore is checked before open. (This is due to scan being |
3061 | // spread across possibly multiple requests.) Now set closed to false for the actual scanning of rows. |
3062 | closed = false; |
3063 | |
3064 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/PersistitAdapter.java' |
3065 | --- src/main/java/com/akiban/qp/persistitadapter/PersistitAdapter.java 2013-07-10 17:01:24 +0000 |
3066 | +++ src/main/java/com/akiban/qp/persistitadapter/PersistitAdapter.java 2013-07-10 21:47:26 +0000 |
3067 | @@ -71,11 +71,10 @@ |
3068 | } |
3069 | |
3070 | @Override |
3071 | - public Cursor newIndexCursor(QueryContext context, QueryBindings bindings, Index index, IndexKeyRange keyRange, API.Ordering ordering, |
3072 | + public RowCursor newIndexCursor(QueryContext context, Index index, IndexKeyRange keyRange, API.Ordering ordering, |
3073 | IndexScanSelector selector, boolean usePValues) |
3074 | { |
3075 | return new PersistitIndexCursor(context, |
3076 | - bindings, |
3077 | schema.indexRowType(index), |
3078 | keyRange, |
3079 | ordering, |
3080 | @@ -86,7 +85,7 @@ |
3081 | @Override |
3082 | public Sorter createSorter(QueryContext context, |
3083 | QueryBindings bindings, |
3084 | - Cursor input, |
3085 | + RowCursor input, |
3086 | RowType rowType, |
3087 | API.Ordering ordering, |
3088 | API.SortOption sortOption, |
3089 | |
3090 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/PersistitIndexCursor.java' |
3091 | --- src/main/java/com/akiban/qp/persistitadapter/PersistitIndexCursor.java 2013-07-05 21:35:32 +0000 |
3092 | +++ src/main/java/com/akiban/qp/persistitadapter/PersistitIndexCursor.java 2013-07-10 21:47:26 +0000 |
3093 | @@ -28,7 +28,7 @@ |
3094 | import com.akiban.server.api.dml.ColumnSelector; |
3095 | import com.persistit.exception.PersistitException; |
3096 | |
3097 | -class PersistitIndexCursor implements Cursor |
3098 | +class PersistitIndexCursor implements BindingsAwareCursor |
3099 | { |
3100 | // Cursor interface |
3101 | |
3102 | @@ -103,10 +103,15 @@ |
3103 | return destroyed; |
3104 | } |
3105 | |
3106 | + @Override |
3107 | + public void rebind(QueryBindings bindings) |
3108 | + { |
3109 | + indexCursor.rebind(bindings); |
3110 | + } |
3111 | + |
3112 | // For use by this package |
3113 | |
3114 | PersistitIndexCursor(QueryContext context, |
3115 | - QueryBindings bindings, |
3116 | IndexRowType indexRowType, |
3117 | IndexKeyRange keyRange, |
3118 | API.Ordering ordering, |
3119 | @@ -116,14 +121,13 @@ |
3120 | this.keyRange = keyRange; |
3121 | this.ordering = ordering; |
3122 | this.context = context; |
3123 | - this.bindings = bindings; |
3124 | this.indexRowType = indexRowType; |
3125 | this.isTableIndex = indexRowType.index().isTableIndex(); |
3126 | this.usePValues = usePValues; |
3127 | this.selector = selector; |
3128 | this.idle = true; |
3129 | this.rowState = context.getStore().createIterationHelper(indexRowType); |
3130 | - this.indexCursor = IndexCursor.create(context, bindings, keyRange, ordering, rowState, usePValues); |
3131 | + this.indexCursor = IndexCursor.create(context, keyRange, ordering, rowState, usePValues); |
3132 | } |
3133 | |
3134 | // For use by this class |
3135 | @@ -131,7 +135,6 @@ |
3136 | // Object state |
3137 | |
3138 | private final QueryContext context; |
3139 | - private final QueryBindings bindings; |
3140 | private final IndexRowType indexRowType; |
3141 | private final IndexKeyRange keyRange; |
3142 | private final API.Ordering ordering; |
3143 | |
3144 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/Sorter.java' |
3145 | --- src/main/java/com/akiban/qp/persistitadapter/Sorter.java 2013-06-06 14:38:02 +0000 |
3146 | +++ src/main/java/com/akiban/qp/persistitadapter/Sorter.java 2013-07-10 21:47:26 +0000 |
3147 | @@ -17,10 +17,10 @@ |
3148 | |
3149 | package com.akiban.qp.persistitadapter; |
3150 | |
3151 | -import com.akiban.qp.operator.Cursor; |
3152 | +import com.akiban.qp.operator.RowCursor; |
3153 | import com.persistit.exception.PersistitException; |
3154 | |
3155 | public interface Sorter { |
3156 | - Cursor sort(); |
3157 | + RowCursor sort(); |
3158 | void close(); |
3159 | } |
3160 | |
3161 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursor.java' |
3162 | --- src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursor.java 2013-07-05 21:35:32 +0000 |
3163 | +++ src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursor.java 2013-07-10 21:47:26 +0000 |
3164 | @@ -19,7 +19,7 @@ |
3165 | |
3166 | import com.akiban.qp.expression.IndexKeyRange; |
3167 | import com.akiban.qp.operator.API; |
3168 | -import com.akiban.qp.operator.Cursor; |
3169 | +import com.akiban.qp.operator.BindingsAwareCursor; |
3170 | import com.akiban.qp.operator.CursorLifecycle; |
3171 | import com.akiban.qp.operator.QueryBindings; |
3172 | import com.akiban.qp.operator.QueryContext; |
3173 | @@ -32,7 +32,7 @@ |
3174 | import com.persistit.Key.Direction; |
3175 | import com.persistit.exception.PersistitException; |
3176 | |
3177 | -public abstract class IndexCursor implements Cursor |
3178 | +public abstract class IndexCursor implements BindingsAwareCursor |
3179 | { |
3180 | // Cursor interface |
3181 | |
3182 | @@ -89,6 +89,12 @@ |
3183 | return destroyed; |
3184 | } |
3185 | |
3186 | + @Override |
3187 | + public void rebind(QueryBindings bindings) |
3188 | + { |
3189 | + this.bindings = bindings; |
3190 | + } |
3191 | + |
3192 | // For use by subclasses |
3193 | |
3194 | protected boolean nextInternal(boolean deep) |
3195 | @@ -119,7 +125,6 @@ |
3196 | // IndexCursor interface |
3197 | |
3198 | public static IndexCursor create(QueryContext context, |
3199 | - QueryBindings bindings, |
3200 | IndexKeyRange keyRange, |
3201 | API.Ordering ordering, |
3202 | IterationHelper iterationHelper, |
3203 | @@ -132,21 +137,20 @@ |
3204 | return |
3205 | keyRange != null && keyRange.spatial() |
3206 | ? keyRange.hi() == null |
3207 | - ? IndexCursorSpatial_NearPoint.create(context, bindings, iterationHelper, keyRange) |
3208 | - : IndexCursorSpatial_InBox.create(context, bindings, iterationHelper, keyRange) |
3209 | + ? IndexCursorSpatial_NearPoint.create(context, iterationHelper, keyRange) |
3210 | + : IndexCursorSpatial_InBox.create(context, iterationHelper, keyRange) |
3211 | : ordering.allAscending() || ordering.allDescending() |
3212 | ? (keyRange != null && keyRange.lexicographic() |
3213 | - ? IndexCursorUnidirectionalLexicographic.create(context, bindings, iterationHelper, keyRange, ordering, adapter) |
3214 | - : IndexCursorUnidirectional.create(context, bindings, iterationHelper, keyRange, ordering, adapter)) |
3215 | - : IndexCursorMixedOrder.create(context, bindings, iterationHelper, keyRange, ordering, adapter); |
3216 | + ? IndexCursorUnidirectionalLexicographic.create(context, iterationHelper, keyRange, ordering, adapter) |
3217 | + : IndexCursorUnidirectional.create(context, iterationHelper, keyRange, ordering, adapter)) |
3218 | + : IndexCursorMixedOrder.create(context, iterationHelper, keyRange, ordering, adapter); |
3219 | } |
3220 | |
3221 | // For use by subclasses |
3222 | |
3223 | - protected IndexCursor(QueryContext context, QueryBindings bindings, IterationHelper iterationHelper) |
3224 | + protected IndexCursor(QueryContext context, IterationHelper iterationHelper) |
3225 | { |
3226 | this.context = context; |
3227 | - this.bindings = bindings; |
3228 | this.adapter = context.getStore(); |
3229 | this.iterationHelper = iterationHelper; |
3230 | } |
3231 | @@ -159,9 +163,9 @@ |
3232 | // Object state |
3233 | |
3234 | protected final QueryContext context; |
3235 | - protected final QueryBindings bindings; |
3236 | protected final StoreAdapter adapter; |
3237 | protected final IterationHelper iterationHelper; |
3238 | + protected QueryBindings bindings; |
3239 | private boolean idle = true; |
3240 | private boolean destroyed = false; |
3241 | |
3242 | |
3243 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorMixedOrder.java' |
3244 | --- src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorMixedOrder.java 2013-07-08 18:56:18 +0000 |
3245 | +++ src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorMixedOrder.java 2013-07-10 21:47:26 +0000 |
3246 | @@ -24,7 +24,6 @@ |
3247 | import com.akiban.qp.expression.IndexBound; |
3248 | import com.akiban.qp.expression.IndexKeyRange; |
3249 | import com.akiban.qp.operator.API; |
3250 | -import com.akiban.qp.operator.QueryBindings; |
3251 | import com.akiban.qp.operator.QueryContext; |
3252 | import com.akiban.qp.persistitadapter.indexrow.PersistitIndexRow; |
3253 | import com.akiban.qp.persistitadapter.indexrow.PersistitIndexRowBuffer; |
3254 | @@ -181,13 +180,12 @@ |
3255 | // IndexCursorMixedOrder interface |
3256 | |
3257 | public static <S, E> IndexCursorMixedOrder<S, E> create(QueryContext context, |
3258 | - QueryBindings bindings, |
3259 | IterationHelper iterationHelper, |
3260 | IndexKeyRange keyRange, |
3261 | API.Ordering ordering, |
3262 | SortKeyAdapter<S, E> sortKeyAdapter) |
3263 | { |
3264 | - return new IndexCursorMixedOrder<>(context, bindings, iterationHelper, keyRange, ordering, sortKeyAdapter); |
3265 | + return new IndexCursorMixedOrder<>(context, iterationHelper, keyRange, ordering, sortKeyAdapter); |
3266 | } |
3267 | |
3268 | public void initializeScanStates() |
3269 | @@ -277,13 +275,12 @@ |
3270 | // For use by subclasses |
3271 | |
3272 | protected IndexCursorMixedOrder(QueryContext context, |
3273 | - QueryBindings bindings, |
3274 | IterationHelper iterationHelper, |
3275 | IndexKeyRange keyRange, |
3276 | API.Ordering ordering, |
3277 | SortKeyAdapter<S, E> sortKeyAdapter) |
3278 | { |
3279 | - super(context, bindings, iterationHelper); |
3280 | + super(context, iterationHelper); |
3281 | this.keyRange = keyRange; |
3282 | this.ordering = ordering; |
3283 | this.ascending = new boolean[ordering.sortColumns()]; |
3284 | |
3285 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorSpatial_InBox.java' |
3286 | --- src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorSpatial_InBox.java 2013-07-08 18:56:18 +0000 |
3287 | +++ src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorSpatial_InBox.java 2013-07-10 21:47:26 +0000 |
3288 | @@ -82,21 +82,27 @@ |
3289 | multiCursor.destroy(); |
3290 | } |
3291 | |
3292 | + @Override |
3293 | + public void rebind(QueryBindings bindings) |
3294 | + { |
3295 | + super.rebind(bindings); |
3296 | + multiCursor.rebind(bindings); |
3297 | + } |
3298 | + |
3299 | // IndexCursorSpatial_InBox interface |
3300 | |
3301 | public static IndexCursorSpatial_InBox create(QueryContext context, |
3302 | - QueryBindings bindings, |
3303 | IterationHelper iterationHelper, |
3304 | IndexKeyRange keyRange) |
3305 | { |
3306 | - return new IndexCursorSpatial_InBox(context, bindings, iterationHelper, keyRange); |
3307 | + return new IndexCursorSpatial_InBox(context, iterationHelper, keyRange); |
3308 | } |
3309 | |
3310 | // For use by this class |
3311 | |
3312 | - private IndexCursorSpatial_InBox(QueryContext context, QueryBindings bindings, IterationHelper iterationHelper, IndexKeyRange keyRange) |
3313 | + private IndexCursorSpatial_InBox(QueryContext context, IterationHelper iterationHelper, IndexKeyRange keyRange) |
3314 | { |
3315 | - super(context, bindings, iterationHelper); |
3316 | + super(context, iterationHelper); |
3317 | assert keyRange.spatial(); |
3318 | this.multiCursor = new MultiCursor(); |
3319 | this.iterationHelper = iterationHelper; |
3320 | @@ -116,7 +122,7 @@ |
3321 | IterationHelper rowState = adapter.createIterationHelper(keyRange.indexRowType()); |
3322 | if (Types3Switch.ON) { |
3323 | IndexCursorUnidirectional<PValueSource> zIntervalCursor = |
3324 | - new IndexCursorUnidirectional<>(context, bindings, |
3325 | + new IndexCursorUnidirectional<>(context, |
3326 | rowState, |
3327 | zKeyRange, |
3328 | zOrdering, |
3329 | @@ -125,7 +131,7 @@ |
3330 | } |
3331 | else { |
3332 | IndexCursorUnidirectional<ValueSource> zIntervalCursor = |
3333 | - new IndexCursorUnidirectional<>(context, bindings, |
3334 | + new IndexCursorUnidirectional<>(context, |
3335 | rowState, |
3336 | zKeyRange, |
3337 | zOrdering, |
3338 | |
3339 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorSpatial_NearPoint.java' |
3340 | --- src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorSpatial_NearPoint.java 2013-07-08 18:56:18 +0000 |
3341 | +++ src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorSpatial_NearPoint.java 2013-07-10 21:47:26 +0000 |
3342 | @@ -22,7 +22,7 @@ |
3343 | import com.akiban.qp.expression.IndexBound; |
3344 | import com.akiban.qp.expression.IndexKeyRange; |
3345 | import com.akiban.qp.operator.API; |
3346 | -import com.akiban.qp.operator.Cursor; |
3347 | +import com.akiban.qp.operator.BindingsAwareCursor; |
3348 | import com.akiban.qp.operator.QueryBindings; |
3349 | import com.akiban.qp.operator.QueryContext; |
3350 | import com.akiban.qp.row.Row; |
3351 | @@ -110,21 +110,28 @@ |
3352 | } |
3353 | } |
3354 | |
3355 | + @Override |
3356 | + public void rebind(QueryBindings bindings) |
3357 | + { |
3358 | + super.rebind(bindings); |
3359 | + geCursor.rebind(bindings); |
3360 | + ltCursor.rebind(bindings); |
3361 | + } |
3362 | + |
3363 | // IndexCursorSpatial_InBox interface |
3364 | |
3365 | public static IndexCursorSpatial_NearPoint create(QueryContext context, |
3366 | - QueryBindings bindings, |
3367 | IterationHelper iterationHelper, |
3368 | IndexKeyRange keyRange) |
3369 | { |
3370 | - return new IndexCursorSpatial_NearPoint(context, bindings, iterationHelper, keyRange); |
3371 | + return new IndexCursorSpatial_NearPoint(context, iterationHelper, keyRange); |
3372 | } |
3373 | |
3374 | // For use by this class |
3375 | |
3376 | - private IndexCursorSpatial_NearPoint(QueryContext context, QueryBindings bindings, IterationHelper iterationHelper, IndexKeyRange keyRange) |
3377 | + private IndexCursorSpatial_NearPoint(QueryContext context, IterationHelper iterationHelper, IndexKeyRange keyRange) |
3378 | { |
3379 | - super(context, bindings, iterationHelper); |
3380 | + super(context, iterationHelper); |
3381 | assert keyRange.spatial(); |
3382 | this.iterationHelper = iterationHelper; |
3383 | IndexRowType physicalIndexRowType = keyRange.indexRowType().physicalRowType(); |
3384 | @@ -183,12 +190,12 @@ |
3385 | upOrdering.append((TPreparedExpression)null, true); |
3386 | downOrdering.append((TPreparedExpression)null, false); |
3387 | } |
3388 | - geCursor = new IndexCursorUnidirectional<>(context, bindings, |
3389 | + geCursor = new IndexCursorUnidirectional<>(context, |
3390 | geRowState, |
3391 | geKeyRange, |
3392 | upOrdering, |
3393 | PValueSortKeyAdapter.INSTANCE); |
3394 | - ltCursor = new IndexCursorUnidirectional<>(context, bindings, |
3395 | + ltCursor = new IndexCursorUnidirectional<>(context, |
3396 | ltRowState, |
3397 | ltKeyRange, |
3398 | downOrdering, |
3399 | @@ -222,11 +229,11 @@ |
3400 | private final int zPosition; |
3401 | private final IterationHelper iterationHelper; |
3402 | private long zStart; |
3403 | - private Cursor geCursor; |
3404 | + private BindingsAwareCursor geCursor; |
3405 | private Row geRow; |
3406 | private long geDistance; |
3407 | private boolean geNeedToAdvance; |
3408 | - private Cursor ltCursor; |
3409 | + private BindingsAwareCursor ltCursor; |
3410 | private Row ltRow; |
3411 | private long ltDistance; |
3412 | private boolean ltNeedToAdvance; |
3413 | |
3414 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorUnidirectional.java' |
3415 | --- src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorUnidirectional.java 2013-07-08 18:56:18 +0000 |
3416 | +++ src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorUnidirectional.java 2013-07-10 21:47:26 +0000 |
3417 | @@ -25,7 +25,6 @@ |
3418 | import com.akiban.qp.expression.IndexBound; |
3419 | import com.akiban.qp.expression.IndexKeyRange; |
3420 | import com.akiban.qp.operator.API; |
3421 | -import com.akiban.qp.operator.QueryBindings; |
3422 | import com.akiban.qp.operator.QueryContext; |
3423 | import com.akiban.qp.persistitadapter.SpatialHelper; |
3424 | import com.akiban.qp.persistitadapter.indexrow.PersistitIndexRow; |
3425 | @@ -140,7 +139,6 @@ |
3426 | // IndexCursorUnidirectional interface |
3427 | |
3428 | public static <S> IndexCursorUnidirectional<S> create(QueryContext context, |
3429 | - QueryBindings bindings, |
3430 | IterationHelper iterationHelper, |
3431 | IndexKeyRange keyRange, |
3432 | API.Ordering ordering, |
3433 | @@ -148,20 +146,19 @@ |
3434 | { |
3435 | return |
3436 | keyRange == null // occurs if we're doing a sort (PersistitSorter) |
3437 | - ? new IndexCursorUnidirectional<>(context, bindings, iterationHelper, ordering, sortKeyAdapter) |
3438 | - : new IndexCursorUnidirectional<>(context, bindings, iterationHelper, keyRange, ordering, sortKeyAdapter); |
3439 | + ? new IndexCursorUnidirectional<>(context, iterationHelper, ordering, sortKeyAdapter) |
3440 | + : new IndexCursorUnidirectional<>(context, iterationHelper, keyRange, ordering, sortKeyAdapter); |
3441 | } |
3442 | |
3443 | // For use by this subclasses |
3444 | |
3445 | protected IndexCursorUnidirectional(QueryContext context, |
3446 | - QueryBindings bindings, |
3447 | IterationHelper iterationHelper, |
3448 | IndexKeyRange keyRange, |
3449 | API.Ordering ordering, |
3450 | SortKeyAdapter<S, ?> sortKeyAdapter) |
3451 | { |
3452 | - super(context, bindings, iterationHelper); |
3453 | + super(context, iterationHelper); |
3454 | // end state never changes. start state can change on a jump, so it is set in initializeCursor. |
3455 | this.endBoundColumns = keyRange.boundColumns(); |
3456 | this.endKey = endBoundColumns == 0 ? null : adapter.takeIndexRow(keyRange.indexRowType()); |
3457 | @@ -483,12 +480,11 @@ |
3458 | } |
3459 | |
3460 | private IndexCursorUnidirectional(QueryContext context, |
3461 | - QueryBindings bindings, |
3462 | IterationHelper iterationHelper, |
3463 | API.Ordering ordering, |
3464 | SortKeyAdapter<S, ?> sortKeyAdapter) |
3465 | { |
3466 | - super(context, bindings, iterationHelper); |
3467 | + super(context, iterationHelper); |
3468 | this.keyRange = null; |
3469 | this.ordering = ordering; |
3470 | if (ordering.allAscending()) { |
3471 | |
3472 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorUnidirectionalLexicographic.java' |
3473 | --- src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorUnidirectionalLexicographic.java 2013-07-08 18:56:18 +0000 |
3474 | +++ src/main/java/com/akiban/qp/persistitadapter/indexcursor/IndexCursorUnidirectionalLexicographic.java 2013-07-10 21:47:26 +0000 |
3475 | @@ -20,7 +20,6 @@ |
3476 | import com.akiban.qp.expression.BoundExpressions; |
3477 | import com.akiban.qp.expression.IndexKeyRange; |
3478 | import com.akiban.qp.operator.API; |
3479 | -import com.akiban.qp.operator.QueryBindings; |
3480 | import com.akiban.qp.operator.QueryContext; |
3481 | import com.persistit.Key; |
3482 | |
3483 | @@ -31,25 +30,23 @@ |
3484 | // IndexCursorUnidirectional interface |
3485 | |
3486 | public static <S> IndexCursorUnidirectionalLexicographic<S> create(QueryContext context, |
3487 | - QueryBindings bindings, |
3488 | IterationHelper iterationHelper, |
3489 | IndexKeyRange keyRange, |
3490 | API.Ordering ordering, |
3491 | SortKeyAdapter<S, ?> sortKeyAdapter) |
3492 | { |
3493 | - return new IndexCursorUnidirectionalLexicographic<>(context, bindings, iterationHelper, keyRange, ordering, sortKeyAdapter); |
3494 | + return new IndexCursorUnidirectionalLexicographic<>(context, iterationHelper, keyRange, ordering, sortKeyAdapter); |
3495 | } |
3496 | |
3497 | // For use by this class |
3498 | |
3499 | private IndexCursorUnidirectionalLexicographic(QueryContext context, |
3500 | - QueryBindings bindings, |
3501 | IterationHelper iterationHelper, |
3502 | IndexKeyRange keyRange, |
3503 | API.Ordering ordering, |
3504 | SortKeyAdapter<S, ?> sortKeyAdapter) |
3505 | { |
3506 | - super(context, bindings, iterationHelper, keyRange, ordering, sortKeyAdapter); |
3507 | + super(context, iterationHelper, keyRange, ordering, sortKeyAdapter); |
3508 | } |
3509 | |
3510 | @Override |
3511 | |
3512 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/indexcursor/MemorySorter.java' |
3513 | --- src/main/java/com/akiban/qp/persistitadapter/indexcursor/MemorySorter.java 2013-07-08 18:16:50 +0000 |
3514 | +++ src/main/java/com/akiban/qp/persistitadapter/indexcursor/MemorySorter.java 2013-07-10 21:47:26 +0000 |
3515 | @@ -18,7 +18,7 @@ |
3516 | package com.akiban.qp.persistitadapter.indexcursor; |
3517 | |
3518 | import com.akiban.qp.operator.API; |
3519 | -import com.akiban.qp.operator.Cursor; |
3520 | +import com.akiban.qp.operator.RowCursor; |
3521 | import com.akiban.qp.operator.CursorLifecycle; |
3522 | import com.akiban.qp.operator.QueryBindings; |
3523 | import com.akiban.qp.operator.QueryContext; |
3524 | @@ -75,7 +75,7 @@ |
3525 | |
3526 | private final QueryContext context; |
3527 | private final QueryBindings bindings; |
3528 | - private final Cursor input; |
3529 | + private final RowCursor input; |
3530 | private final API.Ordering ordering; |
3531 | private final Key key; |
3532 | private final InOutTap loadTap; |
3533 | @@ -83,7 +83,7 @@ |
3534 | |
3535 | public MemorySorter(QueryContext context, |
3536 | QueryBindings bindings, |
3537 | - Cursor input, |
3538 | + RowCursor input, |
3539 | RowType rowType, |
3540 | API.Ordering ordering, |
3541 | API.SortOption sortOption, |
3542 | @@ -114,7 +114,7 @@ |
3543 | } |
3544 | |
3545 | @Override |
3546 | - public Cursor sort() { |
3547 | + public RowCursor sort() { |
3548 | loadMap(); |
3549 | return new CollectionCursor(navigableMap.values()); |
3550 | } |
3551 | @@ -181,7 +181,7 @@ |
3552 | return states; |
3553 | } |
3554 | |
3555 | - private static final class CollectionCursor implements Cursor { |
3556 | + private static final class CollectionCursor implements RowCursor { |
3557 | private final Collection<Row> collection; |
3558 | private boolean isIdle = true; |
3559 | private boolean isDestroyed = false; |
3560 | |
3561 | === modified file 'src/main/java/com/akiban/qp/persistitadapter/indexcursor/PersistitSorter.java' |
3562 | --- src/main/java/com/akiban/qp/persistitadapter/indexcursor/PersistitSorter.java 2013-07-08 18:16:50 +0000 |
3563 | +++ src/main/java/com/akiban/qp/persistitadapter/indexcursor/PersistitSorter.java 2013-07-10 21:47:26 +0000 |
3564 | @@ -18,7 +18,7 @@ |
3565 | package com.akiban.qp.persistitadapter.indexcursor; |
3566 | |
3567 | import com.akiban.qp.operator.API; |
3568 | -import com.akiban.qp.operator.Cursor; |
3569 | +import com.akiban.qp.operator.RowCursor; |
3570 | import com.akiban.qp.operator.QueryBindings; |
3571 | import com.akiban.qp.operator.QueryContext; |
3572 | import com.akiban.qp.persistitadapter.PersistitAdapter; |
3573 | @@ -67,7 +67,7 @@ |
3574 | { |
3575 | public PersistitSorter(QueryContext context, |
3576 | QueryBindings bindings, |
3577 | - Cursor input, |
3578 | + RowCursor input, |
3579 | RowType rowType, |
3580 | API.Ordering ordering, |
3581 | API.SortOption sortOption, |
3582 | @@ -95,7 +95,7 @@ |
3583 | } |
3584 | |
3585 | @Override |
3586 | - public Cursor sort() |
3587 | + public RowCursor sort() |
3588 | { |
3589 | loadTree(); |
3590 | return cursor(); |
3591 | @@ -144,10 +144,12 @@ |
3592 | } |
3593 | } |
3594 | |
3595 | - private Cursor cursor() |
3596 | + private RowCursor cursor() |
3597 | { |
3598 | exchange.clear(); |
3599 | - return IndexCursor.create(context, bindings, null, ordering, iterationHelper, usePValues); |
3600 | + IndexCursor indexCursor = IndexCursor.create(context, null, ordering, iterationHelper, usePValues); |
3601 | + indexCursor.rebind(bindings); |
3602 | + return indexCursor; |
3603 | } |
3604 | |
3605 | private void createKey(Row row) |
3606 | @@ -188,7 +190,7 @@ |
3607 | // Object state |
3608 | |
3609 | final PersistitAdapter adapter; |
3610 | - final Cursor input; |
3611 | + final RowCursor input; |
3612 | final RowType rowType; |
3613 | final API.Ordering ordering; |
3614 | final QueryContext context; |
3615 | |
3616 | === modified file 'src/main/java/com/akiban/qp/util/MultiCursor.java' |
3617 | --- src/main/java/com/akiban/qp/util/MultiCursor.java 2013-03-22 20:05:57 +0000 |
3618 | +++ src/main/java/com/akiban/qp/util/MultiCursor.java 2013-07-10 21:47:26 +0000 |
3619 | @@ -17,7 +17,9 @@ |
3620 | |
3621 | package com.akiban.qp.util; |
3622 | |
3623 | -import com.akiban.qp.operator.Cursor; |
3624 | +import com.akiban.qp.operator.BindingsAwareCursor; |
3625 | +import com.akiban.qp.operator.QueryBindings; |
3626 | +import com.akiban.qp.operator.RowCursor; |
3627 | import com.akiban.qp.row.Row; |
3628 | import com.akiban.server.api.dml.ColumnSelector; |
3629 | |
3630 | @@ -25,7 +27,7 @@ |
3631 | import java.util.Iterator; |
3632 | import java.util.List; |
3633 | |
3634 | -public class MultiCursor implements Cursor |
3635 | +public class MultiCursor implements BindingsAwareCursor |
3636 | { |
3637 | // Cursor interface |
3638 | |
3639 | @@ -33,6 +35,8 @@ |
3640 | public void open() |
3641 | { |
3642 | sealed = false; |
3643 | + // TODO: Have a mode where all the cursors get opened so that |
3644 | + // they can start in parallel. |
3645 | cursorIterator = cursors.iterator(); |
3646 | startNextCursor(); |
3647 | } |
3648 | @@ -93,9 +97,19 @@ |
3649 | return cursorIterator == null; |
3650 | } |
3651 | |
3652 | + @Override |
3653 | + public void rebind(QueryBindings bindings) |
3654 | + { |
3655 | + for (RowCursor cursor : cursors) { |
3656 | + if (cursor instanceof BindingsAwareCursor) { |
3657 | + ((BindingsAwareCursor)cursor).rebind(bindings); |
3658 | + } |
3659 | + } |
3660 | + } |
3661 | + |
3662 | // MultiCursor interface |
3663 | |
3664 | - public void addCursor(Cursor cursor) |
3665 | + public void addCursor(RowCursor cursor) |
3666 | { |
3667 | if (sealed) { |
3668 | throw new IllegalStateException(); |
3669 | @@ -120,9 +134,9 @@ |
3670 | |
3671 | // Object state |
3672 | |
3673 | - private final List<Cursor> cursors = new ArrayList<>(); |
3674 | + private final List<RowCursor> cursors = new ArrayList<>(); |
3675 | private boolean sealed = false; |
3676 | - private Iterator<Cursor> cursorIterator; |
3677 | - private Cursor current; |
3678 | + private Iterator<RowCursor> cursorIterator; |
3679 | + private RowCursor current; |
3680 | |
3681 | } |
3682 | |
3683 | === modified file 'src/main/java/com/akiban/server/expression/subquery/ResultSetSubqueryExpression.java' |
3684 | --- src/main/java/com/akiban/server/expression/subquery/ResultSetSubqueryExpression.java 2013-07-05 21:35:32 +0000 |
3685 | +++ src/main/java/com/akiban/server/expression/subquery/ResultSetSubqueryExpression.java 2013-07-10 21:47:26 +0000 |
3686 | @@ -83,7 +83,7 @@ |
3687 | public ValueSource eval() { |
3688 | bindings.setRow(bindingPosition, outerRow); |
3689 | Cursor cursor = API.cursor(subquery, context, bindings); |
3690 | - cursor.open(); |
3691 | + cursor.openTopLevel(); |
3692 | return new ValueHolder(AkType.RESULT_SET, cursor); |
3693 | } |
3694 | |
3695 | |
3696 | === modified file 'src/main/java/com/akiban/server/expression/subquery/SubqueryExpressionEvaluation.java' |
3697 | --- src/main/java/com/akiban/server/expression/subquery/SubqueryExpressionEvaluation.java 2013-07-08 19:23:25 +0000 |
3698 | +++ src/main/java/com/akiban/server/expression/subquery/SubqueryExpressionEvaluation.java 2013-07-10 21:47:26 +0000 |
3699 | @@ -56,12 +56,12 @@ |
3700 | if (cursor == null) { |
3701 | cursor = API.cursor(subquery, context, bindings); |
3702 | } |
3703 | - cursor.open(); |
3704 | + cursor.openTopLevel(); |
3705 | try { |
3706 | return doEval(); |
3707 | } |
3708 | finally { |
3709 | - cursor.close(); |
3710 | + cursor.closeTopLevel(); |
3711 | } |
3712 | } |
3713 | |
3714 | |
3715 | === modified file 'src/main/java/com/akiban/server/service/dxl/BasicDDLFunctions.java' |
3716 | --- src/main/java/com/akiban/server/service/dxl/BasicDDLFunctions.java 2013-07-10 18:04:32 +0000 |
3717 | +++ src/main/java/com/akiban/server/service/dxl/BasicDDLFunctions.java 2013-07-10 21:47:26 +0000 |
3718 | @@ -310,14 +310,14 @@ |
3719 | ); |
3720 | com.akiban.qp.operator.Cursor cursor = API.cursor(plan, queryContext, queryBindings); |
3721 | |
3722 | - cursor.open(); |
3723 | + cursor.openTopLevel(); |
3724 | try { |
3725 | Row oldRow; |
3726 | while((oldRow = cursor.next()) != null) { |
3727 | checker.checkConstraints(oldRow, Types3Switch.ON); |
3728 | } |
3729 | } finally { |
3730 | - cursor.close(); |
3731 | + cursor.closeTopLevel(); |
3732 | } |
3733 | } |
3734 | schemaManager().alterTableDefinitions(session, changedTables); |
3735 | @@ -487,7 +487,7 @@ |
3736 | for(UserTable root : roots) { |
3737 | Operator plan = groupScan_Default(root.getGroup()); |
3738 | com.akiban.qp.operator.Cursor cursor = API.cursor(plan, queryContext, queryBindings); |
3739 | - cursor.open(); |
3740 | + cursor.openTopLevel(); |
3741 | try { |
3742 | Row oldRow; |
3743 | while((oldRow = cursor.next()) != null) { |
3744 | @@ -512,7 +512,7 @@ |
3745 | adapter.writeRow(newRow, indexes, usePValues); |
3746 | } |
3747 | } finally { |
3748 | - cursor.close(); |
3749 | + cursor.closeTopLevel(); |
3750 | } |
3751 | } |
3752 | |
3753 | |
3754 | === modified file 'src/main/java/com/akiban/server/service/externaldata/JsonRowWriter.java' |
3755 | --- src/main/java/com/akiban/server/service/externaldata/JsonRowWriter.java 2013-03-25 23:55:33 +0000 |
3756 | +++ src/main/java/com/akiban/server/service/externaldata/JsonRowWriter.java 2013-07-10 21:47:26 +0000 |
3757 | @@ -20,6 +20,7 @@ |
3758 | import com.akiban.ais.model.Column; |
3759 | import com.akiban.ais.model.IndexColumn; |
3760 | import com.akiban.qp.operator.Cursor; |
3761 | +import com.akiban.qp.operator.RowCursor; |
3762 | import com.akiban.qp.row.Row; |
3763 | import com.akiban.server.types3.pvalue.PValueSource; |
3764 | import com.akiban.util.AkibanAppender; |
3765 | @@ -42,7 +43,16 @@ |
3766 | } |
3767 | |
3768 | public boolean writeRows(Cursor cursor, AkibanAppender appender, String prefix, WriteRow rowWriter) { |
3769 | - cursor.open(); |
3770 | + try { |
3771 | + cursor.openTopLevel(); |
3772 | + return writeRowsFromOpenCursor(cursor, appender, prefix, rowWriter); |
3773 | + } |
3774 | + finally { |
3775 | + cursor.closeTopLevel(); |
3776 | + } |
3777 | + } |
3778 | + |
3779 | + public boolean writeRowsFromOpenCursor(RowCursor cursor, AkibanAppender appender, String prefix, WriteRow rowWriter) { |
3780 | tracker.reset(); |
3781 | final int minDepth = tracker.getMinDepth(); |
3782 | final int maxDepth = tracker.getMaxDepth(); |
3783 | @@ -81,7 +91,6 @@ |
3784 | appender.append('{'); |
3785 | rowWriter.write(row, appender); |
3786 | } |
3787 | - cursor.close(); |
3788 | if (depth < minDepth) |
3789 | return false; // Cursor was empty = not found. |
3790 | do { |
3791 | |
3792 | === modified file 'src/main/java/com/akiban/server/service/restdml/DeleteProcessor.java' |
3793 | --- src/main/java/com/akiban/server/service/restdml/DeleteProcessor.java 2013-07-05 21:35:32 +0000 |
3794 | +++ src/main/java/com/akiban/server/service/restdml/DeleteProcessor.java 2013-07-10 21:47:26 +0000 |
3795 | @@ -28,6 +28,7 @@ |
3796 | import com.akiban.qp.operator.API; |
3797 | import com.akiban.qp.operator.Cursor; |
3798 | import com.akiban.qp.operator.Operator; |
3799 | +import com.akiban.qp.operator.QueryBindings; |
3800 | import com.akiban.qp.row.Row; |
3801 | import com.akiban.server.service.session.Session; |
3802 | import com.akiban.server.store.Store; |
3803 | @@ -76,14 +77,14 @@ |
3804 | context.queryBindings.setPValue(i, pvalue); |
3805 | } |
3806 | |
3807 | - cursor.open(); |
3808 | + cursor.openTopLevel(); |
3809 | Row row; |
3810 | while ((row = cursor.next()) != null) { |
3811 | // Do Nothing - the act of reading the cursor |
3812 | // does the delete row processing. |
3813 | // TODO: Check that we got 1 row through. |
3814 | } |
3815 | - cursor.close(); |
3816 | + cursor.closeTopLevel(); |
3817 | } |
3818 | } finally { |
3819 | if (cursor != null) |
3820 | |
3821 | === modified file 'src/main/java/com/akiban/server/service/restdml/ModelBuilder.java' |
3822 | --- src/main/java/com/akiban/server/service/restdml/ModelBuilder.java 2013-07-08 16:06:08 +0000 |
3823 | +++ src/main/java/com/akiban/server/service/restdml/ModelBuilder.java 2013-07-10 21:47:26 +0000 |
3824 | @@ -204,7 +204,7 @@ |
3825 | int convertedRows = 0; |
3826 | try(CloseableTransaction txn = txnService.beginCloseableTransaction(session)) { |
3827 | Cursor cursor = groupScanCursor(session, tempName); |
3828 | - cursor.open(); |
3829 | + cursor.openTopLevel(); |
3830 | try { |
3831 | while((row = cursor.next()) != null) { |
3832 | node = (ObjectNode)JsonUtils.readTree(row.pvalue(1).getString()); |
3833 | @@ -213,7 +213,7 @@ |
3834 | restDMLService.insertNoTxn(session, null, tableName, node); |
3835 | ++convertedRows; |
3836 | } |
3837 | - cursor.close(); |
3838 | + cursor.closeTopLevel(); |
3839 | } finally { |
3840 | cursor.destroy(); |
3841 | } |
3842 | @@ -311,7 +311,7 @@ |
3843 | QueryContext queryContext = new SimpleQueryContext(adapter); |
3844 | QueryBindings queryBindings = queryContext.createBindings(); |
3845 | Cursor cursor = API.cursor(plan, queryContext, queryBindings); |
3846 | - cursor.open(); |
3847 | + cursor.openTopLevel(); |
3848 | try { |
3849 | return cursor.next(); |
3850 | } finally { |
3851 | @@ -334,7 +334,7 @@ |
3852 | |
3853 | private boolean scanCursor(PrintWriter writer, Cursor cursor, boolean first) throws IOException { |
3854 | Row row; |
3855 | - cursor.open(); |
3856 | + cursor.openTopLevel(); |
3857 | try { |
3858 | while((row = cursor.next()) != null) { |
3859 | if(!first) { |
3860 | @@ -348,7 +348,7 @@ |
3861 | writer.write(node.toString()); |
3862 | } |
3863 | } finally { |
3864 | - cursor.close(); |
3865 | + cursor.closeTopLevel(); |
3866 | } |
3867 | return first; |
3868 | } |
3869 | |
3870 | === modified file 'src/main/java/com/akiban/server/service/restdml/RestDMLServiceImpl.java' |
3871 | --- src/main/java/com/akiban/server/service/restdml/RestDMLServiceImpl.java 2013-07-10 16:12:59 +0000 |
3872 | +++ src/main/java/com/akiban/server/service/restdml/RestDMLServiceImpl.java 2013-07-10 21:47:26 +0000 |
3873 | @@ -614,9 +614,10 @@ |
3874 | private static void collectResults(JDBCResultSet resultSet, AkibanAppender appender) throws SQLException { |
3875 | SQLOutputCursor cursor = new SQLOutputCursor(resultSet); |
3876 | JsonRowWriter jsonRowWriter = new JsonRowWriter(cursor); |
3877 | - if(jsonRowWriter.writeRows(cursor, appender, "\n", cursor)) { |
3878 | + if(jsonRowWriter.writeRowsFromOpenCursor(cursor, appender, "\n", cursor)) { |
3879 | appender.append('\n'); |
3880 | } |
3881 | + cursor.close(); |
3882 | } |
3883 | |
3884 | private JDBCConnection jdbcConnection(HttpServletRequest request) throws SQLException { |
3885 | |
3886 | === modified file 'src/main/java/com/akiban/server/service/restdml/SQLOutputCursor.java' |
3887 | --- src/main/java/com/akiban/server/service/restdml/SQLOutputCursor.java 2013-03-22 20:05:57 +0000 |
3888 | +++ src/main/java/com/akiban/server/service/restdml/SQLOutputCursor.java 2013-07-10 21:47:26 +0000 |
3889 | @@ -17,7 +17,7 @@ |
3890 | |
3891 | package com.akiban.server.service.restdml; |
3892 | |
3893 | -import com.akiban.qp.operator.Cursor; |
3894 | +import com.akiban.qp.operator.RowCursor; |
3895 | import com.akiban.qp.row.DelegateRow; |
3896 | import com.akiban.qp.row.Row; |
3897 | import com.akiban.server.api.dml.ColumnSelector; |
3898 | @@ -32,7 +32,7 @@ |
3899 | import java.util.ArrayDeque; |
3900 | import java.util.Deque; |
3901 | |
3902 | -public class SQLOutputCursor extends GenericRowTracker implements Cursor, JsonRowWriter.WriteRow { |
3903 | +public class SQLOutputCursor extends GenericRowTracker implements RowCursor, JsonRowWriter.WriteRow { |
3904 | private final Deque<ResultSetHolder> holderStack = new ArrayDeque<>(); |
3905 | private ResultSetHolder currentHolder; |
3906 | |
3907 | |
3908 | === modified file 'src/main/java/com/akiban/server/service/restdml/UpsertProcessor.java' |
3909 | --- src/main/java/com/akiban/server/service/restdml/UpsertProcessor.java 2013-07-05 21:35:32 +0000 |
3910 | +++ src/main/java/com/akiban/server/service/restdml/UpsertProcessor.java 2013-07-10 21:47:26 +0000 |
3911 | @@ -155,7 +155,7 @@ |
3912 | i++; |
3913 | } |
3914 | cursor = API.cursor(plan, context.queryContext, context.queryBindings); |
3915 | - cursor.open(); |
3916 | + cursor.openTopLevel(); |
3917 | return cursor.next(); |
3918 | } finally { |
3919 | if (cursor != null) { |
3920 | |
3921 | === modified file 'src/main/java/com/akiban/server/service/text/FullTextCursor.java' |
3922 | --- src/main/java/com/akiban/server/service/text/FullTextCursor.java 2013-04-25 17:04:25 +0000 |
3923 | +++ src/main/java/com/akiban/server/service/text/FullTextCursor.java 2013-07-10 21:47:26 +0000 |
3924 | @@ -17,7 +17,7 @@ |
3925 | |
3926 | package com.akiban.server.service.text; |
3927 | |
3928 | -import com.akiban.qp.operator.Cursor; |
3929 | +import com.akiban.qp.operator.RowCursor; |
3930 | import com.akiban.qp.operator.CursorLifecycle; |
3931 | import com.akiban.qp.operator.QueryContext; |
3932 | import com.akiban.qp.persistitadapter.PersistitHKey; |
3933 | @@ -45,7 +45,7 @@ |
3934 | |
3935 | import java.io.IOException; |
3936 | |
3937 | -public class FullTextCursor implements Cursor |
3938 | +public class FullTextCursor implements RowCursor |
3939 | { |
3940 | private final QueryContext context; |
3941 | private final HKeyRowType rowType; |
3942 | |
3943 | === modified file 'src/main/java/com/akiban/server/service/text/FullTextIndexService.java' |
3944 | --- src/main/java/com/akiban/server/service/text/FullTextIndexService.java 2013-07-10 16:12:59 +0000 |
3945 | +++ src/main/java/com/akiban/server/service/text/FullTextIndexService.java 2013-07-10 21:47:26 +0000 |
3946 | @@ -18,7 +18,7 @@ |
3947 | package com.akiban.server.service.text; |
3948 | |
3949 | import com.akiban.ais.model.IndexName; |
3950 | -import com.akiban.qp.operator.Cursor; |
3951 | +import com.akiban.qp.operator.RowCursor; |
3952 | import com.akiban.qp.operator.QueryContext; |
3953 | import com.akiban.server.service.BackgroundWork; |
3954 | |
3955 | @@ -32,5 +32,6 @@ |
3956 | */ |
3957 | public List<? extends BackgroundWork> getBackgroundWorks(); |
3958 | |
3959 | - public Cursor searchIndex(QueryContext context, IndexName name, Query query, int limit); |
3960 | + public RowCursor searchIndex(QueryContext context, IndexName name, |
3961 | + Query query, int limit); |
3962 | } |
3963 | |
3964 | === modified file 'src/main/java/com/akiban/server/service/text/FullTextIndexServiceImpl.java' |
3965 | --- src/main/java/com/akiban/server/service/text/FullTextIndexServiceImpl.java 2013-07-10 18:04:32 +0000 |
3966 | +++ src/main/java/com/akiban/server/service/text/FullTextIndexServiceImpl.java 2013-07-10 21:47:26 +0000 |
3967 | @@ -31,6 +31,7 @@ |
3968 | import com.akiban.qp.operator.Operator; |
3969 | import com.akiban.qp.operator.QueryBindings; |
3970 | import com.akiban.qp.operator.QueryContext; |
3971 | +import com.akiban.qp.operator.RowCursor; |
3972 | import com.akiban.qp.operator.SimpleQueryContext; |
3973 | import com.akiban.qp.operator.StoreAdapter; |
3974 | import com.akiban.qp.persistitadapter.PersistitAdapter; |
3975 | @@ -177,7 +178,7 @@ |
3976 | } |
3977 | |
3978 | @Override |
3979 | - public Cursor searchIndex(QueryContext context, IndexName name, Query query, int limit) { |
3980 | + public RowCursor searchIndex(QueryContext context, IndexName name, Query query, int limit) { |
3981 | FullTextIndexInfo index = getIndex(context.getSession(), name, null); |
3982 | try { |
3983 | return index.getSearcher().search(context, index.getHKeyRowType(), |
3984 | @@ -266,7 +267,6 @@ |
3985 | } |
3986 | finally { |
3987 | if(cursor != null) { |
3988 | - cursor.close(); |
3989 | cursor.destroy(); |
3990 | } |
3991 | if(!success) { |
3992 | @@ -308,7 +308,6 @@ |
3993 | finally |
3994 | { |
3995 | if(cursor != null) { |
3996 | - cursor.close(); |
3997 | cursor.destroy(); |
3998 | } |
3999 | if(!success) { |
4000 | |
4001 | === modified file 'src/main/java/com/akiban/server/service/text/FullTextQueryBuilder.java' |
4002 | --- src/main/java/com/akiban/server/service/text/FullTextQueryBuilder.java 2013-07-08 18:56:18 +0000 |
4003 | +++ src/main/java/com/akiban/server/service/text/FullTextQueryBuilder.java 2013-07-10 21:47:26 +0000 |
4004 | @@ -104,6 +104,11 @@ |
4005 | } |
4006 | |
4007 | @Override |
4008 | + public boolean needsBindings() { |
4009 | + return false; |
4010 | + } |
4011 | + |
4012 | + @Override |
4013 | public Query getQuery(QueryContext context, QueryBindings bindings) { |
4014 | return query; |
4015 | } |
4016 | @@ -138,6 +143,11 @@ |
4017 | } |
4018 | return new FullTextQueryExpression() { |
4019 | @Override |
4020 | + public boolean needsBindings() { |
4021 | + return false; |
4022 | + } |
4023 | + |
4024 | + @Override |
4025 | public Query getQuery(QueryContext context, QueryBindings bindings) { |
4026 | return infos.parseQuery(context, indexName, fieldName, query); |
4027 | } |
4028 | @@ -161,6 +171,11 @@ |
4029 | final String fieldName = (defaultField == null) ? null : defaultField.getColumn().getName(); |
4030 | return new FullTextQueryExpression() { |
4031 | @Override |
4032 | + public boolean needsBindings() { |
4033 | + return true; |
4034 | + } |
4035 | + |
4036 | + @Override |
4037 | public Query getQuery(QueryContext context, QueryBindings bindings) { |
4038 | TEvaluatableExpression qeval = qexpr.build(); |
4039 | qeval.with(context); |
4040 | @@ -197,6 +212,11 @@ |
4041 | final String fieldName = checkFieldForMatch(field); |
4042 | return new FullTextQueryExpression() { |
4043 | @Override |
4044 | + public boolean needsBindings() { |
4045 | + return true; |
4046 | + } |
4047 | + |
4048 | + @Override |
4049 | public Query getQuery(QueryContext context, QueryBindings bindings) { |
4050 | TEvaluatableExpression qeval = qexpr.build(); |
4051 | qeval.with(context); |
4052 | @@ -246,6 +266,16 @@ |
4053 | FullTextQueryExpression result = |
4054 | new FullTextQueryExpression() { |
4055 | @Override |
4056 | + public boolean needsBindings() { |
4057 | + for (FullTextQueryExpression query : queries) { |
4058 | + if (query.needsBindings()) { |
4059 | + return true; |
4060 | + } |
4061 | + } |
4062 | + return false; |
4063 | + } |
4064 | + |
4065 | + @Override |
4066 | public Query getQuery(QueryContext context, QueryBindings bindings) { |
4067 | BooleanQuery query = new BooleanQuery(); |
4068 | for (int i = 0; i < queries.size(); i++) { |
4069 | |
4070 | === modified file 'src/main/java/com/akiban/server/service/text/FullTextQueryExpression.java' |
4071 | --- src/main/java/com/akiban/server/service/text/FullTextQueryExpression.java 2013-07-08 18:56:18 +0000 |
4072 | +++ src/main/java/com/akiban/server/service/text/FullTextQueryExpression.java 2013-07-10 21:47:26 +0000 |
4073 | @@ -27,5 +27,6 @@ |
4074 | * parsed from a string, or built up from expressions. |
4075 | */ |
4076 | public interface FullTextQueryExpression extends Explainable { |
4077 | + public boolean needsBindings(); |
4078 | public Query getQuery(QueryContext context, QueryBindings bindings); |
4079 | } |
4080 | |
4081 | === modified file 'src/main/java/com/akiban/server/service/text/IndexScan_FullText.java' |
4082 | --- src/main/java/com/akiban/server/service/text/IndexScan_FullText.java 2013-07-08 18:56:18 +0000 |
4083 | +++ src/main/java/com/akiban/server/service/text/IndexScan_FullText.java 2013-07-10 21:47:26 +0000 |
4084 | @@ -19,10 +19,14 @@ |
4085 | |
4086 | import com.akiban.ais.model.IndexName; |
4087 | import com.akiban.qp.operator.Cursor; |
4088 | +import com.akiban.qp.operator.LeafCursor; |
4089 | import com.akiban.qp.operator.Operator; |
4090 | -import com.akiban.qp.operator.QueryBindings; |
4091 | +import com.akiban.qp.operator.QueryBindingsCursor; |
4092 | import com.akiban.qp.operator.QueryContext; |
4093 | +import com.akiban.qp.operator.RowCursor; |
4094 | +import com.akiban.qp.row.Row; |
4095 | import com.akiban.qp.rowtype.RowType; |
4096 | +import com.akiban.server.api.dml.ColumnSelector; |
4097 | import com.akiban.server.explain.*; |
4098 | |
4099 | import org.apache.lucene.search.Query; |
4100 | @@ -53,12 +57,91 @@ |
4101 | } |
4102 | |
4103 | @Override |
4104 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) { |
4105 | - Query query = queryExpression.getQuery(context, bindings); |
4106 | - FullTextIndexService service = context.getServiceManager().getServiceByClass(FullTextIndexService.class); |
4107 | - return service.searchIndex(context, index, query, limit); |
4108 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) { |
4109 | + return new Execution(context, bindingsCursor); |
4110 | } |
4111 | |
4112 | + protected class Execution extends LeafCursor { |
4113 | + private final FullTextIndexService service; |
4114 | + private RowCursor cursor; |
4115 | + private boolean destroyed; |
4116 | + |
4117 | + public Execution(QueryContext context, QueryBindingsCursor bindingsCursor) { |
4118 | + super(context, bindingsCursor); |
4119 | + service = context.getServiceManager().getServiceByClass(FullTextIndexService.class); |
4120 | + if (!queryExpression.needsBindings()) { |
4121 | + // Can reuse cursor if it doesn't need bindings at open() time. |
4122 | + Query query = queryExpression.getQuery(context, null); |
4123 | + cursor = service.searchIndex(context, index, query, limit); |
4124 | + } |
4125 | + } |
4126 | + |
4127 | + @Override |
4128 | + public void open() |
4129 | + { |
4130 | + if (queryExpression.needsBindings()) { |
4131 | + Query query = queryExpression.getQuery(context, bindings); |
4132 | + cursor = service.searchIndex(context, index, query, limit); |
4133 | + } |
4134 | + cursor.open(); |
4135 | + } |
4136 | + |
4137 | + @Override |
4138 | + public Row next() |
4139 | + { |
4140 | + checkQueryCancelation(); |
4141 | + return cursor.next(); |
4142 | + } |
4143 | + |
4144 | + @Override |
4145 | + public void jump(Row row, ColumnSelector columnSelector) |
4146 | + { |
4147 | + cursor.jump(row, columnSelector); |
4148 | + } |
4149 | + |
4150 | + @Override |
4151 | + public void close() |
4152 | + { |
4153 | + if (cursor != null) { |
4154 | + if (queryExpression.needsBindings()) { |
4155 | + cursor.destroy(); |
4156 | + cursor = null; |
4157 | + } |
4158 | + else { |
4159 | + cursor.close(); |
4160 | + } |
4161 | + } |
4162 | + } |
4163 | + |
4164 | + @Override |
4165 | + public void destroy() |
4166 | + { |
4167 | + if (cursor != null) { |
4168 | + cursor.destroy(); |
4169 | + cursor = null; |
4170 | + } |
4171 | + destroyed = true; |
4172 | + } |
4173 | + |
4174 | + @Override |
4175 | + public boolean isIdle() |
4176 | + { |
4177 | + return (cursor == null) ? !destroyed : cursor.isIdle(); |
4178 | + } |
4179 | + |
4180 | + @Override |
4181 | + public boolean isActive() |
4182 | + { |
4183 | + return (cursor != null) && cursor.isActive(); |
4184 | + } |
4185 | + |
4186 | + @Override |
4187 | + public boolean isDestroyed() |
4188 | + { |
4189 | + return destroyed; |
4190 | + } |
4191 | + } |
4192 | + |
4193 | @Override |
4194 | public CompoundExplainer getExplainer(ExplainContext context) |
4195 | { |
4196 | |
4197 | === modified file 'src/main/java/com/akiban/server/service/text/RowIndexer.java' |
4198 | --- src/main/java/com/akiban/server/service/text/RowIndexer.java 2013-07-02 19:16:02 +0000 |
4199 | +++ src/main/java/com/akiban/server/service/text/RowIndexer.java 2013-07-10 21:47:26 +0000 |
4200 | @@ -124,13 +124,13 @@ |
4201 | |
4202 | public long indexRows(Cursor cursor) throws IOException { |
4203 | documentCount = 0; |
4204 | - cursor.open(); |
4205 | + cursor.openTopLevel(); |
4206 | Row row; |
4207 | do { |
4208 | row = cursor.next(); |
4209 | indexRow(row); |
4210 | } while (row != null); |
4211 | - cursor.close(); |
4212 | + cursor.closeTopLevel(); |
4213 | return documentCount; |
4214 | } |
4215 | |
4216 | |
4217 | === modified file 'src/main/java/com/akiban/server/service/text/Searcher.java' |
4218 | --- src/main/java/com/akiban/server/service/text/Searcher.java 2013-03-22 20:05:57 +0000 |
4219 | +++ src/main/java/com/akiban/server/service/text/Searcher.java 2013-07-10 21:47:26 +0000 |
4220 | @@ -17,7 +17,7 @@ |
4221 | |
4222 | package com.akiban.server.service.text; |
4223 | |
4224 | -import com.akiban.qp.operator.Cursor; |
4225 | +import com.akiban.qp.operator.RowCursor; |
4226 | import com.akiban.qp.operator.QueryContext; |
4227 | import com.akiban.qp.rowtype.HKeyRowType; |
4228 | |
4229 | @@ -45,8 +45,8 @@ |
4230 | this.searcherManager = new SearcherManager(index.open(), new SearcherFactory()); |
4231 | } |
4232 | |
4233 | - public Cursor search(QueryContext context, HKeyRowType rowType, |
4234 | - Query query, int limit) |
4235 | + public RowCursor search(QueryContext context, HKeyRowType rowType, |
4236 | + Query query, int limit) |
4237 | throws IOException { |
4238 | searcherManager.maybeRefresh(); // TODO: Move to better place. |
4239 | if (limit <= 0) limit = DEFAULT_LIMIT; |
4240 | |
4241 | === modified file 'src/main/java/com/akiban/server/store/AbstractStore.java' |
4242 | --- src/main/java/com/akiban/server/store/AbstractStore.java 2013-07-10 18:04:32 +0000 |
4243 | +++ src/main/java/com/akiban/server/store/AbstractStore.java 2013-07-10 21:47:26 +0000 |
4244 | @@ -35,6 +35,7 @@ |
4245 | import com.akiban.qp.operator.GroupCursor; |
4246 | import com.akiban.qp.operator.Operator; |
4247 | import com.akiban.qp.operator.QueryBindings; |
4248 | +import com.akiban.qp.operator.QueryBindingsCursor; |
4249 | import com.akiban.qp.operator.QueryContext; |
4250 | import com.akiban.qp.operator.SimpleQueryContext; |
4251 | import com.akiban.qp.operator.StoreAdapter; |
4252 | @@ -1217,7 +1218,7 @@ |
4253 | } |
4254 | try { |
4255 | Row row; |
4256 | - cursor.open(); |
4257 | + cursor.openTopLevel(); |
4258 | while((row = cursor.next()) != null) { |
4259 | UserTable table = row.rowType().userTable(); |
4260 | RowData data = adapter.rowData(table.rowDef(), row, new PValueRowDataCreator()); |
4261 | @@ -1229,7 +1230,7 @@ |
4262 | StoreGIHandler.forTable(this, adapter, uTable), |
4263 | StoreGIHandler.Action.CASCADE); |
4264 | } |
4265 | - cursor.close(); |
4266 | + cursor.closeTopLevel(); |
4267 | } finally { |
4268 | cursor.destroy(); |
4269 | } |
4270 | @@ -1308,7 +1309,7 @@ |
4271 | StoreGIHandler handler, |
4272 | StoreGIHandler.Action action) { |
4273 | Cursor cursor = API.cursor(rootOperator, context, bindings); |
4274 | - cursor.open(); |
4275 | + cursor.openTopLevel(); |
4276 | try { |
4277 | Row row; |
4278 | while((row = cursor.next()) != null) { |
4279 | @@ -1316,6 +1317,7 @@ |
4280 | handler.handleRow(groupIndex, row, action); |
4281 | } |
4282 | } |
4283 | + cursor.closeTopLevel(); |
4284 | } finally { |
4285 | cursor.destroy(); |
4286 | } |
4287 | |
4288 | === modified file 'src/main/java/com/akiban/server/store/StoreGIMaintenance.java' |
4289 | --- src/main/java/com/akiban/server/store/StoreGIMaintenance.java 2013-07-08 16:06:08 +0000 |
4290 | +++ src/main/java/com/akiban/server/store/StoreGIMaintenance.java 2013-07-10 21:47:26 +0000 |
4291 | @@ -87,7 +87,7 @@ |
4292 | cursor = API.cursor(planOperator, context, bindings); |
4293 | RUN_TAP.in(); |
4294 | runTapEntered = true; |
4295 | - cursor.open(); |
4296 | + cursor.openTopLevel(); |
4297 | Row row; |
4298 | while ((row = cursor.next()) != null) { |
4299 | boolean actioned = false; |
4300 | @@ -160,7 +160,7 @@ |
4301 | Cursor siblingsCounter = API.cursor(siblingsLookup, context, bindings); |
4302 | SIBLING_ALL_TAP.in(); |
4303 | try { |
4304 | - siblingsCounter.open(); |
4305 | + siblingsCounter.openTopLevel(); |
4306 | int siblings = 0; |
4307 | while (siblingsCounter.next() != null) { |
4308 | SIBLING_ROW_TAP.hit(); |
4309 | |
4310 | === modified file 'src/main/java/com/akiban/server/types3/texpressions/ResultSetSubqueryTExpression.java' |
4311 | --- src/main/java/com/akiban/server/types3/texpressions/ResultSetSubqueryTExpression.java 2013-07-05 21:35:32 +0000 |
4312 | +++ src/main/java/com/akiban/server/types3/texpressions/ResultSetSubqueryTExpression.java 2013-07-10 21:47:26 +0000 |
4313 | @@ -42,7 +42,7 @@ |
4314 | public void evaluate() { |
4315 | bindings.setRow(bindingPosition, outerRow); |
4316 | Cursor cursor = API.cursor(subquery, context, bindings); |
4317 | - cursor.open(); |
4318 | + cursor.openTopLevel(); |
4319 | pvalue.putObject(cursor); |
4320 | } |
4321 | |
4322 | |
4323 | === modified file 'src/main/java/com/akiban/server/types3/texpressions/SubqueryTEvaluateble.java' |
4324 | --- src/main/java/com/akiban/server/types3/texpressions/SubqueryTEvaluateble.java 2013-07-08 18:56:18 +0000 |
4325 | +++ src/main/java/com/akiban/server/types3/texpressions/SubqueryTEvaluateble.java 2013-07-10 21:47:26 +0000 |
4326 | @@ -43,12 +43,12 @@ |
4327 | if (cursor == null) { |
4328 | cursor = API.cursor(subquery, context, bindings); |
4329 | } |
4330 | - cursor.open(); |
4331 | + cursor.openTopLevel(); |
4332 | try { |
4333 | doEval(pvalue); |
4334 | } |
4335 | finally { |
4336 | - cursor.close(); |
4337 | + cursor.closeTopLevel(); |
4338 | } |
4339 | } |
4340 | |
4341 | |
4342 | === modified file 'src/main/java/com/akiban/sql/embedded/ExecutableModifyOperatorStatement.java' |
4343 | --- src/main/java/com/akiban/sql/embedded/ExecutableModifyOperatorStatement.java 2013-07-05 21:35:32 +0000 |
4344 | +++ src/main/java/com/akiban/sql/embedded/ExecutableModifyOperatorStatement.java 2013-07-10 21:47:26 +0000 |
4345 | @@ -22,6 +22,7 @@ |
4346 | import com.akiban.qp.operator.CursorLifecycle; |
4347 | import com.akiban.qp.operator.Operator; |
4348 | import com.akiban.qp.operator.QueryBindings; |
4349 | +import com.akiban.qp.operator.RowCursor; |
4350 | import com.akiban.qp.row.ImmutableRow; |
4351 | import com.akiban.qp.row.ProjectedRow; |
4352 | import com.akiban.qp.row.Row; |
4353 | @@ -54,7 +55,7 @@ |
4354 | @Override |
4355 | public ExecuteResults execute(EmbeddedQueryContext context, QueryBindings bindings) { |
4356 | int updateCount = 0; |
4357 | - SpoolCursor returningRows = null; |
4358 | + SpoolCursor returningRows = null; |
4359 | if (resultSetMetaData != null) |
4360 | // If there are results, we need to read them all now to get the update |
4361 | // count right and have this all happen even if the caller |
4362 | @@ -65,7 +66,7 @@ |
4363 | RuntimeException runtimeException = null; |
4364 | try { |
4365 | cursor = API.cursor(resultOperator, context, bindings); |
4366 | - cursor.open(); |
4367 | + cursor.openTopLevel(); |
4368 | Row row; |
4369 | while ((row = cursor.next()) != null) { |
4370 | updateCount++; |
4371 | @@ -116,7 +117,7 @@ |
4372 | return AISGenerationMode.NOT_ALLOWED; |
4373 | } |
4374 | |
4375 | - static class SpoolCursor implements Cursor { |
4376 | + static class SpoolCursor implements RowCursor { |
4377 | private List<ShareHolder<Row>> rows = new ArrayList<>(); |
4378 | private Iterator<ShareHolder<Row>> iterator; |
4379 | private enum State { CLOSED, FILLING, EMPTYING, DESTROYED } |
4380 | |
4381 | === modified file 'src/main/java/com/akiban/sql/embedded/ExecutableQueryOperatorStatement.java' |
4382 | --- src/main/java/com/akiban/sql/embedded/ExecutableQueryOperatorStatement.java 2013-07-05 21:35:32 +0000 |
4383 | +++ src/main/java/com/akiban/sql/embedded/ExecutableQueryOperatorStatement.java 2013-07-10 21:47:26 +0000 |
4384 | @@ -40,7 +40,7 @@ |
4385 | Cursor cursor = null; |
4386 | try { |
4387 | cursor = API.cursor(resultOperator, context, bindings); |
4388 | - cursor.open(); |
4389 | + cursor.openTopLevel(); |
4390 | ExecuteResults result = new ExecuteResults(cursor); |
4391 | cursor = null; |
4392 | return result; |
4393 | |
4394 | === modified file 'src/main/java/com/akiban/sql/embedded/ExecuteResults.java' |
4395 | --- src/main/java/com/akiban/sql/embedded/ExecuteResults.java 2013-03-22 20:05:57 +0000 |
4396 | +++ src/main/java/com/akiban/sql/embedded/ExecuteResults.java 2013-07-10 21:47:26 +0000 |
4397 | @@ -17,7 +17,7 @@ |
4398 | |
4399 | package com.akiban.sql.embedded; |
4400 | |
4401 | -import com.akiban.qp.operator.Cursor; |
4402 | +import com.akiban.qp.operator.RowCursor; |
4403 | |
4404 | import java.sql.ResultSet; |
4405 | import java.util.Queue; |
4406 | @@ -25,7 +25,7 @@ |
4407 | class ExecuteResults |
4408 | { |
4409 | private int updateCount; |
4410 | - private Cursor cursor; |
4411 | + private RowCursor cursor; |
4412 | private Queue<ResultSet> additionalResultSets; |
4413 | |
4414 | /** No results. */ |
4415 | @@ -36,7 +36,7 @@ |
4416 | /** Ordinary select result. |
4417 | * Transaction remains open while it is visited. |
4418 | */ |
4419 | - public ExecuteResults(Cursor cursor) { |
4420 | + public ExecuteResults(RowCursor cursor) { |
4421 | this.updateCount = -1; |
4422 | this.cursor = cursor; |
4423 | } |
4424 | @@ -44,7 +44,7 @@ |
4425 | /** Update result, possibly with returned keys. |
4426 | * These keys are already copied in order to get update count correct. |
4427 | */ |
4428 | - public ExecuteResults(int updateCount, Cursor generatedKeys) { |
4429 | + public ExecuteResults(int updateCount, RowCursor generatedKeys) { |
4430 | this.updateCount = updateCount; |
4431 | this.cursor = generatedKeys; |
4432 | } |
4433 | @@ -59,7 +59,7 @@ |
4434 | return updateCount; |
4435 | } |
4436 | |
4437 | - public Cursor getCursor() { |
4438 | + public RowCursor getCursor() { |
4439 | return cursor; |
4440 | } |
4441 | |
4442 | |
4443 | === modified file 'src/main/java/com/akiban/sql/embedded/JDBCResultSet.java' |
4444 | --- src/main/java/com/akiban/sql/embedded/JDBCResultSet.java 2013-04-24 19:15:51 +0000 |
4445 | +++ src/main/java/com/akiban/sql/embedded/JDBCResultSet.java 2013-07-10 21:47:26 +0000 |
4446 | @@ -29,7 +29,7 @@ |
4447 | import com.akiban.direct.AbstractDirectObject; |
4448 | import com.akiban.direct.Direct; |
4449 | import com.akiban.direct.DirectResultSet; |
4450 | -import com.akiban.qp.operator.Cursor; |
4451 | +import com.akiban.qp.operator.RowCursor; |
4452 | import com.akiban.qp.row.Row; |
4453 | import com.akiban.server.types.AkType; |
4454 | import com.akiban.server.types.ValueSource; |
4455 | @@ -42,14 +42,14 @@ |
4456 | { |
4457 | protected final JDBCStatement statement; |
4458 | protected final JDBCResultSetMetaData metaData; |
4459 | - protected Cursor cursor; |
4460 | + protected RowCursor cursor; |
4461 | protected Row row; |
4462 | private final EmbeddedQueryContext context; |
4463 | private final Values values; |
4464 | private JDBCWarning warnings; |
4465 | |
4466 | protected JDBCResultSet(JDBCStatement statement, JDBCResultSetMetaData metaData, |
4467 | - Cursor cursor) { |
4468 | + RowCursor cursor) { |
4469 | this.statement = statement; |
4470 | this.metaData = metaData; |
4471 | this.cursor = cursor; |
4472 | @@ -100,7 +100,7 @@ |
4473 | protected ResultSet toResultSet(int index, Object cursor) { |
4474 | if (cursor == null) |
4475 | return null; |
4476 | - JDBCResultSet resultSet = new JDBCResultSet(statement, metaData.getNestedResultSet(index + 1), (Cursor)cursor); |
4477 | + JDBCResultSet resultSet = new JDBCResultSet(statement, metaData.getNestedResultSet(index + 1), (RowCursor)cursor); |
4478 | statement.secondaryResultSet(resultSet); |
4479 | return resultSet; |
4480 | } |
4481 | @@ -137,7 +137,7 @@ |
4482 | |
4483 | @Override |
4484 | public <T> T unwrap(Class<T> iface) throws SQLException { |
4485 | - if (iface == Cursor.class) |
4486 | + if (iface == RowCursor.class) |
4487 | return (T)cursor; |
4488 | if (iface == Row.class) |
4489 | return (T)row; |
4490 | @@ -146,7 +146,7 @@ |
4491 | |
4492 | @Override |
4493 | public boolean isWrapperFor(Class<?> iface) throws SQLException { |
4494 | - if (iface == Cursor.class) |
4495 | + if (iface == RowCursor.class) |
4496 | return true; |
4497 | if (iface == Row.class) |
4498 | return true; |
4499 | |
4500 | === modified file 'src/main/java/com/akiban/sql/pg/PostgresModifyOperatorStatement.java' |
4501 | --- src/main/java/com/akiban/sql/pg/PostgresModifyOperatorStatement.java 2013-07-06 17:46:02 +0000 |
4502 | +++ src/main/java/com/akiban/sql/pg/PostgresModifyOperatorStatement.java 2013-07-10 21:47:26 +0000 |
4503 | @@ -127,7 +127,7 @@ |
4504 | @Override |
4505 | public Cursor openCursor(PostgresQueryContext context, QueryBindings bindings) { |
4506 | Cursor cursor = API.cursor(resultOperator, context, bindings); |
4507 | - cursor.open(); |
4508 | + cursor.openTopLevel(); |
4509 | return cursor; |
4510 | } |
4511 | |
4512 | |
4513 | === modified file 'src/main/java/com/akiban/sql/pg/PostgresOperatorStatement.java' |
4514 | --- src/main/java/com/akiban/sql/pg/PostgresOperatorStatement.java 2013-07-06 17:46:02 +0000 |
4515 | +++ src/main/java/com/akiban/sql/pg/PostgresOperatorStatement.java 2013-07-10 21:47:26 +0000 |
4516 | @@ -84,7 +84,7 @@ |
4517 | @Override |
4518 | public Cursor openCursor(PostgresQueryContext context, QueryBindings bindings) { |
4519 | Cursor cursor = API.cursor(resultOperator, context, bindings); |
4520 | - cursor.open(); |
4521 | + cursor.openTopLevel(); |
4522 | return cursor; |
4523 | } |
4524 | |
4525 | |
4526 | === modified file 'src/test/java/com/akiban/qp/operator/OperatorTestHelper.java' |
4527 | --- src/test/java/com/akiban/qp/operator/OperatorTestHelper.java 2013-07-08 18:16:50 +0000 |
4528 | +++ src/test/java/com/akiban/qp/operator/OperatorTestHelper.java 2013-07-10 21:47:26 +0000 |
4529 | @@ -133,13 +133,14 @@ |
4530 | public static Cursor open(Operator plan) { |
4531 | QueryContext queryContext = new SimpleQueryContext(ADAPTER); |
4532 | QueryBindings queryBindings = queryContext.createBindings(); |
4533 | - Cursor result = plan.cursor(queryContext, queryBindings); |
4534 | + QueryBindingsCursor queryBindingsCursor = new SingletonQueryBindingsCursor(queryBindings); |
4535 | + Cursor result = plan.cursor(queryContext, queryBindingsCursor); |
4536 | reopen(result); |
4537 | return result; |
4538 | } |
4539 | |
4540 | public static void reopen(Cursor cursor) { |
4541 | - cursor.open(); |
4542 | + cursor.openTopLevel(); |
4543 | } |
4544 | |
4545 | public static List<Row> execute(Operator plan) { |
4546 | @@ -188,7 +189,6 @@ |
4547 | |
4548 | @Override |
4549 | public Cursor newIndexCursor(QueryContext context, |
4550 | - QueryBindings bindings, |
4551 | Index index, |
4552 | IndexKeyRange keyRange, |
4553 | API.Ordering ordering, |
4554 | @@ -230,7 +230,7 @@ |
4555 | @Override |
4556 | public Sorter createSorter(QueryContext context, |
4557 | QueryBindings bindings, |
4558 | - Cursor input, |
4559 | + RowCursor input, |
4560 | RowType rowType, |
4561 | API.Ordering ordering, |
4562 | API.SortOption sortOption, |
4563 | |
4564 | === modified file 'src/test/java/com/akiban/qp/operator/TimeOperator.java' |
4565 | --- src/test/java/com/akiban/qp/operator/TimeOperator.java 2013-07-08 18:16:50 +0000 |
4566 | +++ src/test/java/com/akiban/qp/operator/TimeOperator.java 2013-07-10 21:47:26 +0000 |
4567 | @@ -41,9 +41,9 @@ |
4568 | // Operator interface |
4569 | |
4570 | @Override |
4571 | - protected Cursor cursor(QueryContext context, QueryBindings bindings) |
4572 | + protected Cursor cursor(QueryContext context, QueryBindingsCursor bindingsCursor) |
4573 | { |
4574 | - return new Execution(context, bindings); |
4575 | + return new Execution(context, bindingsCursor); |
4576 | } |
4577 | |
4578 | @Override |
4579 | @@ -90,7 +90,7 @@ |
4580 | |
4581 | // Inner classes |
4582 | |
4583 | - private class Execution extends OperatorExecutionBase implements Cursor |
4584 | + private class Execution extends ChainedCursor |
4585 | { |
4586 | // Cursor interface |
4587 | |
4588 | @@ -122,40 +122,11 @@ |
4589 | elapsedNsec += stop - start; |
4590 | } |
4591 | |
4592 | - @Override |
4593 | - public void destroy() |
4594 | - { |
4595 | - input.destroy(); |
4596 | - } |
4597 | - |
4598 | - @Override |
4599 | - public boolean isIdle() |
4600 | - { |
4601 | - return input.isIdle(); |
4602 | - } |
4603 | - |
4604 | - @Override |
4605 | - public boolean isActive() |
4606 | - { |
4607 | - return input.isActive(); |
4608 | - } |
4609 | - |
4610 | - @Override |
4611 | - public boolean isDestroyed() |
4612 | - { |
4613 | - return input.isDestroyed(); |
4614 | - } |
4615 | - |
4616 | // Execution interface |
4617 | |
4618 | - Execution(QueryContext context, QueryBindings bindings) |
4619 | + Execution(QueryContext context, QueryBindingsCursor bindingsCursor) |
4620 | { |
4621 | - super(context, bindings); |
4622 | - this.input = inputOperator.cursor(context, bindings); |
4623 | + super(context, inputOperator.cursor(context, bindingsCursor)); |
4624 | } |
4625 | - |
4626 | - // Object state |
4627 | - |
4628 | - private final Cursor input; |
4629 | } |
4630 | } |
4631 | |
4632 | === modified file 'src/test/java/com/akiban/server/test/costmodel/DistinctCT.java' |
4633 | --- src/test/java/com/akiban/server/test/costmodel/DistinctCT.java 2013-07-08 18:16:50 +0000 |
4634 | +++ src/test/java/com/akiban/server/test/costmodel/DistinctCT.java 2013-07-10 21:47:26 +0000 |
4635 | @@ -122,7 +122,7 @@ |
4636 | long start = System.nanoTime(); |
4637 | for (int r = 0; r < runs; r++) { |
4638 | Cursor cursor = cursor(distinct, queryContext, queryBindings); |
4639 | - cursor.open(); |
4640 | + cursor.openTopLevel(); |
4641 | while (cursor.next() != null); |
4642 | } |
4643 | long stop = System.nanoTime(); |
4644 | |
4645 | === modified file 'src/test/java/com/akiban/server/test/costmodel/FlattenCT.java' |
4646 | --- src/test/java/com/akiban/server/test/costmodel/FlattenCT.java 2013-07-08 18:16:50 +0000 |
4647 | +++ src/test/java/com/akiban/server/test/costmodel/FlattenCT.java 2013-07-10 21:47:26 +0000 |
4648 | @@ -107,7 +107,7 @@ |
4649 | long start = System.nanoTime(); |
4650 | for (int r = 0; r < runs; r++) { |
4651 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4652 | - cursor.open(); |
4653 | + cursor.openTopLevel(); |
4654 | while (cursor.next() != null); |
4655 | } |
4656 | long stop = System.nanoTime(); |
4657 | |
4658 | === modified file 'src/test/java/com/akiban/server/test/costmodel/HKeyUnionCT.java' |
4659 | --- src/test/java/com/akiban/server/test/costmodel/HKeyUnionCT.java 2013-07-08 18:16:50 +0000 |
4660 | +++ src/test/java/com/akiban/server/test/costmodel/HKeyUnionCT.java 2013-07-10 21:47:26 +0000 |
4661 | @@ -124,7 +124,7 @@ |
4662 | long start = System.nanoTime(); |
4663 | for (int r = 0; r < runs; r++) { |
4664 | Cursor cursor = cursor(union, queryContext, queryBindings); |
4665 | - cursor.open(); |
4666 | + cursor.openTopLevel(); |
4667 | while (cursor.next() != null); |
4668 | } |
4669 | long stop = System.nanoTime(); |
4670 | |
4671 | === modified file 'src/test/java/com/akiban/server/test/costmodel/IntersectCT.java' |
4672 | --- src/test/java/com/akiban/server/test/costmodel/IntersectCT.java 2013-07-08 18:16:50 +0000 |
4673 | +++ src/test/java/com/akiban/server/test/costmodel/IntersectCT.java 2013-07-10 21:47:26 +0000 |
4674 | @@ -126,7 +126,7 @@ |
4675 | long start = System.nanoTime(); |
4676 | for (int r = 0; r < runs; r++) { |
4677 | Cursor cursor = cursor(intersect, queryContext, queryBindings); |
4678 | - cursor.open(); |
4679 | + cursor.openTopLevel(); |
4680 | while (cursor.next() != null); |
4681 | } |
4682 | long stop = System.nanoTime(); |
4683 | |
4684 | === modified file 'src/test/java/com/akiban/server/test/costmodel/MapCT.java' |
4685 | --- src/test/java/com/akiban/server/test/costmodel/MapCT.java 2013-07-08 18:16:50 +0000 |
4686 | +++ src/test/java/com/akiban/server/test/costmodel/MapCT.java 2013-07-10 21:47:26 +0000 |
4687 | @@ -87,7 +87,7 @@ |
4688 | long start = System.nanoTime(); |
4689 | for (int r = 0; r < runs; r++) { |
4690 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4691 | - cursor.open(); |
4692 | + cursor.openTopLevel(); |
4693 | while (cursor.next() != null); |
4694 | } |
4695 | long stop = System.nanoTime(); |
4696 | |
4697 | === modified file 'src/test/java/com/akiban/server/test/costmodel/ProductCT.java' |
4698 | --- src/test/java/com/akiban/server/test/costmodel/ProductCT.java 2013-07-08 18:16:50 +0000 |
4699 | +++ src/test/java/com/akiban/server/test/costmodel/ProductCT.java 2013-07-10 21:47:26 +0000 |
4700 | @@ -143,7 +143,7 @@ |
4701 | long start = System.nanoTime(); |
4702 | for (int r = 0; r < runs; r++) { |
4703 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4704 | - cursor.open(); |
4705 | + cursor.openTopLevel(); |
4706 | while (cursor.next() != null); |
4707 | } |
4708 | long stop = System.nanoTime(); |
4709 | @@ -201,7 +201,7 @@ |
4710 | long start = System.nanoTime(); |
4711 | for (int r = 0; r < runs; r++) { |
4712 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4713 | - cursor.open(); |
4714 | + cursor.openTopLevel(); |
4715 | while (cursor.next() != null); |
4716 | } |
4717 | long stop = System.nanoTime(); |
4718 | @@ -217,7 +217,7 @@ |
4719 | private void dump(Operator plan) |
4720 | { |
4721 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4722 | - cursor.open(); |
4723 | + cursor.openTopLevel(); |
4724 | Row row; |
4725 | while ((row = cursor.next()) != null) { |
4726 | System.out.println(row); |
4727 | |
4728 | === modified file 'src/test/java/com/akiban/server/test/costmodel/ProjectCT.java' |
4729 | --- src/test/java/com/akiban/server/test/costmodel/ProjectCT.java 2013-07-08 18:16:50 +0000 |
4730 | +++ src/test/java/com/akiban/server/test/costmodel/ProjectCT.java 2013-07-10 21:47:26 +0000 |
4731 | @@ -72,7 +72,7 @@ |
4732 | long start = System.nanoTime(); |
4733 | for (int r = 0; r < runs; r++) { |
4734 | Cursor cursor = cursor(project, queryContext, queryBindings); |
4735 | - cursor.open(); |
4736 | + cursor.openTopLevel(); |
4737 | while (cursor.next() != null); |
4738 | } |
4739 | long stop = System.nanoTime(); |
4740 | |
4741 | === modified file 'src/test/java/com/akiban/server/test/costmodel/SelectCT.java' |
4742 | --- src/test/java/com/akiban/server/test/costmodel/SelectCT.java 2013-07-08 18:16:50 +0000 |
4743 | +++ src/test/java/com/akiban/server/test/costmodel/SelectCT.java 2013-07-10 21:47:26 +0000 |
4744 | @@ -70,7 +70,7 @@ |
4745 | long start = System.nanoTime(); |
4746 | for (int r = 0; r < runs; r++) { |
4747 | Cursor cursor = cursor(select, queryContext, queryBindings); |
4748 | - cursor.open(); |
4749 | + cursor.openTopLevel(); |
4750 | while (cursor.next() != null); |
4751 | } |
4752 | long stop = System.nanoTime(); |
4753 | |
4754 | === modified file 'src/test/java/com/akiban/server/test/costmodel/Select_BloomFilterCT.java' |
4755 | --- src/test/java/com/akiban/server/test/costmodel/Select_BloomFilterCT.java 2013-07-08 18:16:50 +0000 |
4756 | +++ src/test/java/com/akiban/server/test/costmodel/Select_BloomFilterCT.java 2013-07-10 21:47:26 +0000 |
4757 | @@ -97,7 +97,7 @@ |
4758 | long start = System.nanoTime(); |
4759 | for (int r = 0; r < runs; r++) { |
4760 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4761 | - cursor.open(); |
4762 | + cursor.openTopLevel(); |
4763 | Row row; |
4764 | while ((row = cursor.next()) != null) { |
4765 | // System.out.println(row); |
4766 | |
4767 | === modified file 'src/test/java/com/akiban/server/test/costmodel/SortCT.java' |
4768 | --- src/test/java/com/akiban/server/test/costmodel/SortCT.java 2013-07-08 18:16:50 +0000 |
4769 | +++ src/test/java/com/akiban/server/test/costmodel/SortCT.java 2013-07-10 21:47:26 +0000 |
4770 | @@ -161,7 +161,7 @@ |
4771 | start = System.nanoTime(); |
4772 | for (int r = 0; r < runs; r++) { |
4773 | Cursor cursor = cursor(setup, queryContext, queryBindings); |
4774 | - cursor.open(); |
4775 | + cursor.openTopLevel(); |
4776 | while (cursor.next() != null); |
4777 | } |
4778 | stop = System.nanoTime(); |
4779 | @@ -170,7 +170,7 @@ |
4780 | start = System.nanoTime(); |
4781 | for (int r = 0; r < runs; r++) { |
4782 | Cursor cursor = cursor(sort, queryContext, queryBindings); |
4783 | - cursor.open(); |
4784 | + cursor.openTopLevel(); |
4785 | while (cursor.next() != null); |
4786 | } |
4787 | stop = System.nanoTime(); |
4788 | |
4789 | === modified file 'src/test/java/com/akiban/server/test/costmodel/SortWithLimitCT.java' |
4790 | --- src/test/java/com/akiban/server/test/costmodel/SortWithLimitCT.java 2013-07-08 18:16:50 +0000 |
4791 | +++ src/test/java/com/akiban/server/test/costmodel/SortWithLimitCT.java 2013-07-10 21:47:26 +0000 |
4792 | @@ -107,7 +107,7 @@ |
4793 | long start = System.nanoTime(); |
4794 | for (int r = 0; r < runs; r++) { |
4795 | Cursor cursor = cursor(sort, queryContext, queryBindings); |
4796 | - cursor.open(); |
4797 | + cursor.openTopLevel(); |
4798 | while (cursor.next() != null); |
4799 | } |
4800 | long stop = System.nanoTime(); |
4801 | |
4802 | === modified file 'src/test/java/com/akiban/server/test/costmodel/TreeScanCT.java' |
4803 | --- src/test/java/com/akiban/server/test/costmodel/TreeScanCT.java 2013-07-08 18:16:50 +0000 |
4804 | +++ src/test/java/com/akiban/server/test/costmodel/TreeScanCT.java 2013-07-10 21:47:26 +0000 |
4805 | @@ -135,7 +135,7 @@ |
4806 | long start = System.nanoTime(); |
4807 | for (int r = 0; r < runs; r++) { |
4808 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4809 | - cursor.open(); |
4810 | + cursor.openTopLevel(); |
4811 | for (int s = 0; s < sequentialAccessesPerRandom; s++) { |
4812 | Row row = cursor.next(); |
4813 | assert row != null; |
4814 | @@ -170,10 +170,10 @@ |
4815 | } else { |
4816 | valueHolder.putString((String) key); |
4817 | } |
4818 | - cursor.open(); |
4819 | + cursor.openTopLevel(); |
4820 | Row row = cursor.next(); |
4821 | assert row != null; |
4822 | - cursor.close(); |
4823 | + cursor.closeTopLevel(); |
4824 | } |
4825 | } |
4826 | long endTime = System.nanoTime(); |
4827 | |
4828 | === modified file 'src/test/java/com/akiban/server/test/it/ITBase.java' |
4829 | --- src/test/java/com/akiban/server/test/it/ITBase.java 2013-03-22 20:05:57 +0000 |
4830 | +++ src/test/java/com/akiban/server/test/it/ITBase.java 2013-07-10 21:47:26 +0000 |
4831 | @@ -21,6 +21,7 @@ |
4832 | import com.akiban.ais.model.TableIndex; |
4833 | import com.akiban.ais.model.UserTable; |
4834 | import com.akiban.qp.operator.Cursor; |
4835 | +import com.akiban.qp.operator.RowCursor; |
4836 | import com.akiban.qp.row.Row; |
4837 | import com.akiban.qp.row.RowBase; |
4838 | import com.akiban.qp.rowtype.IndexRowType; |
4839 | @@ -51,16 +52,24 @@ |
4840 | super(suffix); |
4841 | } |
4842 | |
4843 | - protected void compareRows(RowBase[] expected, Cursor cursor) |
4844 | - { |
4845 | - compareRows(expected, cursor, null); |
4846 | - } |
4847 | - |
4848 | - protected void compareRows(RowBase[] expected, Cursor cursor, AkCollator ... collators) |
4849 | + protected void compareRows(RowBase[] expected, RowCursor cursor) |
4850 | + { |
4851 | + compareRows(expected, cursor, (cursor instanceof Cursor), null); |
4852 | + } |
4853 | + |
4854 | + protected void compareRows(RowBase[] expected, RowCursor cursor, AkCollator ... collators) |
4855 | + { |
4856 | + compareRows(expected, cursor, (cursor instanceof Cursor), collators); |
4857 | + } |
4858 | + |
4859 | + protected void compareRows(RowBase[] expected, RowCursor cursor, boolean topLevel, AkCollator ... collators) |
4860 | { |
4861 | List<ShareHolder<Row>> actualRows = new ArrayList<>(); // So that result is viewable in debugger |
4862 | try { |
4863 | - cursor.open(); |
4864 | + if (topLevel) |
4865 | + ((Cursor)cursor).openTopLevel(); |
4866 | + else |
4867 | + cursor.open(); |
4868 | RowBase actualRow; |
4869 | while ((actualRow = cursor.next()) != null) { |
4870 | int count = actualRows.size(); |
4871 | @@ -80,7 +89,10 @@ |
4872 | actualRows.add(new ShareHolder<>((Row) actualRow)); |
4873 | } |
4874 | } finally { |
4875 | - cursor.close(); |
4876 | + if (topLevel) |
4877 | + ((Cursor)cursor).closeTopLevel(); |
4878 | + else |
4879 | + cursor.close(); |
4880 | } |
4881 | assertEquals(expected.length, actualRows.size()); |
4882 | } |
4883 | |
4884 | === modified file 'src/test/java/com/akiban/server/test/it/qp/GroupIndexScanIT.java' |
4885 | --- src/test/java/com/akiban/server/test/it/qp/GroupIndexScanIT.java 2013-07-08 18:16:50 +0000 |
4886 | +++ src/test/java/com/akiban/server/test/it/qp/GroupIndexScanIT.java 2013-07-10 21:47:26 +0000 |
4887 | @@ -133,7 +133,7 @@ |
4888 | private List<List<?>> planToList(Operator plan) { |
4889 | List<List<?>> actualResults = new ArrayList<>(); |
4890 | Cursor cursor = API.cursor(plan, queryContext, queryBindings); |
4891 | - cursor.open(); |
4892 | + cursor.openTopLevel(); |
4893 | try { |
4894 | ToObjectValueTarget target = new ToObjectValueTarget(); |
4895 | for (Row row = cursor.next(); row != null; row = cursor.next()) { |
4896 | @@ -157,7 +157,7 @@ |
4897 | actualResults.add(Arrays.asList(rowArray)); |
4898 | } |
4899 | } finally { |
4900 | - cursor.close(); |
4901 | + cursor.closeTopLevel(); |
4902 | } |
4903 | return actualResults; |
4904 | } |
4905 | |
4906 | === modified file 'src/test/java/com/akiban/server/test/it/qp/GroupScanIT.java' |
4907 | --- src/test/java/com/akiban/server/test/it/qp/GroupScanIT.java 2013-07-08 18:16:50 +0000 |
4908 | +++ src/test/java/com/akiban/server/test/it/qp/GroupScanIT.java 2013-07-10 21:47:26 +0000 |
4909 | @@ -140,7 +140,7 @@ |
4910 | use(db); |
4911 | Operator groupScan = groupScan_Default(coi); |
4912 | Cursor cursor = cursor(groupScan, queryContext, queryBindings); |
4913 | - cursor.open(); |
4914 | + cursor.openTopLevel(); |
4915 | Row row = cursor.next(); |
4916 | assertSame(customerRowType, row.rowType()); |
4917 | row = cursor.next(); |
4918 | |
4919 | === modified file 'src/test/java/com/akiban/server/test/it/qp/IndexScanIT.java' |
4920 | --- src/test/java/com/akiban/server/test/it/qp/IndexScanIT.java 2013-07-08 18:16:50 +0000 |
4921 | +++ src/test/java/com/akiban/server/test/it/qp/IndexScanIT.java 2013-07-10 21:47:26 +0000 |
4922 | @@ -550,7 +550,7 @@ |
4923 | { |
4924 | Operator indexScan = indexScan_Default(itemOidIidIndexRowType, false, null); |
4925 | Cursor cursor = cursor(indexScan, queryContext, queryBindings); |
4926 | - cursor.open(); |
4927 | + cursor.openTopLevel(); |
4928 | Row row = cursor.next(); |
4929 | if (usingPValues()) { |
4930 | // Get and checking each field should work |
4931 | |
4932 | === modified file 'src/test/java/com/akiban/server/test/it/qp/IndexScanJumpBoundedIT.java' |
4933 | --- src/test/java/com/akiban/server/test/it/qp/IndexScanJumpBoundedIT.java 2013-07-08 20:48:05 +0000 |
4934 | +++ src/test/java/com/akiban/server/test/it/qp/IndexScanJumpBoundedIT.java 2013-07-10 21:47:26 +0000 |
4935 | @@ -88,34 +88,34 @@ |
4936 | { |
4937 | Operator plan = indexScan_Default(idxRowType, bounded(1, 11, true, 13, true), ordering); |
4938 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4939 | - cursor.open(); |
4940 | + cursor.openTopLevel(); |
4941 | testJump(cursor, idOrdering, 0); |
4942 | testJump(cursor, idOrdering, -1); |
4943 | - cursor.close(); |
4944 | + cursor.closeTopLevel(); |
4945 | } |
4946 | { |
4947 | Operator plan = indexScan_Default(idxRowType, bounded(1, 11, true, 13, false), ordering); |
4948 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4949 | - cursor.open(); |
4950 | + cursor.openTopLevel(); |
4951 | testJump(cursor, first4(idOrdering), 0); |
4952 | testJump(cursor, first4(idOrdering), -1); |
4953 | - cursor.close(); |
4954 | + cursor.closeTopLevel(); |
4955 | } |
4956 | { |
4957 | Operator plan = indexScan_Default(idxRowType, bounded(1, 11, false, 13, true), ordering); |
4958 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4959 | - cursor.open(); |
4960 | + cursor.openTopLevel(); |
4961 | testJump(cursor, last4(idOrdering), 0); |
4962 | testJump(cursor, last4(idOrdering), -1); |
4963 | - cursor.close(); |
4964 | + cursor.closeTopLevel(); |
4965 | } |
4966 | { |
4967 | Operator plan = indexScan_Default(idxRowType, bounded(1, 11, false, 13, false), ordering); |
4968 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4969 | - cursor.open(); |
4970 | + cursor.openTopLevel(); |
4971 | testJump(cursor, middle2(idOrdering), 0); |
4972 | testJump(cursor, middle2(idOrdering), -1); |
4973 | - cursor.close(); |
4974 | + cursor.closeTopLevel(); |
4975 | } |
4976 | } |
4977 | |
4978 | @@ -127,34 +127,34 @@ |
4979 | { |
4980 | Operator plan = indexScan_Default(idxRowType, bounded(1, 11, true, 13, true), ordering); |
4981 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4982 | - cursor.open(); |
4983 | + cursor.openTopLevel(); |
4984 | testJump(cursor, idOrdering, 0); |
4985 | testJump(cursor, idOrdering, 1); |
4986 | - cursor.close(); |
4987 | + cursor.closeTopLevel(); |
4988 | } |
4989 | { |
4990 | Operator plan = indexScan_Default(idxRowType, bounded(1, 11, true, 13, false), ordering); |
4991 | Cursor cursor = cursor(plan, queryContext, queryBindings); |
4992 | - cursor.open(); |
4993 | + cursor.openTopLevel(); |
4994 | testJump(cursor, first4(idOrdering), 0); |
4995 | testJump(cursor, first4(idOrdering), 1); |
4996 | - cursor.close(); |
4997 | + cursor.closeTopLevel(); |
4998 | } |
4999 | { |
5000 | Operator plan = indexScan_Default(idxRowType, bounded(1, 11, false, 13, true), ordering); |
Sounds, and looks, like previously discussed.
I don't have a suggestion for open vs openTopLevel at the moment and it doesn't look to objectionable from the diff. Perhaps something will come to us later.