Merge lp:~davidagraf/zorba/paging_with_refs into lp:zorba
- paging_with_refs
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | David Graf |
Approved revision: | 10996 |
Merged at revision: | 11037 |
Proposed branch: | lp:~davidagraf/zorba/paging_with_refs |
Merge into: | lp:zorba |
Diff against target: |
697 lines (+278/-53) 27 files modified
include/zorba/pregenerated/diagnostic_list.h (+2/-0) modules/com/zorba-xquery/www/modules/pregenerated/errors.xq (+4/-0) modules/com/zorba-xquery/www/modules/store/dynamic/collections/dml.xq (+29/-0) modules/com/zorba-xquery/www/modules/store/static/collections/dml.xq (+27/-0) src/diagnostics/diagnostic_en.xml (+4/-0) src/diagnostics/pregenerated/diagnostic_list.cpp (+3/-0) src/diagnostics/pregenerated/dict_en.cpp (+1/-0) src/functions/func_sequences_impl.cpp (+13/-10) src/functions/pregenerated/func_collections.cpp (+28/-0) src/functions/pregenerated/function_enum.h (+2/-0) src/runtime/collections/collections_impl.cpp (+41/-13) src/runtime/collections/pregenerated/collections.h (+2/-0) src/runtime/spec/collections/collections.xml (+27/-7) src/store/api/collection.h (+4/-2) src/store/naive/collection.h (+3/-1) src/store/naive/simple_collection.cpp (+32/-4) src/store/naive/simple_collection.h (+6/-2) test/rbkt/ExpQueryResults/zorba/collections/paging_1.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/collections/paging_2.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/collections/paging_3.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/collections/paging_4.xml.res (+1/-1) test/rbkt/Queries/zorba/collections/paging_1.xq (+12/-3) test/rbkt/Queries/zorba/collections/paging_2.xq (+4/-2) test/rbkt/Queries/zorba/collections/paging_3.xq (+5/-3) test/rbkt/Queries/zorba/collections/paging_4.xq (+4/-2) test/rbkt/Queries/zorba/collections/paging_5.spec (+1/-0) test/rbkt/Queries/zorba/collections/paging_5.xq (+20/-0) |
To merge this branch: | bzr merge lp:~davidagraf/zorba/paging_with_refs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Matthias Brantner | Approve | ||
Till Westmann | Approve | ||
Review via email: mp+123509@code.launchpad.net |
This proposal supersedes a proposal from 2012-08-14.
Commit message
feature: skipping nodes in a collection using a node-reference
Description of the change
Resubmit to trigger patchqueue.
Matthias Brantner (matthias-brantner) wrote : Posted in a previous version of this proposal | # |
David Graf (davidagraf) wrote : Posted in a previous version of this proposal | # |
> - Given the documentation, I was not able to figure out why the collection
> function takes the $start and $skip parameters. Is one of the ignored if
> the other one is given? Does skipping start at the item identified by
> $start? If so, would it make sense to separate the two ways of skipping
> into separate functions?
No, none is ignored. If you don't wanna skip, you pass 0. If you wanna skip only, you use db:collection(
But as already mentioned in a yammer message, I am thinking about replacing the $skip parameter with an optimisation for fn:subsequence(
>
Fixed everything below:
> - improved
> The reference to first node to return
> =>
> A reference to the first node to return.
>
> - What does "order is implementation dependent" mean for ordered collections?
>
> - Error message can be improved according to Paul's style:
>
> Node reference $1 doesn't reference a node in collection $2
> =>
> $1: doesn't reference a node in collection ($2)
>
> - typo:
> if the passed reference $start doesn't reference
> a _not_ from the collection identified by $name.
>
> - the documentation mention zerr:ZAPI0028 if the given URI
> is not a valid node reference
Till Westmann (tillw) wrote : Posted in a previous version of this proposal | # |
There are a few small fixes that I've sent as a patch via email as I could not push them into this branch. Once this patch is applied this branch works for me.
Matthias Brantner (matthias-brantner) wrote : Posted in a previous version of this proposal | # |
The patch looks great.
As far as I can tell, the documentation should also mention the error zerr:ZAPI0028.
David Graf (davidagraf) wrote : Posted in a previous version of this proposal | # |
> There are a few small fixes that I've sent as a patch via email as I could not
> push them into this branch. Once this patch is applied this branch works for
> me.
I patched you patch. Unfortunately, I needed to do it by hand. Did you create the patch with bzr diff?
David Graf (davidagraf) wrote : Posted in a previous version of this proposal | # |
> The patch looks great.
>
> As far as I can tell, the documentation should also mention the error
> zerr:ZAPI0028.
done
Till Westmann (tillw) : Posted in a previous version of this proposal | # |
Matthias Brantner (matthias-brantner) : Posted in a previous version of this proposal | # |
Till Westmann (tillw) : | # |
Matthias Brantner (matthias-brantner) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~davidagraf/zorba/paging_with_refs into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job paging_
The final status was:
2 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~davidagraf/zorba/paging_with_refs into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job paging_
The final status was:
1 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job paging_
All tests succeeded!
Preview Diff
1 | === modified file 'include/zorba/pregenerated/diagnostic_list.h' |
2 | --- include/zorba/pregenerated/diagnostic_list.h 2012-09-12 08:06:26 +0000 |
3 | +++ include/zorba/pregenerated/diagnostic_list.h 2012-09-12 11:09:20 +0000 |
4 | @@ -750,6 +750,8 @@ |
5 | |
6 | extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZSTR0065_STRINGS_IN_POOL; |
7 | |
8 | +extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZSTR0066_REFERENCED_NODE_NOT_IN_COLLECTION; |
9 | + |
10 | extern ZORBA_DLL_PUBLIC ZorbaErrorCode XSST0001; |
11 | |
12 | extern ZORBA_DLL_PUBLIC ZorbaErrorCode XSST0002; |
13 | |
14 | === modified file 'modules/com/zorba-xquery/www/modules/pregenerated/errors.xq' |
15 | --- modules/com/zorba-xquery/www/modules/pregenerated/errors.xq 2012-09-10 22:53:04 +0000 |
16 | +++ modules/com/zorba-xquery/www/modules/pregenerated/errors.xq 2012-09-12 11:09:20 +0000 |
17 | @@ -781,6 +781,10 @@ |
18 | |
19 | (:~ |
20 | :) |
21 | +declare variable $zerr:ZSTR0066 as xs:QName := fn:QName($zerr:NS, "zerr:ZSTR0066"); |
22 | + |
23 | +(:~ |
24 | +:) |
25 | declare variable $zerr:XSST0001 as xs:QName := fn:QName($zerr:NS, "zerr:XSST0001"); |
26 | |
27 | (:~ |
28 | |
29 | === modified file 'modules/com/zorba-xquery/www/modules/store/dynamic/collections/dml.xq' |
30 | --- modules/com/zorba-xquery/www/modules/store/dynamic/collections/dml.xq 2012-09-10 22:53:04 +0000 |
31 | +++ modules/com/zorba-xquery/www/modules/store/dynamic/collections/dml.xq 2012-09-12 11:09:20 +0000 |
32 | @@ -632,6 +632,35 @@ |
33 | |
34 | |
35 | (:~ |
36 | + : The collection function returns the sequence of nodes and/or json items |
37 | + : that belong to the collection identified by the given name. |
38 | + : The parameters $start and $skip can be used to skip over some items at |
39 | + : the beginning of the collection. If both are given, both are applied: |
40 | + : first $start to skip to the referenced item and then $skip to skip an |
41 | + : additional number of items. |
42 | + : |
43 | + : @param $name The name of the collection. |
44 | + : @param $start A reference to the first item to return. All items before |
45 | + are skipped. |
46 | + : @param $skip The number of collection items to skip. |
47 | + : |
48 | + : @return The sequence contained in the given collection. |
49 | + : |
50 | + : @error zerr:ZAPI0028 If the given URI is not a valid node |
51 | + : position computed by the <tt>np:node-position</tt> function. |
52 | + : @error zerr:ZDDY0003 If available collections does not provide a mapping |
53 | + : for the expanded QName $name. |
54 | + : @error zerr:ZSTR0066 If the passed reference $start does not reference |
55 | + : a node from the collection identified by $name. |
56 | + : |
57 | + :) |
58 | +declare function |
59 | +dml:collection($name as xs:QName, |
60 | + $start as xs:anyURI, |
61 | + $skip as xs:integer) as item()* external; |
62 | + |
63 | + |
64 | +(:~ |
65 | : The collection-name function returns the name of the collection the given |
66 | : item (node or json item) belongs to. |
67 | : |
68 | |
69 | === modified file 'modules/com/zorba-xquery/www/modules/store/static/collections/dml.xq' |
70 | --- modules/com/zorba-xquery/www/modules/store/static/collections/dml.xq 2012-09-10 22:53:04 +0000 |
71 | +++ modules/com/zorba-xquery/www/modules/store/static/collections/dml.xq 2012-09-12 11:09:20 +0000 |
72 | @@ -884,6 +884,33 @@ |
73 | |
74 | |
75 | (:~ |
76 | + : The collection function returns the sequence of nodes and/or json items |
77 | + : that belong to the collection identified by the given name. |
78 | + : The parameters $start and $skip can be used to skip over some items at |
79 | + : the beginning of the collection. If both are given, both are applied: |
80 | + : first $start to skip to the referenced item and then $skip to skip an |
81 | + : additional number of items. |
82 | + : |
83 | + : @param $name The name of the collection. |
84 | + : @param $start The reference to the first item to return. All items before |
85 | + are skipped. |
86 | + : @param $skip The number of collection items to skip. |
87 | + : |
88 | + : @return The sequence contained in the given collection. |
89 | + : |
90 | + : @error zerr:ZAPI0028 If the given URI is not a valid node |
91 | + : position computed by the <tt>np:node-position</tt> function. |
92 | + : @error zerr:ZDDY0001 if the collection identified by $name is not declared. |
93 | + : @error zerr:ZDDY0003 if the collection identified by $name is not available. |
94 | + : @error zerr:ZSTR0066 if the passed reference $start does not reference |
95 | + : a node from the collection identified by $name. |
96 | + : |
97 | + :) |
98 | +declare function |
99 | +cdml:collection($name as xs:QName, |
100 | + $start as xs:anyURI, |
101 | + $skip as xs:integer) as item()* external; |
102 | +(:~ |
103 | : The collection-name function returns the name of the collection the given |
104 | : item (node or json item) belongs to. |
105 | : |
106 | |
107 | === modified file 'src/diagnostics/diagnostic_en.xml' |
108 | --- src/diagnostics/diagnostic_en.xml 2012-09-12 08:06:26 +0000 |
109 | +++ src/diagnostics/diagnostic_en.xml 2012-09-12 11:09:20 +0000 |
110 | @@ -2433,6 +2433,10 @@ |
111 | <value>Zorba did not close properly, objects may still in memory.\n$1 referenced URI(s) remain in the string pool.\nFor help avoiding this message please refer to http://www.zorba-xquery.com/html/documentation in section General Architecture -> Memory Leaks.</value> |
112 | </diagnostic> |
113 | |
114 | + <diagnostic code="ZSTR0066" name="REFERENCED_NODE_NOT_IN_COLLECTION"> |
115 | + <value>$1: does not reference a node in collection $2.</value> |
116 | + </diagnostic> |
117 | + |
118 | <!--////////// XQuery Scripting ////////////////////////////////////////--> |
119 | |
120 | <diagnostic code="XSST0001"> |
121 | |
122 | === modified file 'src/diagnostics/pregenerated/diagnostic_list.cpp' |
123 | --- src/diagnostics/pregenerated/diagnostic_list.cpp 2012-09-12 08:06:26 +0000 |
124 | +++ src/diagnostics/pregenerated/diagnostic_list.cpp 2012-09-12 11:09:20 +0000 |
125 | @@ -1103,6 +1103,9 @@ |
126 | ZorbaErrorCode ZSTR0065_STRINGS_IN_POOL( "ZSTR0065" ); |
127 | |
128 | |
129 | +ZorbaErrorCode ZSTR0066_REFERENCED_NODE_NOT_IN_COLLECTION( "ZSTR0066" ); |
130 | + |
131 | + |
132 | ZorbaErrorCode XSST0001( "XSST0001" ); |
133 | |
134 | |
135 | |
136 | === modified file 'src/diagnostics/pregenerated/dict_en.cpp' |
137 | --- src/diagnostics/pregenerated/dict_en.cpp 2012-09-12 08:06:26 +0000 |
138 | +++ src/diagnostics/pregenerated/dict_en.cpp 2012-09-12 11:09:20 +0000 |
139 | @@ -453,6 +453,7 @@ |
140 | { "ZSTR0055", "streamable string has already been consumed" }, |
141 | { "ZSTR0060", "out of range: $1" }, |
142 | { "ZSTR0065", "Zorba did not close properly, objects may still in memory.\n$1 referenced URI(s) remain in the string pool.\nFor help avoiding this message please refer to http://www.zorba-xquery.com/html/documentation in section General Architecture -> Memory Leaks." }, |
143 | + { "ZSTR0066", "$1: does not reference a node in collection $2." }, |
144 | { "ZWST0002", "\"$1\": unknown or unsupported annotation" }, |
145 | { "ZWST0003", "\"$1\": function declared sequential, but has non-sequential body" }, |
146 | { "ZWST0004", "Sequential FLWOR expr may not have the semantics you expect" }, |
147 | |
148 | === modified file 'src/functions/func_sequences_impl.cpp' |
149 | --- src/functions/func_sequences_impl.cpp 2012-09-10 22:53:04 +0000 |
150 | +++ src/functions/func_sequences_impl.cpp 2012-09-12 11:09:20 +0000 |
151 | @@ -543,16 +543,19 @@ |
152 | ZorbaCollectionIterator& collection = |
153 | static_cast<ZorbaCollectionIterator&>(*argv[0]); |
154 | |
155 | - return new CountCollectionIterator( |
156 | - sctx, |
157 | - loc, |
158 | - collection.getChildren(), |
159 | - ( |
160 | - collection.isDynamic() |
161 | - ? CountCollectionIterator::ZORBADYNAMIC |
162 | - : CountCollectionIterator::ZORBASTATIC |
163 | - ) |
164 | - ); |
165 | + if (collection.isCountOptimizable()) |
166 | + { |
167 | + return new CountCollectionIterator( |
168 | + sctx, |
169 | + loc, |
170 | + collection.getChildren(), |
171 | + ( |
172 | + collection.isDynamic() |
173 | + ? CountCollectionIterator::ZORBADYNAMIC |
174 | + : CountCollectionIterator::ZORBASTATIC |
175 | + ) |
176 | + ); |
177 | + } |
178 | } |
179 | else if (typeid(FnCollectionIterator) == counted_type) |
180 | { |
181 | |
182 | === modified file 'src/functions/pregenerated/func_collections.cpp' |
183 | --- src/functions/pregenerated/func_collections.cpp 2012-09-10 22:53:04 +0000 |
184 | +++ src/functions/pregenerated/func_collections.cpp 2012-09-12 11:09:20 +0000 |
185 | @@ -355,6 +355,20 @@ |
186 | |
187 | { |
188 | DECL_WITH_KIND(sctx, static_collections_dml_collection, |
189 | + (createQName("http://www.zorba-xquery.com/modules/store/static/collections/dml","","collection"), |
190 | + GENV_TYPESYSTEM.QNAME_TYPE_ONE, |
191 | + GENV_TYPESYSTEM.ANY_URI_TYPE_ONE, |
192 | + GENV_TYPESYSTEM.INTEGER_TYPE_ONE, |
193 | + GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_STAR), |
194 | + FunctionConsts::STATIC_COLLECTIONS_DML_COLLECTION_3); |
195 | + |
196 | + } |
197 | + |
198 | + |
199 | + |
200 | + |
201 | + { |
202 | + DECL_WITH_KIND(sctx, static_collections_dml_collection, |
203 | (createQName("http://www.zorba-xquery.com/modules/store/dynamic/collections/dml","","collection"), |
204 | GENV_TYPESYSTEM.QNAME_TYPE_ONE, |
205 | GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_STAR), |
206 | @@ -379,6 +393,20 @@ |
207 | |
208 | |
209 | { |
210 | + DECL_WITH_KIND(sctx, static_collections_dml_collection, |
211 | + (createQName("http://www.zorba-xquery.com/modules/store/dynamic/collections/dml","","collection"), |
212 | + GENV_TYPESYSTEM.QNAME_TYPE_ONE, |
213 | + GENV_TYPESYSTEM.ANY_URI_TYPE_ONE, |
214 | + GENV_TYPESYSTEM.INTEGER_TYPE_ONE, |
215 | + GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_STAR), |
216 | + FunctionConsts::DYNAMIC_COLLECTIONS_DML_COLLECTION_3); |
217 | + |
218 | + } |
219 | + |
220 | + |
221 | + |
222 | + |
223 | + { |
224 | DECL_WITH_KIND(sctx, static_collections_dml_collection_name, |
225 | (createQName("http://www.zorba-xquery.com/modules/store/static/collections/dml","","collection-name"), |
226 | GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_ONE, |
227 | |
228 | === modified file 'src/functions/pregenerated/function_enum.h' |
229 | --- src/functions/pregenerated/function_enum.h 2012-09-11 16:33:21 +0000 |
230 | +++ src/functions/pregenerated/function_enum.h 2012-09-12 11:09:20 +0000 |
231 | @@ -55,8 +55,10 @@ |
232 | FN_COLLECTION_1, |
233 | STATIC_COLLECTIONS_DML_COLLECTION_1, |
234 | STATIC_COLLECTIONS_DML_COLLECTION_2, |
235 | + STATIC_COLLECTIONS_DML_COLLECTION_3, |
236 | DYNAMIC_COLLECTIONS_DML_COLLECTION_1, |
237 | DYNAMIC_COLLECTIONS_DML_COLLECTION_2, |
238 | + DYNAMIC_COLLECTIONS_DML_COLLECTION_3, |
239 | STATIC_COLLECTIONS_DML_COLLECTION_NAME_1, |
240 | DYNAMIC_COLLECTIONS_DML_COLLECTION_NAME_1, |
241 | STATIC_COLLECTIONS_DML_INDEX_OF_1, |
242 | |
243 | === modified file 'src/runtime/collections/collections_impl.cpp' |
244 | --- src/runtime/collections/collections_impl.cpp 2012-09-10 22:53:04 +0000 |
245 | +++ src/runtime/collections/collections_impl.cpp 2012-09-12 11:09:20 +0000 |
246 | @@ -367,6 +367,12 @@ |
247 | } |
248 | } |
249 | |
250 | +bool ZorbaCollectionIterator::isCountOptimizable() const |
251 | +{ |
252 | + // if ref is passed to the collections function, count cannot be |
253 | + // optimized anymore. |
254 | + return theChildren.size() <= 2; |
255 | +} |
256 | |
257 | bool ZorbaCollectionIterator::nextImpl( |
258 | store::Item_t& result, |
259 | @@ -375,6 +381,7 @@ |
260 | store::Item_t name; |
261 | store::Collection_t collection; |
262 | xs_integer lSkip; |
263 | + zstring lStart; |
264 | |
265 | ZorbaCollectionIteratorState* state; |
266 | DEFAULT_STACK_INIT(ZorbaCollectionIteratorState, state, planState); |
267 | @@ -383,21 +390,42 @@ |
268 | |
269 | (void)getCollection(theSctx, name, loc, theIsDynamic, collection); |
270 | |
271 | - if (theChildren.size() > 1) |
272 | - { |
273 | - // skip parameter passed |
274 | + if (theChildren.size() == 1) |
275 | + { |
276 | + state->theIterator = collection->getIterator(); |
277 | + } |
278 | + else |
279 | + { |
280 | + bool lRefPassed = theChildren.size() >= 3; |
281 | + |
282 | + // read positional skip parameter |
283 | store::Item_t lSkipItem; |
284 | - consumeNext(lSkipItem, theChildren[1].getp(), planState); |
285 | + consumeNext(lSkipItem, theChildren[(lRefPassed ? 2 : 1)].getp(), planState); |
286 | lSkip = lSkipItem->getIntegerValue(); |
287 | - // negative is transformed into 0 |
288 | - state->theIterator = ( lSkip > xs_integer::zero() |
289 | - ? collection->getIterator(lSkip) |
290 | - : collection->getIterator() |
291 | - ); |
292 | - } |
293 | - else |
294 | - { |
295 | - state->theIterator = collection->getIterator(); |
296 | + // negative skip is not allowed |
297 | + if (lSkip < xs_integer::zero()) |
298 | + { |
299 | + lSkip = xs_integer::zero(); |
300 | + } |
301 | + if (!lRefPassed) |
302 | + { |
303 | + state->theIterator = collection->getIterator(lSkip); |
304 | + } |
305 | + else |
306 | + { |
307 | + store::Item_t lRefItem; |
308 | + consumeNext(lRefItem, theChildren[1].getp(), planState); |
309 | + lStart = lRefItem->getString(); |
310 | + try |
311 | + { |
312 | + state->theIterator = collection->getIterator(lSkip, lStart); |
313 | + } |
314 | + catch (ZorbaException& e) |
315 | + { |
316 | + set_source(e, loc); |
317 | + throw; |
318 | + } |
319 | + } |
320 | } |
321 | |
322 | ZORBA_ASSERT(state->theIterator != NULL); |
323 | |
324 | === modified file 'src/runtime/collections/pregenerated/collections.h' |
325 | --- src/runtime/collections/pregenerated/collections.h 2012-09-10 22:53:04 +0000 |
326 | +++ src/runtime/collections/pregenerated/collections.h 2012-09-12 11:09:20 +0000 |
327 | @@ -285,6 +285,8 @@ |
328 | |
329 | bool isDynamic() const { return theIsDynamic; } |
330 | |
331 | +public: |
332 | + bool isCountOptimizable() const; |
333 | void accept(PlanIterVisitor& v) const; |
334 | |
335 | bool nextImpl(store::Item_t& result, PlanState& aPlanState) const; |
336 | |
337 | === modified file 'src/runtime/spec/collections/collections.xml' |
338 | --- src/runtime/spec/collections/collections.xml 2012-09-10 22:53:04 +0000 |
339 | +++ src/runtime/spec/collections/collections.xml 2012-09-12 11:09:20 +0000 |
340 | @@ -255,13 +255,29 @@ |
341 | <zorba:output>structured-item()*</zorba:output> |
342 | </zorba:signature> |
343 | |
344 | - <zorba:signature localname="collection" prefix="dynamic-collections-dml"> |
345 | - <zorba:param>xs:QName</zorba:param> |
346 | - <zorba:output>structured-item()*</zorba:output> |
347 | - </zorba:signature> |
348 | - |
349 | - <zorba:signature localname="collection" prefix="dynamic-collections-dml"> |
350 | - <zorba:param>xs:QName</zorba:param> |
351 | + <zorba:signature localname="collection" |
352 | + prefix="static-collections-dml"> |
353 | + <zorba:param>xs:QName</zorba:param> |
354 | + <zorba:param>xs:anyURI</zorba:param><!-- start ref --> |
355 | + <zorba:param>xs:integer</zorba:param><!-- nodes to skip --> |
356 | + <zorba:output>structured-item()*</zorba:output> |
357 | + </zorba:signature> |
358 | + |
359 | + <zorba:signature localname="collection" prefix="dynamic-collections-dml"> |
360 | + <zorba:param>xs:QName</zorba:param> |
361 | + <zorba:output>structured-item()*</zorba:output> |
362 | + </zorba:signature> |
363 | + |
364 | + <zorba:signature localname="collection" prefix="dynamic-collections-dml"> |
365 | + <zorba:param>xs:QName</zorba:param> |
366 | + <zorba:param>xs:integer</zorba:param><!-- start to skip --> |
367 | + <zorba:output>structured-item()*</zorba:output> |
368 | + </zorba:signature> |
369 | + |
370 | + <zorba:signature localname="collection" |
371 | + prefix="dynamic-collections-dml"> |
372 | + <zorba:param>xs:QName</zorba:param> |
373 | + <zorba:param>xs:anyURI</zorba:param><!-- node ref--> |
374 | <zorba:param>xs:integer</zorba:param><!-- nodes to skip --> |
375 | <zorba:output>structured-item()*</zorba:output> |
376 | </zorba:signature> |
377 | @@ -281,6 +297,10 @@ |
378 | |
379 | <zorba:member type="bool" name="theIsDynamic" getterName="isDynamic"/> |
380 | |
381 | + <zorba:method const="true" |
382 | + name="isCountOptimizable" |
383 | + return="bool" /> |
384 | + |
385 | <zorba:state generateInit="false" generateReset="false" generateDestructor="false"> |
386 | <zorba:member type="store::Iterator_t" name="theIterator"/> |
387 | <zorba:member type="bool" name="theIteratorOpened" defaultValue="false"/> |
388 | |
389 | === modified file 'src/store/api/collection.h' |
390 | --- src/store/api/collection.h 2012-09-10 22:53:04 +0000 |
391 | +++ src/store/api/collection.h 2012-09-12 11:09:20 +0000 |
392 | @@ -54,11 +54,13 @@ |
393 | * It is allowed to have several concurrent iterators on the same Collection, |
394 | * but each iterator should be used by a single thread only. |
395 | * |
396 | - * @param aSkip The number of collection entries to skip. |
397 | + * @param aSkip The number of collection items to skip. |
398 | + * @param aStart The reference to the first node. All nodes before are skipped. |
399 | * @return Iterator |
400 | */ |
401 | virtual Iterator_t getIterator( |
402 | - const xs_integer& aSkip = xs_integer::zero()) = 0; |
403 | + const xs_integer& aSkip = xs_integer::zero(), |
404 | + const zstring& aStart = "") = 0; |
405 | |
406 | /** |
407 | * Get the node at the given position in the collection. |
408 | |
409 | === modified file 'src/store/naive/collection.h' |
410 | --- src/store/naive/collection.h 2012-09-10 22:53:04 +0000 |
411 | +++ src/store/naive/collection.h 2012-09-12 11:09:20 +0000 |
412 | @@ -54,7 +54,9 @@ |
413 | |
414 | zorba::xs_integer size() const = 0; |
415 | |
416 | - zorba::store::Iterator_t getIterator(const xs_integer& aSkip) = 0; |
417 | + zorba::store::Iterator_t getIterator( |
418 | + const xs_integer& aSkip, |
419 | + const zstring& aStart) = 0; |
420 | |
421 | virtual zorba::store::Item_t nodeAt(xs_integer position) = 0; |
422 | |
423 | |
424 | === modified file 'src/store/naive/simple_collection.cpp' |
425 | --- src/store/naive/simple_collection.cpp 2012-09-10 22:53:04 +0000 |
426 | +++ src/store/naive/simple_collection.cpp 2012-09-12 11:09:20 +0000 |
427 | @@ -81,9 +81,22 @@ |
428 | Note: it is allowed to have several concurrent iterators on the same collection |
429 | but each iterator should be used by a single thread only. |
430 | ********************************************************************************/ |
431 | -store::Iterator_t SimpleCollection::getIterator(const xs_integer& aSkip) |
432 | +store::Iterator_t SimpleCollection::getIterator(const xs_integer& aSkip, |
433 | + const zstring& aStart) |
434 | { |
435 | - return new CollectionIter(this, aSkip); |
436 | + store::Item_t lReferencedNode; |
437 | + xs_integer lReferencedPosition = xs_integer::zero(); |
438 | + if (aStart.size() != 0 |
439 | + && (!GET_STORE().getNodeByReference(lReferencedNode, aStart) |
440 | + || !findNode(lReferencedNode.getp(), lReferencedPosition))) |
441 | + { |
442 | + throw ZORBA_EXCEPTION(zerr::ZSTR0066_REFERENCED_NODE_NOT_IN_COLLECTION, |
443 | + ERROR_PARAMS(aStart, theName->getStringValue())); |
444 | + } |
445 | + |
446 | + return new CollectionIter( |
447 | + this, |
448 | + aSkip + lReferencedPosition); |
449 | } |
450 | |
451 | |
452 | @@ -596,6 +609,21 @@ |
453 | theCollection->theLatch.unlock();) |
454 | } |
455 | |
456 | +void SimpleCollection::CollectionIter::skip() |
457 | +{ |
458 | + // skip by position |
459 | + long lToSkip = to_xs_long(theSkip); |
460 | + if (theSkip >= theCollection->size()) |
461 | + { |
462 | + // we need to skip more then possible -> jump to the end |
463 | + theIterator = theEnd; |
464 | + } |
465 | + else |
466 | + { |
467 | + theIterator += to_xs_long(theSkip); |
468 | + } |
469 | +} |
470 | + |
471 | |
472 | /******************************************************************************* |
473 | |
474 | @@ -606,8 +634,8 @@ |
475 | theHaveLock = true; |
476 | |
477 | theIterator = theCollection->theXmlTrees.begin(); |
478 | - theIterator += to_xs_long(theSkip); |
479 | theEnd = theCollection->theXmlTrees.end(); |
480 | + skip(); |
481 | } |
482 | |
483 | |
484 | @@ -641,8 +669,8 @@ |
485 | void SimpleCollection::CollectionIter::reset() |
486 | { |
487 | theIterator = theCollection->theXmlTrees.begin(); |
488 | - theIterator += to_xs_long(theSkip); |
489 | theEnd = theCollection->theXmlTrees.end(); |
490 | + skip(); |
491 | } |
492 | |
493 | |
494 | |
495 | === modified file 'src/store/naive/simple_collection.h' |
496 | --- src/store/naive/simple_collection.h 2012-09-10 22:53:04 +0000 |
497 | +++ src/store/naive/simple_collection.h 2012-09-12 11:09:20 +0000 |
498 | @@ -57,7 +57,8 @@ |
499 | xs_integer theSkip; |
500 | |
501 | public: |
502 | - CollectionIter(SimpleCollection* collection, const xs_integer& aSkip); |
503 | + CollectionIter(SimpleCollection* collection, |
504 | + const xs_integer& aSkip); |
505 | |
506 | ~CollectionIter(); |
507 | |
508 | @@ -65,6 +66,8 @@ |
509 | bool next(store::Item_t& result); |
510 | void reset(); |
511 | void close(); |
512 | + private: |
513 | + void skip(); |
514 | }; |
515 | |
516 | |
517 | @@ -110,7 +113,8 @@ |
518 | |
519 | TreeId createTreeId(); |
520 | |
521 | - store::Iterator_t getIterator(const xs_integer& aSkip); |
522 | + store::Iterator_t getIterator(const xs_integer& aSkip, |
523 | + const zstring& aStart); |
524 | |
525 | void addNode(store::Item* node, xs_integer position = xs_integer(-1)); |
526 | |
527 | |
528 | === modified file 'test/rbkt/ExpQueryResults/zorba/collections/paging_1.xml.res' |
529 | --- test/rbkt/ExpQueryResults/zorba/collections/paging_1.xml.res 2012-06-28 18:19:34 +0000 |
530 | +++ test/rbkt/ExpQueryResults/zorba/collections/paging_1.xml.res 2012-09-12 11:09:20 +0000 |
531 | @@ -1,1 +1,1 @@ |
532 | -<d/><e/><a/><b/><c/><d/><e/> |
533 | +<d/><e/><delim/><a/><b/><c/><d/><e/><delim/><c/><d/><e/> |
534 | |
535 | === modified file 'test/rbkt/ExpQueryResults/zorba/collections/paging_2.xml.res' |
536 | --- test/rbkt/ExpQueryResults/zorba/collections/paging_2.xml.res 2012-06-28 18:19:34 +0000 |
537 | +++ test/rbkt/ExpQueryResults/zorba/collections/paging_2.xml.res 2012-09-12 11:09:20 +0000 |
538 | @@ -1,1 +1,1 @@ |
539 | -2 5 0 |
540 | +2 5 0 3 |
541 | |
542 | === modified file 'test/rbkt/ExpQueryResults/zorba/collections/paging_3.xml.res' |
543 | --- test/rbkt/ExpQueryResults/zorba/collections/paging_3.xml.res 2012-06-28 18:19:34 +0000 |
544 | +++ test/rbkt/ExpQueryResults/zorba/collections/paging_3.xml.res 2012-09-12 11:09:20 +0000 |
545 | @@ -1,1 +1,1 @@ |
546 | -<d/><e/><a/><b/><c/><d/><e/> |
547 | +<d/><e/><delim/><a/><b/><c/><d/><e/><delim/><c/><d/><e/> |
548 | |
549 | === modified file 'test/rbkt/ExpQueryResults/zorba/collections/paging_4.xml.res' |
550 | --- test/rbkt/ExpQueryResults/zorba/collections/paging_4.xml.res 2012-06-28 18:19:34 +0000 |
551 | +++ test/rbkt/ExpQueryResults/zorba/collections/paging_4.xml.res 2012-09-12 11:09:20 +0000 |
552 | @@ -1,1 +1,1 @@ |
553 | -2 5 0 |
554 | +2 5 0 3 |
555 | |
556 | === modified file 'test/rbkt/Queries/zorba/collections/paging_1.xq' |
557 | --- test/rbkt/Queries/zorba/collections/paging_1.xq 2012-06-28 18:19:34 +0000 |
558 | +++ test/rbkt/Queries/zorba/collections/paging_1.xq 2012-09-12 11:09:20 +0000 |
559 | @@ -1,9 +1,17 @@ |
560 | import module namespace ddl = "http://www.zorba-xquery.com/modules/store/static/collections/ddl"; |
561 | import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml"; |
562 | import module namespace ns = "http://example.org/datamodule/" at "collections.xqdata"; |
563 | +import module namespace ref = "http://www.zorba-xquery.com/modules/node-reference"; |
564 | |
565 | declare namespace ann = "http://www.zorba-xquery.com/annotations"; |
566 | |
567 | +declare function local:order($items) |
568 | +{ |
569 | + for $item in $items |
570 | + order by fn:local-name($item) |
571 | + return $item |
572 | +}; |
573 | + |
574 | declare %ann:sequential function local:test() |
575 | { |
576 | ddl:create(xs:QName("ns:test2")); |
577 | @@ -11,10 +19,11 @@ |
578 | dml:insert-nodes(xs:QName("ns:test2"), <b/>); |
579 | dml:insert-nodes(xs:QName("ns:test2"), (<c/>, <d/>, <e/>)); |
580 | ( |
581 | - dml:collection(xs:QName("ns:test2"), 3), |
582 | - dml:collection(xs:QName("ns:test2"), -1) |
583 | + local:order(dml:collection(xs:QName("ns:test2"), 3)), <delim/>, |
584 | + local:order(dml:collection(xs:QName("ns:test2"), -1)), <delim/>, |
585 | + let $ref := ref:node-reference(dml:collection(xs:QName("ns:test2"))[3]) |
586 | + return local:order(dml:collection(xs:QName("ns:test2"), $ref, 0)) |
587 | ) |
588 | }; |
589 | |
590 | local:test() |
591 | - |
592 | |
593 | === modified file 'test/rbkt/Queries/zorba/collections/paging_2.xq' |
594 | --- test/rbkt/Queries/zorba/collections/paging_2.xq 2012-06-28 18:19:34 +0000 |
595 | +++ test/rbkt/Queries/zorba/collections/paging_2.xq 2012-09-12 11:09:20 +0000 |
596 | @@ -1,6 +1,7 @@ |
597 | import module namespace ddl = "http://www.zorba-xquery.com/modules/store/static/collections/ddl"; |
598 | import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml"; |
599 | import module namespace ns = "http://example.org/datamodule/" at "collections.xqdata"; |
600 | +import module namespace ref = "http://www.zorba-xquery.com/modules/node-reference"; |
601 | |
602 | declare namespace ann = "http://www.zorba-xquery.com/annotations"; |
603 | |
604 | @@ -13,9 +14,10 @@ |
605 | ( |
606 | fn:count(dml:collection(xs:QName("ns:test2"), 3)), |
607 | fn:count(dml:collection(xs:QName("ns:test2"), -1)), |
608 | - fn:count(dml:collection(xs:QName("ns:test2"), 100)) |
609 | + fn:count(dml:collection(xs:QName("ns:test2"), 100)), |
610 | + let $ref := ref:node-reference(dml:collection(xs:QName("ns:test2"))[3]) |
611 | + return fn:count(dml:collection(xs:QName("ns:test2"), $ref, 0)) |
612 | ) |
613 | }; |
614 | |
615 | local:test() |
616 | - |
617 | |
618 | === modified file 'test/rbkt/Queries/zorba/collections/paging_3.xq' |
619 | --- test/rbkt/Queries/zorba/collections/paging_3.xq 2012-06-28 18:19:34 +0000 |
620 | +++ test/rbkt/Queries/zorba/collections/paging_3.xq 2012-09-12 11:09:20 +0000 |
621 | @@ -1,5 +1,6 @@ |
622 | import module namespace ddl = "http://www.zorba-xquery.com/modules/store/dynamic/collections/ddl"; |
623 | import module namespace dml = "http://www.zorba-xquery.com/modules/store/dynamic/collections/dml"; |
624 | +import module namespace ref = "http://www.zorba-xquery.com/modules/node-reference"; |
625 | |
626 | declare namespace ann = "http://www.zorba-xquery.com/annotations"; |
627 | declare namespace ns = "http://www.zorba-xquery.com/test"; |
628 | @@ -11,10 +12,11 @@ |
629 | dml:insert-nodes-last(xs:QName("ns:test2"), <b/>); |
630 | dml:insert-nodes-last(xs:QName("ns:test2"), (<c/>, <d/>, <e/>)); |
631 | ( |
632 | - dml:collection(xs:QName("ns:test2"), 3), |
633 | - dml:collection(xs:QName("ns:test2"), -1) |
634 | + dml:collection(xs:QName("ns:test2"), 3), <delim/>, |
635 | + dml:collection(xs:QName("ns:test2"), -1), <delim/>, |
636 | + let $ref := ref:node-reference(dml:collection(xs:QName("ns:test2"))[3]) |
637 | + return dml:collection(xs:QName("ns:test2"), $ref, 0) |
638 | ) |
639 | }; |
640 | |
641 | local:test() |
642 | - |
643 | |
644 | === modified file 'test/rbkt/Queries/zorba/collections/paging_4.xq' |
645 | --- test/rbkt/Queries/zorba/collections/paging_4.xq 2012-06-28 18:19:34 +0000 |
646 | +++ test/rbkt/Queries/zorba/collections/paging_4.xq 2012-09-12 11:09:20 +0000 |
647 | @@ -1,5 +1,6 @@ |
648 | import module namespace ddl = "http://www.zorba-xquery.com/modules/store/dynamic/collections/ddl"; |
649 | import module namespace dml = "http://www.zorba-xquery.com/modules/store/dynamic/collections/dml"; |
650 | +import module namespace ref = "http://www.zorba-xquery.com/modules/node-reference"; |
651 | |
652 | declare namespace ann = "http://www.zorba-xquery.com/annotations"; |
653 | declare namespace ns = "http://www.zorba-xquery.com/test"; |
654 | @@ -13,9 +14,10 @@ |
655 | ( |
656 | fn:count(dml:collection(xs:QName("ns:test2"), 3)), |
657 | fn:count(dml:collection(xs:QName("ns:test2"), -1)), |
658 | - fn:count(dml:collection(xs:QName("ns:test2"), 100)) |
659 | + fn:count(dml:collection(xs:QName("ns:test2"), 100)), |
660 | + let $ref := ref:node-reference(dml:collection(xs:QName("ns:test2"))[3]) |
661 | + return fn:count(dml:collection(xs:QName("ns:test2"), $ref, 0)) |
662 | ) |
663 | }; |
664 | |
665 | local:test() |
666 | - |
667 | |
668 | === added file 'test/rbkt/Queries/zorba/collections/paging_5.spec' |
669 | --- test/rbkt/Queries/zorba/collections/paging_5.spec 1970-01-01 00:00:00 +0000 |
670 | +++ test/rbkt/Queries/zorba/collections/paging_5.spec 2012-09-12 11:09:20 +0000 |
671 | @@ -0,0 +1,1 @@ |
672 | +Error: http://www.zorba-xquery.com/errors:ZSTR0066 |
673 | |
674 | === added file 'test/rbkt/Queries/zorba/collections/paging_5.xq' |
675 | --- test/rbkt/Queries/zorba/collections/paging_5.xq 1970-01-01 00:00:00 +0000 |
676 | +++ test/rbkt/Queries/zorba/collections/paging_5.xq 2012-09-12 11:09:20 +0000 |
677 | @@ -0,0 +1,20 @@ |
678 | +import module namespace ddl = "http://www.zorba-xquery.com/modules/store/dynamic/collections/ddl"; |
679 | +import module namespace dml = "http://www.zorba-xquery.com/modules/store/dynamic/collections/dml"; |
680 | +import module namespace ref = "http://www.zorba-xquery.com/modules/node-reference"; |
681 | + |
682 | +declare namespace ann = "http://www.zorba-xquery.com/annotations"; |
683 | +declare namespace ns = "http://www.zorba-xquery.com/test"; |
684 | + |
685 | +declare %ann:sequential function local:test() |
686 | +{ |
687 | + ddl:create(xs:QName("ns:test2")); |
688 | + dml:insert-nodes-last(xs:QName("ns:test2"), <a/>); |
689 | + dml:insert-nodes-last(xs:QName("ns:test2"), <b/>); |
690 | + dml:insert-nodes-last(xs:QName("ns:test2"), (<c/>, <d/>, <e/>)); |
691 | + |
692 | + dml:collection( |
693 | + xs:QName("ns:test2"), |
694 | + xs:anyURI("urn:uuid:aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"), 0) |
695 | +}; |
696 | + |
697 | +local:test() |
- Given the documentation, I was not able to figure out why the collection
function takes the $start and $skip parameters. Is one of the ignored if
the other one is given? Does skipping start at the item identified by
$start? If so, would it make sense to separate the two ways of skipping
into separate functions?
- improved
The reference to first node to return
=>
A reference to the first node to return.
- What does "order is implementation dependent" mean for ordered collections?
- Error message can be improved according to Paul's style:
Node reference $1 doesn't reference a node in collection $2
=>
$1: doesn't reference a node in collection ($2)
- typo:
if the passed reference $start doesn't reference
a _not_ from the collection identified by $name.
- the documentation mention zerr:ZAPI0028 if the given URI
is not a valid node reference