Merge lp:~zorba-coders/zorba/bug-966706 into lp:zorba
- bug-966706
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Markos Zaharioudakis |
Approved revision: | 10749 |
Merged at revision: | 10817 |
Proposed branch: | lp:~zorba-coders/zorba/bug-966706 |
Merge into: | lp:zorba |
Diff against target: |
2245 lines (+925/-429) 23 files modified
ChangeLog (+1/-0) src/runtime/core/apply_updates.cpp (+11/-5) src/runtime/indexing/doc_indexer.cpp (+4/-6) src/store/naive/node_items.cpp (+23/-23) src/store/naive/node_items.h (+0/-22) src/store/naive/pul_primitives.cpp (+33/-43) src/store/naive/simple_index_value.cpp (+14/-13) src/store/naive/simple_index_value.h (+9/-3) src/store/naive/simple_pul.cpp (+476/-285) src/store/naive/simple_pul.h (+24/-10) src/store/naive/store.cpp (+18/-19) src/store/naive/store_defs.h (+22/-0) test/rbkt/ExpQueryResults/zorba/index/delete_from_collection_01.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/index/undo2.xml.res (+2/-0) test/rbkt/ExpQueryResults/zorba/index/undo3.xml.res (+6/-0) test/rbkt/ExpQueryResults/zorba/index/unique.xml.res (+1/-0) test/rbkt/Queries/zorba/index/delete_from_collection_01.xq (+13/-0) test/rbkt/Queries/zorba/index/delete_from_collection_01.xqlib (+42/-0) test/rbkt/Queries/zorba/index/undo2.xq (+43/-0) test/rbkt/Queries/zorba/index/undo2.xqlib (+36/-0) test/rbkt/Queries/zorba/index/undo3.xq (+59/-0) test/rbkt/Queries/zorba/index/unique.xq (+50/-0) test/rbkt/Queries/zorba/index/unique.xqlib (+37/-0) |
To merge this branch: | bzr merge lp:~zorba-coders/zorba/bug-966706 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Markos Zaharioudakis | Approve | ||
Till Westmann | Approve | ||
Matthias Brantner | Approve | ||
Review via email: mp+103835@code.launchpad.net |
This proposal supersedes a proposal from 2012-04-11.
Commit message
fixed bug #966706 (key uniqueness of value equality index not enforced)
Description of the change
fixed bug #966706 (key uniqueness of value equality index not enforced)
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Validation queue job bug-966706-2012-04-
All tests succeeded!
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1. Got: 3 Pending.
Markos Zaharioudakis (markos-za) wrote : Posted in a previous version of this proposal | # |
The problem is that now an index refresh must be undoable. I am looking at the code to think wat is the best way to do the undo.
Markos Zaharioudakis (markos-za) : Posted in a previous version of this proposal | # |
Markos Zaharioudakis (markos-za) wrote : Posted in a previous version of this proposal | # |
I have implemented undo for incrementally maintained indexes.
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Attempt to merge into lp:zorba failed due to conflicts:
text conflict in ChangeLog
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
The attempt to merge lp:~zorba-coders/zorba/bug-966706 into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job bug-966706-2012-04-
final status was:
1 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Validation queue job bug-966706-2012-04-
All tests succeeded!
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1. Got: 2 Approve, 2 Pending.
Matthias Brantner (matthias-brantner) : Posted in a previous version of this proposal | # |
Matthias Brantner (matthias-brantner) wrote : Posted in a previous version of this proposal | # |
It seems that automatic indexes are not maintained if a node is deleted. The following example shows this:
library module:
module namespace seq = "http://
import module namespace ddl = "http://
import module namespace dml = "http://
import module namespace iddl = "http://
import module namespace idml = "http://
declare namespace an = "http://
declare collection seq:counters as node()*;
declare %an:automatic %an:unique %an:value-equality index seq:counters-by-uri
on nodes dml:collection(
by xs:string(@uri) as xs:string;
declare %an:sequential function seq:init()
{
ddl:create(
iddl:create(
dml:insert-
};
declare function seq:index ()
{
idml:
};
declare %an:sequential function seq:reset ()
{
dml:delete-
};
main module:
import module namespace seq = "http://
seq:init();
variable $foo := seq:index();
seq:reset();
variable $bar := seq:index();
$foo, $bar
The expected result is '<foo uri="1"/><foo uri="1"/>' but should be '<foo uri="1"/>'.
Markos Zaharioudakis (markos-za) wrote : Posted in a previous version of this proposal | # |
I have fixed your test, but now I have a problem with test index/undo3.xq. Its result is non-deterministic. Most of the time it returns the correct result, but sometimes not. And valgrind does not show any errors :(
Markos Zaharioudakis (markos-za) wrote : Posted in a previous version of this proposal | # |
This is ready for review again.
Matthias Brantner (matthias-brantner) wrote : | # |
Looks good. I have disabled some debug output in rev. 10748.
Till Westmann (tillw) wrote : | # |
It would be nice to have 2 comments explaining
1) the modification of the parameter in simple_
2) the role of key2 in Store::
It would also be nice to use the typedef here:
=== modified file 'src/store/
--- src/store/
+++ src/store/
@@ -1463,8 +1463,8 @@
{
csize numRoots = rootNodes.size();
- std::vector<
- std::vector<
+ CollectionPuls:
+ CollectionPuls:
for (; collIte != collEnd; ++collIte)
{
Markos Zaharioudakis (markos-za) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Attempt to merge into lp:zorba failed due to conflicts:
text conflict in src/store/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Attempt to merge into lp:zorba failed due to conflicts:
text conflict in src/store/
- 10749. By Markos Zaharioudakis
-
merge from trunk
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job bug-966706-2012-05-
All tests succeeded!
Preview Diff
1 | === modified file 'ChangeLog' |
2 | --- ChangeLog 2012-05-03 09:13:18 +0000 |
3 | +++ ChangeLog 2012-05-03 10:05:25 +0000 |
4 | @@ -36,6 +36,7 @@ |
5 | * Fixed bug #967428 (do not hoist index creation outside a try-catch) |
6 | * Fixed performance problem with the findNodeSources function of the no-copy rule |
7 | * Fixed bug #872234 (prevent a rewritting to take place in case of sequential expr) |
8 | + * Fixed bug #966706 (key uniqueness of index not enforced during incremental refresh) |
9 | * Fixed bug #906494 (default compile with D_FILE_OFFSET_BITS=64) |
10 | * Fixed bug #988412 (date:current-dateTime daylight saving) |
11 | * Fixed bug #912586, #912593 and #912722 (assertion failures with lax validation) |
12 | |
13 | === modified file 'src/runtime/core/apply_updates.cpp' |
14 | --- src/runtime/core/apply_updates.cpp 2012-04-24 12:39:38 +0000 |
15 | +++ src/runtime/core/apply_updates.cpp 2012-05-03 10:05:25 +0000 |
16 | @@ -92,19 +92,24 @@ |
17 | |
18 | store::Item_t item; |
19 | ulong numItems = 0; |
20 | - std::auto_ptr<store::PUL> pul; |
21 | + store::PUL_t pul; |
22 | |
23 | ApplyIteratorState* state; |
24 | DEFAULT_STACK_INIT(ApplyIteratorState, state, planState); |
25 | |
26 | - pul.reset(GENV_ITEMFACTORY->createPendingUpdateList()); |
27 | - |
28 | // Note: updating expr might not return a pul because of vacuous exprs |
29 | while (consumeNext(item, theChild, planState)) |
30 | { |
31 | if (item->isPul()) |
32 | { |
33 | - pul->mergeUpdates(item); |
34 | + if (pul) |
35 | + { |
36 | + pul->mergeUpdates(item); |
37 | + } |
38 | + else |
39 | + { |
40 | + pul.transfer(item); |
41 | + } |
42 | } |
43 | else if (!theDiscardXDM) |
44 | { |
45 | @@ -113,7 +118,8 @@ |
46 | } |
47 | } |
48 | |
49 | - apply_updates(ccb, gdctx, theSctx, pul.get(), loc); |
50 | + if(pul) |
51 | + apply_updates(ccb, gdctx, theSctx, pul, loc); |
52 | |
53 | state->theXDMIte = state->theXDMItems.begin(); |
54 | state->theXDMEnd = state->theXDMItems.end(); |
55 | |
56 | === modified file 'src/runtime/indexing/doc_indexer.cpp' |
57 | --- src/runtime/indexing/doc_indexer.cpp 2012-04-24 12:39:38 +0000 |
58 | +++ src/runtime/indexing/doc_indexer.cpp 2012-05-03 10:05:25 +0000 |
59 | @@ -84,7 +84,7 @@ |
60 | QueryLoc::null, |
61 | tmp); |
62 | |
63 | - ulong numEntries = delta.size(); |
64 | + csize numEntries = delta.size(); |
65 | store::Item_t domainNode; |
66 | store::IndexKey* key = NULL; |
67 | |
68 | @@ -96,13 +96,11 @@ |
69 | |
70 | //std::cout << domainNode.getp() << " " << key << std::endl; |
71 | |
72 | - for (ulong i = 0; i < theNumColumns; ++i) |
73 | + for (csize i = 0; i < theNumColumns; ++i) |
74 | { |
75 | if (!thePlanWrapper->next((*key)[i])) |
76 | - throw ZORBA_EXCEPTION( |
77 | - zerr::ZXQP0003_INTERNAL_ERROR, |
78 | - ERROR_PARAMS( ZED( IncompleteKeyInIndexRefresh ) ) |
79 | - ); |
80 | + throw ZORBA_EXCEPTION(zerr::ZXQP0003_INTERNAL_ERROR, |
81 | + ERROR_PARAMS(ZED(IncompleteKeyInIndexRefresh))); |
82 | } |
83 | |
84 | delta.resize(numEntries + 1); |
85 | |
86 | === modified file 'src/store/naive/node_items.cpp' |
87 | --- src/store/naive/node_items.cpp 2012-05-03 09:09:01 +0000 |
88 | +++ src/store/naive/node_items.cpp 2012-05-03 10:05:25 +0000 |
89 | @@ -457,7 +457,7 @@ |
90 | #ifndef NDEBUG |
91 | XmlNode::~XmlNode() |
92 | { |
93 | - NODE_TRACE1("Deleted " << store::StoreConsts::toString(getNodeKind()) << this); |
94 | + STORE_TRACE1("Deleted " << store::StoreConsts::toString(getNodeKind()) << this); |
95 | } |
96 | #endif |
97 | |
98 | @@ -1651,7 +1651,7 @@ |
99 | : |
100 | InternalNode(store::StoreConsts::documentNode) |
101 | { |
102 | - NODE_TRACE1("Loaded doc node " << this); |
103 | + STORE_TRACE1("Loaded doc node " << this); |
104 | } |
105 | |
106 | |
107 | @@ -1667,7 +1667,7 @@ |
108 | theBaseUri(baseUri), |
109 | theDocUri(docUri) |
110 | { |
111 | - NODE_TRACE1("{\nConstructing doc node " << this << " tree = " |
112 | + STORE_TRACE1("{\nConstructing doc node " << this << " tree = " |
113 | << getTree()->getId() << ":" << getTree() |
114 | << " doc uri = " << docUri); |
115 | } |
116 | @@ -1722,8 +1722,8 @@ |
117 | throw; |
118 | } |
119 | |
120 | - NODE_TRACE1("}"); |
121 | - NODE_TRACE1("Copied doc node " << this << " to node " << copyNode); |
122 | + STORE_TRACE1("}"); |
123 | + STORE_TRACE1("Copied doc node " << this << " to node " << copyNode); |
124 | |
125 | return copyNode; |
126 | } |
127 | @@ -1892,7 +1892,7 @@ |
128 | theNodes.resize(numAttributes); |
129 | } |
130 | |
131 | - NODE_TRACE1("Loaded elem node " << this << " name = " << theName->show() |
132 | + STORE_TRACE1("Loaded elem node " << this << " name = " << theName->show() |
133 | << " num bindings = " << numBindings << " num attributes = " |
134 | << numAttributes << std::endl); |
135 | } |
136 | @@ -2018,7 +2018,7 @@ |
137 | throw; |
138 | } |
139 | |
140 | - NODE_TRACE1("Constructed element node " << this << " parent = " |
141 | + STORE_TRACE1("Constructed element node " << this << " parent = " |
142 | << std::hex << (parent ? (ulong)parent : 0) << " pos = " << pos |
143 | << " tree = " << getTree()->getId() << ":" << getTree() |
144 | << " ordpath = " << theOrdPath.show() |
145 | @@ -2359,7 +2359,7 @@ |
146 | throw; |
147 | } |
148 | |
149 | - NODE_TRACE1("Copied elem node " << this << " to node " << copyNode |
150 | + STORE_TRACE1("Copied elem node " << this << " to node " << copyNode |
151 | << " name = " << theName->getStringValue() << " parent = " |
152 | << (parent ? parent : 0x0) |
153 | << " pos = " << pos << " copy mode = " << copymode.toString()); |
154 | @@ -3327,7 +3327,7 @@ |
155 | if (qn->isBaseUri()) |
156 | theFlags |= IsBaseUri; |
157 | |
158 | - NODE_TRACE1("Loaded attr node " << this << " name = " << theName->getStringValue()); |
159 | + STORE_TRACE1("Loaded attr node " << this << " name = " << theName->getStringValue()); |
160 | } |
161 | |
162 | |
163 | @@ -3450,7 +3450,7 @@ |
164 | throw; |
165 | } |
166 | |
167 | - NODE_TRACE1("Constructed attribute node " << this << " parent = " |
168 | + STORE_TRACE1("Constructed attribute node " << this << " parent = " |
169 | << std::hex << (parent ? (ulong)parent : 0) << " pos = " << pos |
170 | << " tree = " << getTree()->getId() << ":" << getTree() |
171 | << " ordpath = " << theOrdPath.show() |
172 | @@ -3533,7 +3533,7 @@ |
173 | throw; |
174 | } |
175 | |
176 | - NODE_TRACE1("Copied attribute node " << this << " to node " << copyNode |
177 | + STORE_TRACE1("Copied attribute node " << this << " to node " << copyNode |
178 | << " name = " << theName->show() << " parent = " |
179 | << std::hex << (parent ? (ulong)parent : 0) << " pos = " << pos |
180 | << " copy mode = " << copymode.toString()); |
181 | @@ -3789,7 +3789,7 @@ |
182 | { |
183 | setText(content); |
184 | |
185 | - NODE_TRACE1("Loaded text node " << this << " content = " << getText()); |
186 | + STORE_TRACE1("Loaded text node " << this << " content = " << getText()); |
187 | } |
188 | |
189 | |
190 | @@ -3834,13 +3834,13 @@ |
191 | } |
192 | |
193 | #ifdef TEXT_ORDPATH |
194 | - NODE_TRACE1("Constructed text node " << this << " parent = " |
195 | + STORE_TRACE1("Constructed text node " << this << " parent = " |
196 | << std::hex << (parent ? (ulong)parent : 0) << " pos = " << pos |
197 | << " tree = " << getTree()->getId() << ":" << getTree() |
198 | << " ordpath = " << theOrdPath.show() |
199 | << " content = " << getText()); |
200 | #else |
201 | - NODE_TRACE1("Constructed text node " << this << " parent = " |
202 | + STORE_TRACE1("Constructed text node " << this << " parent = " |
203 | << std::hex << (parent ? (ulong)parent : 0) << " pos = " << pos |
204 | << " tree = " << getTree()->getId() << ":" << getTree() |
205 | << " content = " << getText()); |
206 | @@ -3895,12 +3895,12 @@ |
207 | p->insertChild(this, p->numChildren()); |
208 | |
209 | #ifdef TEXT_ORDPATH |
210 | - NODE_TRACE1("Constructed text node " << this << " parent = " |
211 | + STORE_TRACE1("Constructed text node " << this << " parent = " |
212 | << std::hex << (parent ? (ulong)parent : 0) |
213 | << " ordpath = " << theOrdPath.show() |
214 | << " content = " << getValue()->getStringValue()); |
215 | #else |
216 | - NODE_TRACE1("Constructed text node " << this << " parent = " |
217 | + STORE_TRACE1("Constructed text node " << this << " parent = " |
218 | << std::hex << (parent ? (ulong)parent : 0) |
219 | << " content = " << getValue()->getStringValue()); |
220 | #endif |
221 | @@ -4012,7 +4012,7 @@ |
222 | throw; |
223 | } |
224 | |
225 | - NODE_TRACE1("Copied text node " << this << " to node " << copyNode |
226 | + STORE_TRACE1("Copied text node " << this << " to node " << copyNode |
227 | << " parent = " << std::hex << (parent ? (ulong)parent : 0) |
228 | << " pos = " << pos); |
229 | |
230 | @@ -4497,7 +4497,7 @@ |
231 | |
232 | theName = qnpool.insert(zstring(), zstring(), theTarget); |
233 | |
234 | - NODE_TRACE1("Loaded pi node " << this << " target = " << theTarget |
235 | + STORE_TRACE1("Loaded pi node " << this << " target = " << theTarget |
236 | << std::endl); |
237 | } |
238 | |
239 | @@ -4530,7 +4530,7 @@ |
240 | parent->insertChild(this, pos); |
241 | } |
242 | |
243 | - NODE_TRACE1("Constructed pi node " << this << " parent = " |
244 | + STORE_TRACE1("Constructed pi node " << this << " parent = " |
245 | << std::hex << (parent ? (ulong)parent : 0) << " pos = " << pos |
246 | << " tree = " << getTree()->getId() << ":" << getTree() |
247 | << " ordpath = " << theOrdPath.show() << " target = " << theTarget); |
248 | @@ -4579,7 +4579,7 @@ |
249 | throw; |
250 | } |
251 | |
252 | - NODE_TRACE1("Copied pi node " << this << " to node " << copyNode |
253 | + STORE_TRACE1("Copied pi node " << this << " to node " << copyNode |
254 | << " parent = " << std::hex << (parent ? (ulong)parent : 0) |
255 | << " pos = " << pos); |
256 | |
257 | @@ -4637,7 +4637,7 @@ |
258 | { |
259 | theContent.take(content); |
260 | |
261 | - NODE_TRACE1("Loaded comment node " << this << " content = " << theContent); |
262 | + STORE_TRACE1("Loaded comment node " << this << " content = " << theContent); |
263 | } |
264 | |
265 | |
266 | @@ -4663,7 +4663,7 @@ |
267 | parent->insertChild(this, pos); |
268 | } |
269 | |
270 | - NODE_TRACE1("Constructed comment node " << this << " parent = " |
271 | + STORE_TRACE1("Constructed comment node " << this << " parent = " |
272 | << std::hex << (parent ? (ulong)parent : 0) << " pos = " << pos |
273 | << " tree = " << getTree()->getId() << ":" << getTree() |
274 | << " ordpath = " << theOrdPath.show() << " content = " |
275 | @@ -4710,7 +4710,7 @@ |
276 | throw; |
277 | } |
278 | |
279 | - NODE_TRACE1("Copied coment node " << this << " to node " << copyNode |
280 | + STORE_TRACE1("Copied coment node " << this << " to node " << copyNode |
281 | << " parent = " << std::hex << (parent ? (ulong)parent : 0) |
282 | << " pos = " << pos); |
283 | |
284 | |
285 | === modified file 'src/store/naive/node_items.h' |
286 | --- src/store/naive/node_items.h 2012-05-03 09:09:01 +0000 |
287 | +++ src/store/naive/node_items.h 2012-05-03 10:05:25 +0000 |
288 | @@ -107,28 +107,6 @@ |
289 | << store::StoreConsts::toString(getNodeKind())) |
290 | |
291 | |
292 | -#ifndef NDEBUG |
293 | - |
294 | -#define NODE_TRACE(level, msg) \ |
295 | -{ \ |
296 | - if (level <= GET_STORE().getTraceLevel()) \ |
297 | - std::cout << msg << std::endl; \ |
298 | -} |
299 | - |
300 | -#define NODE_TRACE1(msg) NODE_TRACE(1, msg); |
301 | -#define NODE_TRACE2(msg) NODE_TRACE(2, msg); |
302 | -#define NODE_TRACE3(msg) NODE_TRACE(3, msg); |
303 | - |
304 | -#else |
305 | - |
306 | -#define NODE_TRACE(msg) |
307 | -#define NODE_TRACE1(msg) |
308 | -#define NODE_TRACE2(msg) |
309 | -#define NODE_TRACE3(msg) |
310 | - |
311 | -#endif |
312 | - |
313 | - |
314 | /******************************************************************************* |
315 | |
316 | theRefCount : It is the sum of theRefCounts of all the nodes belonging to |
317 | |
318 | === modified file 'src/store/naive/pul_primitives.cpp' |
319 | --- src/store/naive/pul_primitives.cpp 2012-04-24 12:39:38 +0000 |
320 | +++ src/store/naive/pul_primitives.cpp 2012-05-03 10:05:25 +0000 |
321 | @@ -35,6 +35,7 @@ |
322 | #include "store/api/validator.h" |
323 | |
324 | #include "diagnostics/xquery_diagnostics.h" |
325 | +#include "diagnostics/util_macros.h" |
326 | |
327 | |
328 | namespace zorba { |
329 | @@ -946,42 +947,36 @@ |
330 | void UpdDeleteCollection::apply() |
331 | { |
332 | theCollection = GET_STORE().getCollection(theName, theDynamicCollection); |
333 | + |
334 | if (theCollection == NULL) |
335 | return;//If two delete collection are issued in the same snapshot is a noop |
336 | + |
337 | Collection* collection = static_cast<Collection*>(theCollection.getp()); |
338 | |
339 | std::vector<store::Index*> indexes; |
340 | collection->getIndexes(indexes); |
341 | |
342 | if (!indexes.empty()) |
343 | - throw XQUERY_EXCEPTION( |
344 | - zerr::ZDDY0013_COLLECTION_BAD_DESTROY_INDEXES, |
345 | - ERROR_PARAMS( collection->getName()->getStringValue() ), |
346 | - ERROR_LOC( theLoc ) |
347 | - ); |
348 | + RAISE_ERROR(zerr::ZDDY0013_COLLECTION_BAD_DESTROY_INDEXES, theLoc, |
349 | + ERROR_PARAMS(collection->getName()->getStringValue())); |
350 | |
351 | std::vector<store::IC*> activeICs; |
352 | collection->getActiveICs(activeICs); |
353 | |
354 | if (!activeICs.empty()) |
355 | - throw XQUERY_EXCEPTION( |
356 | - zerr::ZDDY0014_COLLECTION_BAD_DESTROY_ICS, |
357 | - ERROR_PARAMS( collection->getName()->getStringValue() ), |
358 | - ERROR_LOC( theLoc ) |
359 | - ); |
360 | + RAISE_ERROR(zerr::ZDDY0014_COLLECTION_BAD_DESTROY_ICS, theLoc, |
361 | + ERROR_PARAMS(collection->getName()->getStringValue())); |
362 | |
363 | uint64_t size; |
364 | - try { |
365 | + try |
366 | + { |
367 | size = to_xs_unsignedLong(collection->size()); |
368 | - } catch (std::range_error& e) |
369 | + } |
370 | + catch (std::range_error& e) |
371 | { |
372 | - throw ZORBA_EXCEPTION( |
373 | - zerr::ZSTR0060_RANGE_EXCEPTION, |
374 | - ERROR_PARAMS( |
375 | - BUILD_STRING("collection too big (" |
376 | - << e.what() << "; " << theName << ")") |
377 | - ) |
378 | - ); |
379 | + throw ZORBA_EXCEPTION(zerr::ZSTR0060_RANGE_EXCEPTION, |
380 | + ERROR_PARAMS(BUILD_STRING("collection too big (" |
381 | + << e.what() << "; " << theName << ")"))); |
382 | } |
383 | |
384 | for (uint64_t i = 0; i < size; ++i) |
385 | @@ -989,11 +984,10 @@ |
386 | XmlNode* root = static_cast<XmlNode*>(collection->nodeAt(xs_integer(i)).getp()); |
387 | XmlTree* tree = root->getTree(); |
388 | if (tree->getRefCount() > 1) |
389 | - throw XQUERY_EXCEPTION( |
390 | - zerr::ZDDY0015_COLLECTION_BAD_DESTROY_NODES, |
391 | - ERROR_PARAMS( collection->getName()->getStringValue() ), |
392 | - ERROR_LOC( theLoc ) |
393 | - ); |
394 | + { |
395 | + RAISE_ERROR(zerr::ZDDY0015_COLLECTION_BAD_DESTROY_NODES, theLoc, |
396 | + ERROR_PARAMS(collection->getName()->getStringValue())); |
397 | + } |
398 | } |
399 | |
400 | GET_STORE().deleteCollection(theName, theDynamicCollection); |
401 | @@ -1013,13 +1007,13 @@ |
402 | void UpdInsertIntoCollection::apply() |
403 | { |
404 | Collection* lColl = static_cast<Collection*> |
405 | - (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
406 | + (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
407 | assert(lColl); |
408 | |
409 | theIsApplied = true; |
410 | |
411 | - std::size_t numNodes = theNodes.size(); |
412 | - for (std::size_t i = 0; i < numNodes; ++i) |
413 | + csize numNodes = theNodes.size(); |
414 | + for (csize i = 0; i < numNodes; ++i) |
415 | { |
416 | lColl->addNode(theNodes[i], xs_integer(-1)); |
417 | ++theNumApplied; |
418 | @@ -1030,7 +1024,7 @@ |
419 | void UpdInsertIntoCollection::undo() |
420 | { |
421 | Collection* lColl = static_cast<Collection*> |
422 | - (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
423 | + (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
424 | assert(lColl); |
425 | |
426 | uint64_t lastPos; |
427 | @@ -1040,13 +1034,9 @@ |
428 | } |
429 | catch (std::range_error& e) |
430 | { |
431 | - throw ZORBA_EXCEPTION( |
432 | - zerr::ZSTR0060_RANGE_EXCEPTION, |
433 | - ERROR_PARAMS( |
434 | - BUILD_STRING("collection too big (" |
435 | - << e.what() << "; " << theName << ")") |
436 | - ) |
437 | - ); |
438 | + throw ZORBA_EXCEPTION(zerr::ZSTR0060_RANGE_EXCEPTION, |
439 | + ERROR_PARAMS(BUILD_STRING("collection too big (" |
440 | + << e.what() << "; " << theName << ")"))); |
441 | } |
442 | |
443 | for (long i = theNumApplied-1; i >= 0; --i) |
444 | @@ -1154,7 +1144,7 @@ |
445 | void UpdInsertBeforeIntoCollection::apply() |
446 | { |
447 | Collection* lColl = static_cast<Collection*> |
448 | - (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
449 | + (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
450 | assert(lColl); |
451 | |
452 | if (!theNodes.empty()) |
453 | @@ -1170,7 +1160,7 @@ |
454 | void UpdInsertBeforeIntoCollection::undo() |
455 | { |
456 | Collection* lColl = static_cast<Collection*> |
457 | - (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
458 | + (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
459 | assert(lColl); |
460 | ZORBA_ASSERT(theFirstNode == lColl->nodeAt(theFirstPos)); |
461 | |
462 | @@ -1184,7 +1174,7 @@ |
463 | void UpdInsertAfterIntoCollection::apply() |
464 | { |
465 | Collection* lColl = static_cast<Collection*> |
466 | - (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
467 | + (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
468 | assert(lColl); |
469 | |
470 | if (!theNodes.empty()) |
471 | @@ -1201,7 +1191,7 @@ |
472 | void UpdInsertAfterIntoCollection::undo() |
473 | { |
474 | Collection* lColl = static_cast<Collection*> |
475 | - (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
476 | + (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
477 | assert(lColl); |
478 | ZORBA_ASSERT(theFirstNode == lColl->nodeAt(theFirstPos)); |
479 | |
480 | @@ -1236,13 +1226,13 @@ |
481 | ); |
482 | } |
483 | |
484 | - std::size_t numNodes = theNodes.size(); |
485 | + csize numNodes = theNodes.size(); |
486 | |
487 | bool isLast = theIsLast; |
488 | |
489 | if (theIsLast) |
490 | { |
491 | - for (std::size_t i = numNodes; i > 0; --i) |
492 | + for (csize i = numNodes; i > 0; --i) |
493 | { |
494 | if (theNodes[i-1] != lColl->nodeAt(xs_integer(size - i))) |
495 | { |
496 | @@ -1270,7 +1260,7 @@ |
497 | void UpdDeleteNodesFromCollection::undo() |
498 | { |
499 | Collection* lColl = static_cast<Collection*> |
500 | - (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
501 | + (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
502 | assert(lColl); |
503 | |
504 | for (std::size_t i = 0; i < theNumApplied; ++i) |
505 | @@ -1289,7 +1279,7 @@ |
506 | void UpdTruncateCollection::apply() |
507 | { |
508 | Collection* lColl = static_cast<Collection*> |
509 | - (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
510 | + (GET_STORE().getCollection(theName, theDynamicCollection).getp()); |
511 | assert(lColl); |
512 | |
513 | lColl->removeAll(); |
514 | |
515 | === modified file 'src/store/naive/simple_index_value.cpp' |
516 | --- src/store/naive/simple_index_value.cpp 2012-05-02 23:15:16 +0000 |
517 | +++ src/store/naive/simple_index_value.cpp 2012-05-03 10:05:25 +0000 |
518 | @@ -368,9 +368,9 @@ |
519 | ERROR_PARAMS(key->toString(), theQname->getStringValue())); |
520 | } |
521 | |
522 | - ValueIndexValue* valueSet = NULL; |
523 | + IndexMap::iterator pos = theMap.find(key); |
524 | |
525 | - if (theMap.get(key, valueSet)) |
526 | + if (pos != theMap.end()) |
527 | { |
528 | if (isUnique()) |
529 | { |
530 | @@ -378,21 +378,20 @@ |
531 | ERROR_PARAMS(theQname->getStringValue())); |
532 | } |
533 | |
534 | - valueSet->resize(valueSet->size() + 1); |
535 | - (*valueSet)[valueSet->size()-1].transfer(value); |
536 | - |
537 | + (*pos).second->transfer_back(value); |
538 | + key = const_cast<store::IndexKey*>((*pos).first); |
539 | + |
540 | return true; |
541 | } |
542 | |
543 | - valueSet = new ValueIndexValue(1); |
544 | + ValueIndexValue* valueSet = new ValueIndexValue(1); |
545 | (*valueSet)[0].transfer(value); |
546 | |
547 | //std::cout << "Index Entry Insert [" << key << "," |
548 | // << valueSet << "]" << std::endl; |
549 | |
550 | - const store::IndexKey* key2 = key; |
551 | - theMap.insert(key2, valueSet); |
552 | - key = NULL; // ownership of the key obj passes to the index. |
553 | + // Note: ownership of the key obj passes to the index. |
554 | + theMap.insert(key, valueSet); |
555 | |
556 | return false; |
557 | } |
558 | @@ -409,7 +408,7 @@ |
559 | ********************************************************************************/ |
560 | bool ValueHashIndex::remove( |
561 | const store::IndexKey* key, |
562 | - store::Item_t& value, |
563 | + const store::Item_t& value, |
564 | bool all) |
565 | { |
566 | if (key->size() != getNumColumns()) |
567 | @@ -653,7 +652,7 @@ |
568 | #if 0 |
569 | std::cout << "inserting entry : [("; |
570 | |
571 | - for (ulong i = 0; i < getNumColumns(); i++) |
572 | + for (csize i = 0; i < getNumColumns(); i++) |
573 | { |
574 | if (key[i] != NULL) |
575 | std::cout << key[i]->getStringValue() << ", "; |
576 | @@ -676,14 +675,16 @@ |
577 | } |
578 | |
579 | pos->second->transfer_back(value); |
580 | + key = const_cast<store::IndexKey*>(pos->first); |
581 | + |
582 | return true; |
583 | } |
584 | |
585 | ValueIndexValue* valueSet = new ValueIndexValue(1); |
586 | (*valueSet)[0].transfer(value); |
587 | |
588 | + // Note: ownership of the key obj passes to the index. |
589 | theMap.insert(IndexMapPair(key, valueSet)); |
590 | - key = NULL; // ownership of the key obj passes to the index. |
591 | |
592 | return false; |
593 | } |
594 | @@ -694,7 +695,7 @@ |
595 | ********************************************************************************/ |
596 | bool ValueTreeIndex::remove( |
597 | const store::IndexKey* key, |
598 | - store::Item_t& value, |
599 | + const store::Item_t& value, |
600 | bool all) |
601 | { |
602 | if (key->size() != getNumColumns()) |
603 | |
604 | === modified file 'src/store/naive/simple_index_value.h' |
605 | --- src/store/naive/simple_index_value.h 2012-04-24 12:39:38 +0000 |
606 | +++ src/store/naive/simple_index_value.h 2012-05-03 10:05:25 +0000 |
607 | @@ -88,11 +88,13 @@ |
608 | public: |
609 | const XQPCollator* getCollator(ulong i) const; |
610 | |
611 | + virtual bool isTreeIndex() = 0; |
612 | + |
613 | virtual bool insert(store::IndexKey*& key, store::Item_t& item) = 0; |
614 | |
615 | virtual bool remove( |
616 | const store::IndexKey* key, |
617 | - store::Item_t& item, |
618 | + const store::Item_t& item, |
619 | bool all = false) = 0; |
620 | }; |
621 | |
622 | @@ -142,6 +144,8 @@ |
623 | ~ValueHashIndex(); |
624 | |
625 | public: |
626 | + bool isTreeIndex() { return false; } |
627 | + |
628 | void clear(); |
629 | |
630 | ulong size() const; |
631 | @@ -150,7 +154,7 @@ |
632 | |
633 | bool insert(store::IndexKey*& key, store::Item_t& item); |
634 | |
635 | - bool remove(const store::IndexKey* key, store::Item_t& item, bool all); |
636 | + bool remove(const store::IndexKey* key, const store::Item_t& item, bool all); |
637 | }; |
638 | |
639 | |
640 | @@ -227,6 +231,8 @@ |
641 | ~ValueTreeIndex(); |
642 | |
643 | public: |
644 | + bool isTreeIndex() { return true; } |
645 | + |
646 | void clear(); |
647 | |
648 | ulong size() const; |
649 | @@ -235,7 +241,7 @@ |
650 | |
651 | bool insert(store::IndexKey*& key, store::Item_t& item); |
652 | |
653 | - bool remove(const store::IndexKey* key, store::Item_t& item, bool all = false); |
654 | + bool remove(const store::IndexKey* key, const store::Item_t& item, bool all = false); |
655 | }; |
656 | |
657 | |
658 | |
659 | === modified file 'src/store/naive/simple_pul.cpp' |
660 | --- src/store/naive/simple_pul.cpp 2012-05-02 22:59:31 +0000 |
661 | +++ src/store/naive/simple_pul.cpp 2012-05-03 10:05:25 +0000 |
662 | @@ -58,28 +58,6 @@ |
663 | /******************************************************************************* |
664 | |
665 | ********************************************************************************/ |
666 | -void cleanIndexDeltas(std::vector<store::IndexDelta>& deltas) |
667 | -{ |
668 | - std::vector<store::IndexDelta>::iterator ite = deltas.begin(); |
669 | - std::vector<store::IndexDelta>::iterator end = deltas.end(); |
670 | - |
671 | - for (; ite != end; ++ite) |
672 | - { |
673 | - store::IndexDelta::iterator ite2 = (*ite).begin(); |
674 | - store::IndexDelta::iterator end2 = (*ite).end(); |
675 | - |
676 | - for (; ite2 != end2; ++ite2) |
677 | - { |
678 | - if ((*ite2).second) |
679 | - delete (*ite2).second; |
680 | - } |
681 | - } |
682 | -} |
683 | - |
684 | - |
685 | -/******************************************************************************* |
686 | - |
687 | -********************************************************************************/ |
688 | void applyList(std::vector<UpdatePrimitive*>& aVector) |
689 | { |
690 | std::vector<UpdatePrimitive*>::iterator iter = aVector.begin(); |
691 | @@ -97,9 +75,9 @@ |
692 | ********************************************************************************/ |
693 | void undoList(std::vector<UpdatePrimitive*>& list) |
694 | { |
695 | - ulong size = (ulong)list.size(); |
696 | + csize size = list.size(); |
697 | |
698 | - for (ulong i = size; i > 0; --i) |
699 | + for (csize i = size; i > 0; --i) |
700 | { |
701 | if (list[i-1]->isApplied()) |
702 | list[i-1]->undo(); |
703 | @@ -150,14 +128,14 @@ |
704 | |
705 | cleanList(theValidationList); |
706 | |
707 | - CollectionPulMap::iterator ite = theCollectionPuls.begin(); |
708 | - CollectionPulMap::iterator end = theCollectionPuls.end(); |
709 | + CollectionPuls::iterator ite = theCollectionPuls.begin(); |
710 | + CollectionPuls::iterator end = theCollectionPuls.end(); |
711 | |
712 | for (; ite != end; ++ite) |
713 | { |
714 | - if ((*ite).second != NULL) |
715 | - delete (*ite).second; |
716 | + delete (*ite); |
717 | } |
718 | + |
719 | cleanList(theICActivationList); |
720 | cleanList(theCreateDocumentList); |
721 | cleanList(theDeleteDocumentList); |
722 | @@ -197,49 +175,53 @@ |
723 | |
724 | if (collName == theLastCollection) |
725 | return theLastPul; |
726 | - return getCollectionPulByName(collName,collection->isDynamic()); |
727 | + |
728 | + return getCollectionPulByName(collName, collection->isDynamic()); |
729 | } |
730 | else if (theNoCollectionPul != NULL) |
731 | { |
732 | return theNoCollectionPul; |
733 | } |
734 | - else if (theCollectionPuls[NULL] != NULL) |
735 | - { |
736 | - theNoCollectionPul = theCollectionPuls[NULL]; |
737 | - return theNoCollectionPul; |
738 | - } |
739 | else |
740 | { |
741 | theNoCollectionPul = new CollectionPul(this, NULL); |
742 | - theCollectionPuls[NULL] = theNoCollectionPul; |
743 | + theCollectionPuls.push_back(theNoCollectionPul); |
744 | + theCollectionPulsMap[NULL] = theCollectionPuls.size() - 1; |
745 | return theNoCollectionPul; |
746 | } |
747 | } |
748 | |
749 | -CollectionPul* PULImpl::getCollectionPulByName(const store::Item* name, bool dynamicCollection) |
750 | + |
751 | +CollectionPul* PULImpl::getCollectionPulByName( |
752 | + const store::Item* name, |
753 | + bool isDynamic) |
754 | { |
755 | const QNameItem* collName = static_cast<const QNameItem*>(name)->getNormalized(); |
756 | |
757 | - assert(!name->isNode()); |
758 | + assert(name->isAtomic()); |
759 | |
760 | // "name" is the name of a collection. |
761 | if (name == theLastCollection) |
762 | return theLastPul; |
763 | |
764 | - CollectionPulMap::iterator ite = theCollectionPuls.find(collName); |
765 | + CollectionPulMap::iterator ite = theCollectionPulsMap.find(collName); |
766 | |
767 | theLastCollection = collName; |
768 | |
769 | - if (ite != theCollectionPuls.end()) |
770 | + if (ite != theCollectionPulsMap.end()) |
771 | { |
772 | - theLastPul = ite->second; |
773 | + theLastPul = theCollectionPuls[ite->second]; |
774 | } |
775 | else |
776 | { |
777 | Collection* collection = static_cast<Collection*> |
778 | - (GET_STORE().getCollection(collName,dynamicCollection).getp()); |
779 | + (GET_STORE().getCollection(collName, isDynamic).getp()); |
780 | + |
781 | theLastPul = new CollectionPul(this, collection); |
782 | - theCollectionPuls[collName] = theLastPul; |
783 | + |
784 | + theCollectionPuls.push_back(theLastPul); |
785 | + |
786 | + theCollectionPulsMap[collName] = theCollectionPuls.size() - 1; |
787 | } |
788 | |
789 | return theLastPul; |
790 | @@ -1107,17 +1089,17 @@ |
791 | PULImpl* otherp = reinterpret_cast<PULImpl*>(other); |
792 | |
793 | // Merge collection-specific primitives |
794 | - CollectionPulMap::iterator thisIte = theCollectionPuls.begin(); |
795 | - CollectionPulMap::iterator thisEnd = theCollectionPuls.end(); |
796 | - CollectionPulMap::iterator otherIte = otherp->theCollectionPuls.begin(); |
797 | - CollectionPulMap::iterator otherEnd = otherp->theCollectionPuls.end(); |
798 | + CollectionPulMap::iterator thisIte = theCollectionPulsMap.begin(); |
799 | + CollectionPulMap::iterator thisEnd = theCollectionPulsMap.end(); |
800 | + CollectionPulMap::iterator otherIte = otherp->theCollectionPulsMap.begin(); |
801 | + CollectionPulMap::iterator otherEnd = otherp->theCollectionPulsMap.end(); |
802 | |
803 | while (thisIte != thisEnd && otherIte != otherEnd) |
804 | { |
805 | if (thisIte->first == otherIte->first) |
806 | { |
807 | - CollectionPul* thisPul = thisIte->second; |
808 | - CollectionPul* otherPul = otherIte->second; |
809 | + CollectionPul* thisPul = theCollectionPuls[thisIte->second]; |
810 | + CollectionPul* otherPul = otherp->theCollectionPuls[otherIte->second]; |
811 | |
812 | // Merge XQUF primitives |
813 | mergeUpdateList(thisPul, |
814 | @@ -1186,18 +1168,27 @@ |
815 | } |
816 | else |
817 | { |
818 | - theCollectionPuls[otherIte->first] = otherIte->second; |
819 | - otherIte->second->switchPul(this); |
820 | - otherIte->second = NULL; |
821 | + CollectionPul* otherPul = otherp->theCollectionPuls[otherIte->second]; |
822 | + otherp->theCollectionPuls[otherIte->second] = NULL; |
823 | + |
824 | + theCollectionPuls.push_back(otherPul); |
825 | + theCollectionPulsMap[otherIte->first] = theCollectionPuls.size() - 1; |
826 | + |
827 | + otherPul->switchPul(this); |
828 | ++otherIte; |
829 | } |
830 | } |
831 | |
832 | while (otherIte != otherEnd) |
833 | { |
834 | - theCollectionPuls[otherIte->first] = otherIte->second; |
835 | - otherIte->second->switchPul(this); |
836 | - otherIte->second = NULL; |
837 | + CollectionPul* otherPul = otherp->theCollectionPuls[otherIte->second]; |
838 | + otherp->theCollectionPuls[otherIte->second] = NULL; |
839 | + |
840 | + theCollectionPuls.push_back(otherPul); |
841 | + theCollectionPulsMap[otherIte->first] = theCollectionPuls.size() - 1; |
842 | + |
843 | + otherPul->switchPul(this); |
844 | + |
845 | ++otherIte; |
846 | } |
847 | |
848 | @@ -1470,14 +1461,14 @@ |
849 | ********************************************************************************/ |
850 | void PULImpl::checkTransformUpdates(const std::vector<store::Item*>& rootNodes) const |
851 | { |
852 | - ulong numRoots = (ulong)rootNodes.size(); |
853 | + csize numRoots = rootNodes.size(); |
854 | |
855 | - CollectionPulMap::const_iterator collIte = theCollectionPuls.begin(); |
856 | - CollectionPulMap::const_iterator collEnd = theCollectionPuls.end(); |
857 | + std::vector<CollectionPul*>::const_iterator collIte = theCollectionPuls.begin(); |
858 | + std::vector<CollectionPul*>::const_iterator collEnd = theCollectionPuls.end(); |
859 | |
860 | for (; collIte != collEnd; ++collIte) |
861 | { |
862 | - CollectionPul* pul = collIte->second; |
863 | + CollectionPul* pul = *collIte; |
864 | |
865 | NodeToUpdatesMap::iterator it = pul->theNodeToUpdatesMap.begin(); |
866 | NodeToUpdatesMap::iterator end = pul->theNodeToUpdatesMap.end(); |
867 | @@ -1488,7 +1479,7 @@ |
868 | |
869 | bool found = false; |
870 | |
871 | - for (ulong i = 0; i < numRoots; i++) |
872 | + for (csize i = 0; i < numRoots; i++) |
873 | { |
874 | XmlNode* rootNode = reinterpret_cast<XmlNode*>(rootNodes[i]); |
875 | |
876 | @@ -1533,12 +1524,12 @@ |
877 | std::set<store::Collection*> collections; |
878 | std::set<store::Collection*> truncated_collections; |
879 | |
880 | - CollectionPulMap::iterator collIte = theCollectionPuls.begin(); |
881 | - CollectionPulMap::iterator collEnd = theCollectionPuls.end(); |
882 | + CollectionPuls::iterator collIte = theCollectionPuls.begin(); |
883 | + CollectionPuls::iterator collEnd = theCollectionPuls.end(); |
884 | |
885 | for (; collIte != collEnd; ++collIte) |
886 | { |
887 | - store::Collection* collection = store->getCollection(collIte->first); |
888 | + store::Collection* collection = (*collIte)->theCollection; |
889 | |
890 | // The collection may not be created yet. |
891 | if (collection == NULL) |
892 | @@ -1546,7 +1537,7 @@ |
893 | |
894 | collections.insert(collection); |
895 | |
896 | - CollectionPul* pul = collIte->second; |
897 | + CollectionPul* pul = *collIte; |
898 | |
899 | if (pul->theTruncateCollectionList.size() > 0) |
900 | { |
901 | @@ -1570,6 +1561,7 @@ |
902 | (pul->theInsertIntoCollectionList[i]); |
903 | |
904 | csize numDocs = upd->numNodes(); |
905 | + |
906 | for (csize j = 0; j < numDocs; ++j) |
907 | pul->theInsertedDocs.push_back(static_cast<XmlNode*>(upd->getNode(j))); |
908 | } |
909 | @@ -1582,6 +1574,7 @@ |
910 | (pul->theDeleteFromCollectionList[i]); |
911 | |
912 | csize numDocs = upd->numNodes(); |
913 | + |
914 | for (csize j = 0; j < numDocs; ++j) |
915 | pul->theDeletedDocs.push_back(static_cast<XmlNode*>(upd->getNode(j))); |
916 | } |
917 | @@ -1689,8 +1682,8 @@ |
918 | ********************************************************************************/ |
919 | void PULImpl::applyUpdates(bool inheritNSBindings) |
920 | { |
921 | - CollectionPulMap::iterator collIte = theCollectionPuls.begin(); |
922 | - CollectionPulMap::iterator collEnd = theCollectionPuls.end(); |
923 | + CollectionPuls::iterator collIte = theCollectionPuls.begin(); |
924 | + CollectionPuls::iterator collEnd = theCollectionPuls.end(); |
925 | |
926 | theInheritNSBindings = inheritNSBindings; |
927 | |
928 | @@ -1701,7 +1694,7 @@ |
929 | // maintained incrementally w.r.t. updates in C. |
930 | for (; collIte != collEnd; ++collIte) |
931 | { |
932 | - CollectionPul* pul = collIte->second; |
933 | + CollectionPul* pul = *collIte; |
934 | pul->applyUpdates(); |
935 | } |
936 | |
937 | @@ -1726,7 +1719,7 @@ |
938 | // check integrity constraints for involved collections |
939 | for (collIte = theCollectionPuls.begin(); collIte != collEnd; ++collIte) |
940 | { |
941 | - CollectionPul* pul = collIte->second; |
942 | + CollectionPul* pul = *collIte; |
943 | |
944 | if (pul->theCollection != NULL) |
945 | { |
946 | @@ -1743,9 +1736,18 @@ |
947 | // Apply delete-collection primitives |
948 | for (collIte = theCollectionPuls.begin(); collIte != collEnd; ++collIte) |
949 | { |
950 | - CollectionPul* pul = collIte->second; |
951 | + CollectionPul* pul = *collIte; |
952 | applyList(pul->theDeleteCollectionList); |
953 | } |
954 | + |
955 | + // Refresh each incrementally maintained index. We need to do this here |
956 | + // because refreshIndices can raise an error (e.g. if the unique constraint |
957 | + // of an index is violated). |
958 | + for (collIte = theCollectionPuls.begin(); collIte != collEnd; ++collIte) |
959 | + { |
960 | + CollectionPul* pul = *collIte; |
961 | + pul->refreshIndexes(); |
962 | + } |
963 | } |
964 | catch (...) |
965 | { |
966 | @@ -1753,10 +1755,10 @@ |
967 | throw; |
968 | } |
969 | |
970 | - // |
971 | + // Perform actions that are not expected to raise any errors |
972 | for (collIte = theCollectionPuls.begin(); collIte != collEnd; ++collIte) |
973 | { |
974 | - CollectionPul* pul = collIte->second; |
975 | + CollectionPul* pul = *collIte; |
976 | pul->finalizeUpdates(); |
977 | } |
978 | |
979 | @@ -1790,12 +1792,12 @@ |
980 | { |
981 | undoList(theValidationList); |
982 | |
983 | - CollectionPulMap::iterator collIte = theCollectionPuls.begin(); |
984 | - CollectionPulMap::iterator collEnd = theCollectionPuls.end(); |
985 | + CollectionPuls::iterator collIte = theCollectionPuls.begin(); |
986 | + CollectionPuls::iterator collEnd = theCollectionPuls.end(); |
987 | |
988 | for (; collIte != collEnd; ++collIte) |
989 | { |
990 | - CollectionPul* pul = collIte->second; |
991 | + CollectionPul* pul = *collIte; |
992 | undoList(pul->theDeleteCollectionList); |
993 | } |
994 | |
995 | @@ -1807,7 +1809,7 @@ |
996 | |
997 | for (collIte = theCollectionPuls.begin(); collIte != collEnd; ++collIte) |
998 | { |
999 | - CollectionPul* pul = collIte->second; |
1000 | + CollectionPul* pul = *collIte; |
1001 | pul->undoUpdates(); |
1002 | } |
1003 | |
1004 | @@ -1851,10 +1853,7 @@ |
1005 | cleanList(theTruncateCollectionList); |
1006 | cleanList(theDeleteCollectionList); |
1007 | |
1008 | - cleanIndexDeltas(theBeforeIndexDeltas); |
1009 | - cleanIndexDeltas(theAfterIndexDeltas); |
1010 | - cleanIndexDeltas(theInsertedDocsIndexDeltas); |
1011 | - cleanIndexDeltas(theDeletedDocsIndexDeltas); |
1012 | + cleanIndexDeltas(); |
1013 | } |
1014 | |
1015 | |
1016 | @@ -1890,22 +1889,44 @@ |
1017 | } |
1018 | } |
1019 | |
1020 | -/******************************************************************************* |
1021 | - The comparison function for sorting the entries of an IndexDelta by the doc node |
1022 | -********************************************************************************/ |
1023 | -static bool cmp(const std::pair<store::Item_t, store::IndexKey*>& e1, |
1024 | - const std::pair<store::Item_t, store::IndexKey*>& e2) |
1025 | -{ |
1026 | - return e1.first.getp() < e2.first.getp(); |
1027 | -} |
1028 | - |
1029 | - |
1030 | -/******************************************************************************* |
1031 | - Compute the index contents on the modified docs, before any modifications |
1032 | - are actually applied. |
1033 | + |
1034 | +/******************************************************************************* |
1035 | + For each incrementally-maintained index associated with this collection, |
1036 | + compute the index contents on the modified and deleted docs, before any |
1037 | + modifications are actually applied. |
1038 | + |
1039 | + Note 1: If any docs are deleted, we have to remove from the before and after |
1040 | + deltas any entries for nodes belonging to the deleted docs. This is required |
1041 | + for the undo to work properly. For example, let E = [N, K] be an after-delta |
1042 | + entry, and let N be a node in a doc D that is going to be removed from the |
1043 | + collection. Then, during undo, the key pointer in E may be a dangling pointer. |
1044 | + |
1045 | + Note 2: Given note 1, we actually have to compute the delete-docs deltas |
1046 | + *before* any modification are actually applied. |
1047 | ********************************************************************************/ |
1048 | void CollectionPul::computeIndexBeforeDeltas() |
1049 | { |
1050 | + csize numIncrementalIndices = theIncrementalIndices.size(); |
1051 | + |
1052 | + if (numIncrementalIndices == 0) |
1053 | + return; |
1054 | + |
1055 | + std::vector<XmlNode*>::const_iterator docIte = theDeletedDocs.begin(); |
1056 | + std::vector<XmlNode*>::const_iterator docEnd = theDeletedDocs.end(); |
1057 | + |
1058 | + for (; docIte != docEnd; ++docIte) |
1059 | + { |
1060 | + theModifiedDocs.erase(*docIte); |
1061 | + |
1062 | + for (csize i = 0; i < numIncrementalIndices; ++i) |
1063 | + { |
1064 | + store::IndexEntryCreator* docIndexer = theIndexEntryCreators[i].getp(); |
1065 | + store::IndexDelta& indexDelta = theDeletedDocsIndexDeltas[i]; |
1066 | + |
1067 | + docIndexer->createIndexEntries((*docIte), indexDelta); |
1068 | + } |
1069 | + } |
1070 | + |
1071 | computeIndexDeltas(theBeforeIndexDeltas); |
1072 | } |
1073 | |
1074 | @@ -1917,21 +1938,19 @@ |
1075 | ********************************************************************************/ |
1076 | void CollectionPul::computeIndexAfterDeltas() |
1077 | { |
1078 | + csize numIncrementalIndices = theIncrementalIndices.size(); |
1079 | + |
1080 | + if (numIncrementalIndices == 0) |
1081 | + return; |
1082 | + |
1083 | computeIndexDeltas(theAfterIndexDeltas); |
1084 | |
1085 | - csize numIncrementalIndices = theIncrementalIndices.size(); |
1086 | - |
1087 | - if (numIncrementalIndices == 0) |
1088 | - return; |
1089 | - |
1090 | - theInsertedDocsIndexDeltas.resize(numIncrementalIndices); |
1091 | - |
1092 | std::vector<XmlNode*>::const_iterator docIte = theInsertedDocs.begin(); |
1093 | std::vector<XmlNode*>::const_iterator docEnd = theInsertedDocs.end(); |
1094 | |
1095 | for (; docIte != docEnd; ++docIte) |
1096 | { |
1097 | - for (ulong i = 0; i < numIncrementalIndices; ++i) |
1098 | + for (csize i = 0; i < numIncrementalIndices; ++i) |
1099 | { |
1100 | store::IndexEntryCreator* docIndexer = theIndexEntryCreators[i].getp(); |
1101 | store::IndexDelta& indexDelta = theInsertedDocsIndexDeltas[i]; |
1102 | @@ -1939,22 +1958,6 @@ |
1103 | docIndexer->createIndexEntries((*docIte), indexDelta); |
1104 | } |
1105 | } |
1106 | - |
1107 | - theDeletedDocsIndexDeltas.resize(numIncrementalIndices); |
1108 | - |
1109 | - docIte = theDeletedDocs.begin(); |
1110 | - docEnd = theDeletedDocs.end(); |
1111 | - |
1112 | - for (; docIte != docEnd; ++docIte) |
1113 | - { |
1114 | - for (ulong i = 0; i < numIncrementalIndices; ++i) |
1115 | - { |
1116 | - store::IndexEntryCreator* docIndexer = theIndexEntryCreators[i].getp(); |
1117 | - store::IndexDelta& indexDelta = theDeletedDocsIndexDeltas[i]; |
1118 | - |
1119 | - docIndexer->createIndexEntries((*docIte), indexDelta); |
1120 | - } |
1121 | - } |
1122 | } |
1123 | |
1124 | |
1125 | @@ -1965,19 +1968,14 @@ |
1126 | ********************************************************************************/ |
1127 | void CollectionPul::computeIndexDeltas(std::vector<store::IndexDelta>& deltas) |
1128 | { |
1129 | - ulong numIncrementalIndices = (ulong)theIncrementalIndices.size(); |
1130 | - |
1131 | - if (numIncrementalIndices == 0) |
1132 | - return; |
1133 | - |
1134 | - deltas.resize(numIncrementalIndices); |
1135 | + csize numIncrementalIndices = theIncrementalIndices.size(); |
1136 | |
1137 | std::set<XmlNode*>::const_iterator docIte = theModifiedDocs.begin(); |
1138 | std::set<XmlNode*>::const_iterator docEnd = theModifiedDocs.end(); |
1139 | |
1140 | for (; docIte != docEnd; ++docIte) |
1141 | { |
1142 | - for (ulong i = 0; i < numIncrementalIndices; ++i) |
1143 | + for (csize i = 0; i < numIncrementalIndices; ++i) |
1144 | { |
1145 | store::IndexEntryCreator* docIndexer = theIndexEntryCreators[i].getp(); |
1146 | store::IndexDelta& indexDelta = deltas[i]; |
1147 | @@ -1985,113 +1983,268 @@ |
1148 | docIndexer->createIndexEntries((*docIte), indexDelta); |
1149 | } |
1150 | } |
1151 | - |
1152 | - for (ulong i = 0; i < numIncrementalIndices; ++i) |
1153 | - { |
1154 | - store::IndexDelta& indexDelta = deltas[i]; |
1155 | - |
1156 | - std::sort(indexDelta.begin(), indexDelta.end(), cmp); |
1157 | - } |
1158 | -} |
1159 | - |
1160 | - |
1161 | -/******************************************************************************* |
1162 | - |
1163 | -********************************************************************************/ |
1164 | -void CollectionPul::refreshIndices() |
1165 | -{ |
1166 | - csize numIncrementalIndices = theTruncatedIndices.size(); |
1167 | - for (csize idx = 0; idx < numIncrementalIndices; ++idx) |
1168 | +} |
1169 | + |
1170 | + |
1171 | +/******************************************************************************* |
1172 | + |
1173 | +********************************************************************************/ |
1174 | +void CollectionPul::cleanIndexDeltas() |
1175 | +{ |
1176 | + csize numIncrementalIndices = theIncrementalIndices.size(); |
1177 | + |
1178 | + for (csize idx = 0; idx < numIncrementalIndices; ++idx) |
1179 | + { |
1180 | + store::IndexDelta::iterator ite; |
1181 | + store::IndexDelta::iterator end; |
1182 | + store::IndexDelta* delta; |
1183 | + csize numApplied; |
1184 | + |
1185 | + delta = &theInsertedDocsIndexDeltas[idx]; |
1186 | + if (delta) |
1187 | + { |
1188 | + numApplied = theNumInsertedDocsIndexDeltasApplied[idx]; |
1189 | + ite = delta->begin() + numApplied; |
1190 | + end = delta->end(); |
1191 | + for (; ite != end; ++ite) |
1192 | + { |
1193 | + delete (*ite).second; |
1194 | + } |
1195 | + } |
1196 | + |
1197 | + delta = &theAfterIndexDeltas[idx]; |
1198 | + if (delta) |
1199 | + { |
1200 | + numApplied = theNumAfterIndexDeltasApplied[idx]; |
1201 | + ite = delta->begin() + numApplied; |
1202 | + end = delta->end(); |
1203 | + for (; ite != end; ++ite) |
1204 | + { |
1205 | + delete (*ite).second; |
1206 | + } |
1207 | + } |
1208 | + |
1209 | + delta = &theDeletedDocsIndexDeltas[idx]; |
1210 | + if (delta) |
1211 | + { |
1212 | + ite = delta->begin(); |
1213 | + end = delta->end(); |
1214 | + for (; ite != end; ++ite) |
1215 | + { |
1216 | + delete (*ite).second; |
1217 | + } |
1218 | + } |
1219 | + |
1220 | + delta = &theBeforeIndexDeltas[idx]; |
1221 | + if (delta) |
1222 | + { |
1223 | + ite = delta->begin(); |
1224 | + end = delta->end(); |
1225 | + for (; ite != end; ++ite) |
1226 | + { |
1227 | + delete (*ite).second; |
1228 | + } |
1229 | + } |
1230 | + } |
1231 | +} |
1232 | + |
1233 | + |
1234 | +/******************************************************************************* |
1235 | + Refresh the incrementally maintained indexes. |
1236 | +********************************************************************************/ |
1237 | +void CollectionPul::refreshIndexes() |
1238 | +{ |
1239 | + csize numIncrementalIndices = theIncrementalIndices.size(); |
1240 | + |
1241 | + STORE_TRACE1("Refreshing indexes for collection " |
1242 | + << (theCollection ? |
1243 | + theCollection->getName()->getStringValue().c_str() : |
1244 | + "NULL")); |
1245 | + |
1246 | + for (csize idx = 0; idx < numIncrementalIndices; ++idx) |
1247 | + { |
1248 | + ValueIndex* index = static_cast<ValueIndex*>(theIncrementalIndices[idx]); |
1249 | + |
1250 | + STORE_TRACE2("Index size before do = " |
1251 | + << (!index->isTreeIndex() ? index->size() : 0)); |
1252 | + |
1253 | + store::IndexDelta& beforeDelta = theBeforeIndexDeltas[idx]; |
1254 | + store::IndexDelta& afterDelta = theAfterIndexDeltas[idx]; |
1255 | + store::IndexDelta& deletedDelta = theDeletedDocsIndexDeltas[idx]; |
1256 | + store::IndexDelta& insertedDelta = theInsertedDocsIndexDeltas[idx]; |
1257 | + |
1258 | + csize& numBeforeApplied = theNumBeforeIndexDeltasApplied[idx]; |
1259 | + csize& numAfterApplied = theNumAfterIndexDeltasApplied[idx]; |
1260 | + csize& numDeletedApplied = theNumDeletedDocsIndexDeltasApplied[idx]; |
1261 | + csize& numInsertedApplied = theNumInsertedDocsIndexDeltasApplied[idx]; |
1262 | + |
1263 | + store::IndexKey* key; |
1264 | + store::Item_t node; |
1265 | + |
1266 | + store::IndexDelta::iterator ite; |
1267 | + store::IndexDelta::iterator end; |
1268 | + |
1269 | + ite = beforeDelta.begin(); |
1270 | + end = beforeDelta.end(); |
1271 | + for (; ite != end; ++ite, ++numBeforeApplied) |
1272 | + { |
1273 | + index->remove((*ite).second, (*ite).first); |
1274 | + } |
1275 | + |
1276 | + ite = afterDelta.begin(); |
1277 | + end = afterDelta.end(); |
1278 | + for (; ite != end; ++ite, ++numAfterApplied) |
1279 | + { |
1280 | + node = (*ite).first; |
1281 | + key = (*ite).second; |
1282 | + |
1283 | + // If the index had its own key obj already, delete the key obj that was |
1284 | + // allocated during the delta creation. |
1285 | + if (index->insert((*ite).second, node)) |
1286 | + { |
1287 | + assert(key != (*ite).second); |
1288 | + delete key; |
1289 | + } |
1290 | + } |
1291 | + |
1292 | + STORE_TRACE2("deleted-delta size = " << deletedDelta.size()); |
1293 | + |
1294 | + ite = deletedDelta.begin(); |
1295 | + end = deletedDelta.end(); |
1296 | + for (; ite != end; ++ite, ++numDeletedApplied) |
1297 | + { |
1298 | + index->remove((*ite).second, (*ite).first); |
1299 | + } |
1300 | + |
1301 | + STORE_TRACE2("inserted-delta size = " << insertedDelta.size()); |
1302 | + |
1303 | + ite = insertedDelta.begin(); |
1304 | + end = insertedDelta.end(); |
1305 | + for (; ite != end; ++ite, ++numInsertedApplied) |
1306 | + { |
1307 | + node = (*ite).first; |
1308 | + key = (*ite).second; |
1309 | + |
1310 | + if (index->insert((*ite).second, node)) |
1311 | + { |
1312 | + assert(key != (*ite).second); |
1313 | + delete key; |
1314 | + } |
1315 | + } |
1316 | + |
1317 | + STORE_TRACE2("Index size after do = " |
1318 | + << (!index->isTreeIndex() ? index->size() : 0)); |
1319 | + } |
1320 | + |
1321 | + STORE_TRACE1("Refreshed indexes for collection " |
1322 | + << (theCollection ? |
1323 | + theCollection->getName()->getStringValue().c_str() : |
1324 | + "NULL") |
1325 | + << std::endl); |
1326 | +} |
1327 | + |
1328 | + |
1329 | +/******************************************************************************* |
1330 | + |
1331 | +********************************************************************************/ |
1332 | +void CollectionPul::undoRefreshIndexes() |
1333 | +{ |
1334 | + csize numIncrementalIndices = theIncrementalIndices.size(); |
1335 | + |
1336 | + STORE_TRACE1("Reverting indexes for collection " |
1337 | + << (theCollection ? |
1338 | + theCollection->getName()->getStringValue().c_str() : |
1339 | + "NULL") |
1340 | + << std::endl); |
1341 | + |
1342 | + for (csize idx = 0; idx < numIncrementalIndices; ++idx) |
1343 | + { |
1344 | + ValueIndex* index = static_cast<ValueIndex*>(theIncrementalIndices[idx]); |
1345 | + |
1346 | + STORE_TRACE2("Index size before undo = " |
1347 | + << (!index->isTreeIndex() ? index->size() : 0)); |
1348 | + |
1349 | + store::IndexDelta& beforeDelta = theBeforeIndexDeltas[idx]; |
1350 | + store::IndexDelta& afterDelta = theAfterIndexDeltas[idx]; |
1351 | + store::IndexDelta& insertedDelta = theInsertedDocsIndexDeltas[idx]; |
1352 | + store::IndexDelta& deletedDelta = theDeletedDocsIndexDeltas[idx]; |
1353 | + |
1354 | + csize numBeforeApplied = theNumBeforeIndexDeltasApplied[idx]; |
1355 | + csize numAfterApplied = theNumAfterIndexDeltasApplied[idx]; |
1356 | + csize numDeletedApplied = theNumDeletedDocsIndexDeltasApplied[idx]; |
1357 | + csize numInsertedApplied = theNumInsertedDocsIndexDeltasApplied[idx]; |
1358 | + |
1359 | + store::IndexDelta::reverse_iterator ite; |
1360 | + store::IndexDelta::reverse_iterator end; |
1361 | + |
1362 | + ite = insertedDelta.rbegin() + (insertedDelta.size() - numInsertedApplied); |
1363 | + end = insertedDelta.rend(); |
1364 | + for (; ite != end; ++ite) |
1365 | + { |
1366 | + index->remove((*ite).second, (*ite).first); |
1367 | + } |
1368 | + |
1369 | + ite = deletedDelta.rbegin() + (deletedDelta.size() - numDeletedApplied); |
1370 | + end = deletedDelta.rend(); |
1371 | + for (; ite != end; ++ite) |
1372 | + { |
1373 | + store::IndexKey* key = (*ite).second; |
1374 | + |
1375 | + // If the index takes ownership of the key obj, set the key ptr to null |
1376 | + // so that the key obj will not be deleted during cleanIndexDeltas(). |
1377 | + if (!index->insert(key, (*ite).first)) |
1378 | + { |
1379 | + assert(key == (*ite).second); |
1380 | + (*ite).second = NULL; |
1381 | + } |
1382 | + } |
1383 | + |
1384 | + ite = afterDelta.rbegin() + (afterDelta.size() - numAfterApplied); |
1385 | + end = afterDelta.rend(); |
1386 | + for (; ite != end; ++ite) |
1387 | + { |
1388 | + index->remove((*ite).second, (*ite).first); |
1389 | + } |
1390 | + |
1391 | + ite = beforeDelta.rbegin() + (beforeDelta.size() - numBeforeApplied); |
1392 | + end = beforeDelta.rend(); |
1393 | + for (; ite != end; ++ite) |
1394 | + { |
1395 | + store::IndexKey* key = (*ite).second; |
1396 | + |
1397 | + // If the index takes ownership of the key obj, set the key ptr to null |
1398 | + // so that the key obj will not be deleted during cleanIndexDeltas(). |
1399 | + if (!index->insert(key, (*ite).first)) |
1400 | + { |
1401 | + assert(key == (*ite).second); |
1402 | + (*ite).second = NULL; |
1403 | + } |
1404 | + } |
1405 | + |
1406 | + STORE_TRACE2("Index size after undo = " |
1407 | + << (!index->isTreeIndex() ? index->size() : 0)); |
1408 | + } |
1409 | + |
1410 | + STORE_TRACE1("Reverted indexes for collection " |
1411 | + << (theCollection ? |
1412 | + theCollection->getName()->getStringValue().c_str() : |
1413 | + "NULL") |
1414 | + << std::endl); |
1415 | +} |
1416 | + |
1417 | + |
1418 | +/******************************************************************************* |
1419 | + The method is called from CollectionPul::finalizeUpdates() |
1420 | +********************************************************************************/ |
1421 | +void CollectionPul::truncateIndexes() |
1422 | +{ |
1423 | + csize numTruncatedIndices = theTruncatedIndices.size(); |
1424 | + |
1425 | + for (csize idx = 0; idx < numTruncatedIndices; ++idx) |
1426 | { |
1427 | ValueIndex* index = static_cast<ValueIndex*>(theTruncatedIndices[idx]); |
1428 | index->clear(); |
1429 | } |
1430 | - |
1431 | - numIncrementalIndices = theIncrementalIndices.size(); |
1432 | - |
1433 | - for (csize idx = 0; idx < numIncrementalIndices; ++idx) |
1434 | - { |
1435 | - ValueIndex* index = static_cast<ValueIndex*>(theIncrementalIndices[idx]); |
1436 | - |
1437 | - // |
1438 | - // Referesh the index w.r.t. modified docs. |
1439 | - // |
1440 | - ValueIndexCompareFunction keyCmp(index->getNumColumns(), |
1441 | - index->getTimezone(), |
1442 | - index->getCollations()); |
1443 | - |
1444 | - store::IndexDelta& beforeDelta = theBeforeIndexDeltas[idx]; |
1445 | - store::IndexDelta& afterDelta = theAfterIndexDeltas[idx]; |
1446 | - store::IndexDelta& insertedDelta = theInsertedDocsIndexDeltas[idx]; |
1447 | - store::IndexDelta& deletedDelta = theDeletedDocsIndexDeltas[idx]; |
1448 | - |
1449 | - store::IndexDelta::iterator beforeIte = beforeDelta.begin(); |
1450 | - store::IndexDelta::iterator beforeEnd = beforeDelta.end(); |
1451 | - store::IndexDelta::iterator afterIte = afterDelta.begin(); |
1452 | - store::IndexDelta::iterator afterEnd = afterDelta.end(); |
1453 | - store::IndexDelta::iterator insertedIte = insertedDelta.begin(); |
1454 | - store::IndexDelta::iterator insertedEnd = insertedDelta.end(); |
1455 | - store::IndexDelta::iterator deletedIte = deletedDelta.begin(); |
1456 | - store::IndexDelta::iterator deletedEnd = deletedDelta.end(); |
1457 | - |
1458 | - while (beforeIte != beforeEnd && afterIte != afterEnd) |
1459 | - { |
1460 | - store::Item_t& beforeNode = (*beforeIte).first; |
1461 | - store::Item_t& afterNode = (*afterIte).first; |
1462 | - store::IndexKey* beforeKey = (*beforeIte).second; |
1463 | - store::IndexKey*& afterKey = (*afterIte).second; |
1464 | - |
1465 | - if (beforeNode == afterNode) |
1466 | - { |
1467 | - if (!keyCmp.equal(beforeKey, afterKey)) |
1468 | - { |
1469 | - index->remove(beforeKey, beforeNode); |
1470 | - index->insert(afterKey, afterNode); |
1471 | - } |
1472 | - |
1473 | - ++beforeIte; |
1474 | - ++afterIte; |
1475 | - } |
1476 | - else if (beforeNode < afterNode) |
1477 | - { |
1478 | - index->remove(beforeKey, beforeNode); |
1479 | - ++beforeIte; |
1480 | - } |
1481 | - else |
1482 | - { |
1483 | - index->insert(afterKey, afterNode); |
1484 | - ++afterIte; |
1485 | - } |
1486 | - } |
1487 | - |
1488 | - while (beforeIte != beforeEnd) |
1489 | - { |
1490 | - index->remove((*beforeIte).second, (*beforeIte).first); |
1491 | - ++beforeIte; |
1492 | - } |
1493 | - |
1494 | - while (afterIte != afterEnd) |
1495 | - { |
1496 | - index->insert((*afterIte).second, (*afterIte).first); |
1497 | - ++afterIte; |
1498 | - } |
1499 | - |
1500 | - // |
1501 | - // Referesh the index w.r.t. newly inserted docs. |
1502 | - // |
1503 | - for (; insertedIte != insertedEnd; ++insertedIte) |
1504 | - { |
1505 | - index->insert((*insertedIte).second, (*insertedIte).first); |
1506 | - } |
1507 | - |
1508 | - // |
1509 | - // Referesh the index w.r.t. deleted docs, |
1510 | - // |
1511 | - for (; deletedIte != deletedEnd; ++deletedIte) |
1512 | - { |
1513 | - index->remove((*deletedIte).second, (*deletedIte).first); |
1514 | - } |
1515 | - } |
1516 | } |
1517 | |
1518 | |
1519 | @@ -2100,6 +2253,37 @@ |
1520 | ********************************************************************************/ |
1521 | void CollectionPul::applyUpdates() |
1522 | { |
1523 | + csize numIncrementalIndices = theIncrementalIndices.size(); |
1524 | + |
1525 | +#if 0 |
1526 | + if (theCollection != NULL) |
1527 | + { |
1528 | + std::cout << "applying PUL for collection " |
1529 | + << theCollection->getName()->getStringValue() << std::endl; |
1530 | + } |
1531 | +#endif |
1532 | + |
1533 | + if (numIncrementalIndices > 0) |
1534 | + { |
1535 | + theBeforeIndexDeltas.resize(numIncrementalIndices); |
1536 | + theAfterIndexDeltas.resize(numIncrementalIndices); |
1537 | + theDeletedDocsIndexDeltas.resize(numIncrementalIndices); |
1538 | + theInsertedDocsIndexDeltas.resize(numIncrementalIndices); |
1539 | + |
1540 | + theNumBeforeIndexDeltasApplied.resize(numIncrementalIndices); |
1541 | + theNumAfterIndexDeltasApplied.resize(numIncrementalIndices); |
1542 | + theNumInsertedDocsIndexDeltasApplied.resize(numIncrementalIndices); |
1543 | + theNumDeletedDocsIndexDeltasApplied.resize(numIncrementalIndices); |
1544 | + |
1545 | + for (csize idx = 0; idx < numIncrementalIndices; ++idx) |
1546 | + { |
1547 | + theNumBeforeIndexDeltasApplied[idx] = 0; |
1548 | + theNumAfterIndexDeltasApplied[idx] = 0; |
1549 | + theNumInsertedDocsIndexDeltasApplied[idx] = 0; |
1550 | + theNumDeletedDocsIndexDeltasApplied[idx] = 0; |
1551 | + } |
1552 | + } |
1553 | + |
1554 | // Don't apply anything if the collection is going to be deleted. |
1555 | if (!theDeleteCollectionList.empty()) |
1556 | return; |
1557 | @@ -2214,6 +2398,71 @@ |
1558 | #endif |
1559 | throw; |
1560 | } |
1561 | + |
1562 | +#if 0 |
1563 | + if (theCollection != NULL) |
1564 | + { |
1565 | + std::cout << "applied PUL for collection " |
1566 | + << theCollection->getName()->getStringValue() << std::endl << std::endl; |
1567 | + } |
1568 | +#endif |
1569 | +} |
1570 | + |
1571 | + |
1572 | +/******************************************************************************* |
1573 | + |
1574 | +********************************************************************************/ |
1575 | +void CollectionPul::undoUpdates() |
1576 | +{ |
1577 | + if (!theIsApplied) |
1578 | + return; |
1579 | + |
1580 | + try |
1581 | + { |
1582 | + undoList(theTruncateCollectionList); |
1583 | + undoList(theDeleteFromCollectionList); |
1584 | + undoList(theInsertIntoCollectionList); |
1585 | + undoList(theCreateCollectionList); |
1586 | + |
1587 | +#ifndef ZORBA_NO_XMLSCHEMA |
1588 | + // Undo validate-in-place validation |
1589 | + undoList(theRevalidateList); |
1590 | + |
1591 | + // Undo apply-updates caused validation |
1592 | + if (theValidationPul) |
1593 | + { |
1594 | + undoList(static_cast<PULImpl *>(theValidationPul.getp())->theValidationList); |
1595 | + } |
1596 | +#endif |
1597 | + |
1598 | + // Undo text node merging |
1599 | + std::vector<TextNodeMerge>::reverse_iterator rit = theMergeList.rbegin(); |
1600 | + std::vector<TextNodeMerge>::reverse_iterator rend = theMergeList.rend(); |
1601 | + for (; rit != rend; ++rit) |
1602 | + { |
1603 | + TextNodeMerge merge = (*rit); |
1604 | + XmlNode* newTextNode = merge.theParent->getChild(merge.thePos); |
1605 | + ZORBA_ASSERT(newTextNode->getNodeKind()== store::StoreConsts::textNode); |
1606 | + |
1607 | + newTextNode->detach(); |
1608 | + |
1609 | + for (csize j = 0; j < merge.theMergedNodes.size(); ++j) |
1610 | + merge.theMergedNodes[j]->connect(merge.theParent, merge.thePos + j); |
1611 | + } |
1612 | + theMergeList.clear(); |
1613 | + |
1614 | + undoList(theDeleteList); |
1615 | + undoList(theReplaceContentList); |
1616 | + undoList(theReplaceNodeList); |
1617 | + undoList(theInsertList); |
1618 | + undoList(theDoFirstList); |
1619 | + |
1620 | + undoRefreshIndexes(); |
1621 | + } |
1622 | + catch (...) |
1623 | + { |
1624 | + ZORBA_FATAL(0, "Unexpected error during pul undo"); |
1625 | + } |
1626 | } |
1627 | |
1628 | |
1629 | @@ -2228,9 +2477,7 @@ |
1630 | { |
1631 | try |
1632 | { |
1633 | - // Refresh each incrementally maintained index using its before and after |
1634 | - // deltas. |
1635 | - refreshIndices(); |
1636 | + truncateIndexes(); |
1637 | |
1638 | // If necessary, adjust the position of trees inside this collection. |
1639 | if (theAdjustTreePositions) |
1640 | @@ -2241,9 +2488,8 @@ |
1641 | |
1642 | // Detach nodes that were deleted from their trees due to replace-node, |
1643 | // replace-content, or delete-node XQUF primitives. |
1644 | - csize numUpdates; |
1645 | + csize numUpdates = theReplaceNodeList.size(); |
1646 | |
1647 | - numUpdates = theReplaceNodeList.size(); |
1648 | for (csize i = 0; i < numUpdates; ++i) |
1649 | { |
1650 | UpdatePrimitive* upd = theReplaceNodeList[i]; |
1651 | @@ -2318,61 +2564,6 @@ |
1652 | } |
1653 | |
1654 | |
1655 | -/******************************************************************************* |
1656 | - |
1657 | -********************************************************************************/ |
1658 | -void CollectionPul::undoUpdates() |
1659 | -{ |
1660 | - if (!theIsApplied) |
1661 | - return; |
1662 | - |
1663 | - try |
1664 | - { |
1665 | - undoList(theTruncateCollectionList); |
1666 | - undoList(theDeleteFromCollectionList); |
1667 | - undoList(theInsertIntoCollectionList); |
1668 | - undoList(theCreateCollectionList); |
1669 | - |
1670 | -#ifndef ZORBA_NO_XMLSCHEMA |
1671 | - // Undo validate-in-place validation |
1672 | - undoList(theRevalidateList); |
1673 | - |
1674 | - // Undo apply-updates caused validation |
1675 | - if (theValidationPul) |
1676 | - { |
1677 | - undoList(static_cast<PULImpl *>(theValidationPul.getp())->theValidationList); |
1678 | - } |
1679 | -#endif |
1680 | - |
1681 | - // Undo text node merging |
1682 | - std::vector<TextNodeMerge>::reverse_iterator rit = theMergeList.rbegin(); |
1683 | - std::vector<TextNodeMerge>::reverse_iterator rend = theMergeList.rend(); |
1684 | - for (; rit != rend; ++rit) |
1685 | - { |
1686 | - TextNodeMerge merge = (*rit); |
1687 | - XmlNode* newTextNode = merge.theParent->getChild(merge.thePos); |
1688 | - ZORBA_ASSERT(newTextNode->getNodeKind()== store::StoreConsts::textNode); |
1689 | - |
1690 | - newTextNode->detach(); |
1691 | - |
1692 | - for (csize j = 0; j < merge.theMergedNodes.size(); ++j) |
1693 | - merge.theMergedNodes[j]->connect(merge.theParent, merge.thePos + j); |
1694 | - } |
1695 | - theMergeList.clear(); |
1696 | - |
1697 | - undoList(theDeleteList); |
1698 | - undoList(theReplaceContentList); |
1699 | - undoList(theReplaceNodeList); |
1700 | - undoList(theInsertList); |
1701 | - undoList(theDoFirstList); |
1702 | - } |
1703 | - catch (...) |
1704 | - { |
1705 | - ZORBA_FATAL(0, "Unexpected error during pul undo"); |
1706 | - } |
1707 | -} |
1708 | - |
1709 | - |
1710 | } // namespace simplestore |
1711 | } // namespace zorba |
1712 | /* vim:set et sw=2 ts=2: */ |
1713 | |
1714 | === modified file 'src/store/naive/simple_pul.h' |
1715 | --- src/store/naive/simple_pul.h 2012-04-24 12:39:38 +0000 |
1716 | +++ src/store/naive/simple_pul.h 2012-05-03 10:05:25 +0000 |
1717 | @@ -204,6 +204,11 @@ |
1718 | std::vector<store::IndexDelta> theInsertedDocsIndexDeltas; |
1719 | std::vector<store::IndexDelta> theDeletedDocsIndexDeltas; |
1720 | |
1721 | + std::vector<csize> theNumBeforeIndexDeltasApplied; |
1722 | + std::vector<csize> theNumAfterIndexDeltasApplied; |
1723 | + std::vector<csize> theNumInsertedDocsIndexDeltasApplied; |
1724 | + std::vector<csize> theNumDeletedDocsIndexDeltasApplied; |
1725 | + |
1726 | public: |
1727 | CollectionPul(PULImpl* pul, Collection* collection); |
1728 | |
1729 | @@ -211,18 +216,18 @@ |
1730 | |
1731 | void switchPul(PULImpl* pul); |
1732 | |
1733 | + void computeIndexBeforeDeltas(); |
1734 | + |
1735 | + void computeIndexAfterDeltas(); |
1736 | + |
1737 | + void refreshIndexes(); |
1738 | + |
1739 | void applyUpdates(); |
1740 | |
1741 | + void undoUpdates(); |
1742 | + |
1743 | void finalizeUpdates(); |
1744 | |
1745 | - void undoUpdates(); |
1746 | - |
1747 | - void computeIndexBeforeDeltas(); |
1748 | - |
1749 | - void computeIndexAfterDeltas(); |
1750 | - |
1751 | - void refreshIndices(); |
1752 | - |
1753 | void setAdjustTreePositions() { theAdjustTreePositions = true; } |
1754 | |
1755 | void addToCheckForMerge(InternalNode* parent) { theMergeToCheckSet.insert(parent); } |
1756 | @@ -231,6 +236,12 @@ |
1757 | void switchPulInPrimitivesList(std::vector<UpdatePrimitive*>& list); |
1758 | |
1759 | void computeIndexDeltas(std::vector<store::IndexDelta>& deltas); |
1760 | + |
1761 | + void cleanIndexDeltas(); |
1762 | + |
1763 | + void truncateIndexes(); |
1764 | + |
1765 | + void undoRefreshIndexes(); |
1766 | }; |
1767 | |
1768 | |
1769 | @@ -273,11 +284,14 @@ |
1770 | UP_LIST_CREATE_INDEX |
1771 | }; |
1772 | |
1773 | - typedef std::map<const QNameItem*, CollectionPul*> CollectionPulMap; |
1774 | + typedef std::vector<CollectionPul*> CollectionPuls; |
1775 | + |
1776 | + typedef std::map<const QNameItem*, csize> CollectionPulMap; |
1777 | |
1778 | protected: |
1779 | // XQUF and collection primitives, grouped by the collection that is being updated. |
1780 | - CollectionPulMap theCollectionPuls; |
1781 | + CollectionPuls theCollectionPuls; |
1782 | + CollectionPulMap theCollectionPulsMap; |
1783 | CollectionPul * theNoCollectionPul; |
1784 | CollectionPul * theLastPul; |
1785 | const QNameItem * theLastCollection; |
1786 | |
1787 | === modified file 'src/store/naive/store.cpp' |
1788 | --- src/store/naive/store.cpp 2012-05-03 09:09:01 +0000 |
1789 | +++ src/store/naive/store.cpp 2012-05-03 10:05:25 +0000 |
1790 | @@ -523,23 +523,24 @@ |
1791 | |
1792 | ********************************************************************************/ |
1793 | void Store::populateValueIndex( |
1794 | - const store::Index_t& aIndex, |
1795 | - store::Iterator* aSourceIter, |
1796 | - ulong aNumColumns) |
1797 | + const store::Index_t& idx, |
1798 | + store::Iterator* sourceIter, |
1799 | + ulong numColumns) |
1800 | { |
1801 | - if (!aSourceIter) |
1802 | + if (!sourceIter) |
1803 | return; |
1804 | |
1805 | store::Item_t domainItem; |
1806 | store::IndexKey* key = NULL; |
1807 | - |
1808 | - ValueIndex* index = static_cast<ValueIndex*>(aIndex.getp()); |
1809 | - |
1810 | - aSourceIter->open(); |
1811 | + store::IndexKey* key2 = NULL; |
1812 | + |
1813 | + ValueIndex* index = static_cast<ValueIndex*>(idx.getp()); |
1814 | + |
1815 | + sourceIter->open(); |
1816 | |
1817 | try |
1818 | { |
1819 | - while (aSourceIter->next(domainItem)) |
1820 | + while (sourceIter->next(domainItem)) |
1821 | { |
1822 | if (domainItem->isNode() && |
1823 | domainItem->getCollection() == NULL && |
1824 | @@ -549,12 +550,12 @@ |
1825 | ERROR_PARAMS(index->getName()->getStringValue())); |
1826 | } |
1827 | |
1828 | - if (key == NULL) |
1829 | - key = new store::IndexKey(aNumColumns); |
1830 | + if (key2 == key) |
1831 | + key = new store::IndexKey(numColumns); |
1832 | |
1833 | - for (ulong i = 0; i < aNumColumns; ++i) |
1834 | + for (ulong i = 0; i < numColumns; ++i) |
1835 | { |
1836 | - if (!aSourceIter->next((*key)[i])) |
1837 | + if (!sourceIter->next((*key)[i])) |
1838 | { |
1839 | // The source iter is a ValueIndexEntryBuilderIterator, whose next() |
1840 | // method is guaranteed to return true exactly once. The result from |
1841 | @@ -564,7 +565,8 @@ |
1842 | } |
1843 | } |
1844 | |
1845 | - index->insert(key, domainItem); |
1846 | + key2 = key; |
1847 | + index->insert(key2, domainItem); |
1848 | } |
1849 | } |
1850 | catch(...) |
1851 | @@ -572,14 +574,11 @@ |
1852 | if (key != NULL) |
1853 | delete key; |
1854 | |
1855 | - aSourceIter->close(); |
1856 | + sourceIter->close(); |
1857 | throw; |
1858 | } |
1859 | |
1860 | - if (key != NULL) |
1861 | - delete key; |
1862 | - |
1863 | - aSourceIter->close(); |
1864 | + sourceIter->close(); |
1865 | } |
1866 | |
1867 | |
1868 | |
1869 | === modified file 'src/store/naive/store_defs.h' |
1870 | --- src/store/naive/store_defs.h 2012-04-24 12:39:38 +0000 |
1871 | +++ src/store/naive/store_defs.h 2012-05-03 10:05:25 +0000 |
1872 | @@ -55,6 +55,28 @@ |
1873 | |
1874 | #define COMMENT_NODE(item) (reinterpret_cast<CommentNode*>((item).getp())) |
1875 | |
1876 | + |
1877 | +#ifndef NDEBUG |
1878 | + |
1879 | +#define STORE_TRACE(level, msg) \ |
1880 | +{ \ |
1881 | + if (level <= GET_STORE().getTraceLevel()) \ |
1882 | + std::cout << msg << std::endl; \ |
1883 | +} |
1884 | + |
1885 | +#define STORE_TRACE1(msg) STORE_TRACE(1, msg); |
1886 | +#define STORE_TRACE2(msg) STORE_TRACE(2, msg); |
1887 | +#define STORE_TRACE3(msg) STORE_TRACE(3, msg); |
1888 | + |
1889 | +#else |
1890 | + |
1891 | +#define STORE_TRACE(msg) |
1892 | +#define STORE_TRACE1(msg) |
1893 | +#define STORE_TRACE2(msg) |
1894 | +#define STORE_TRACE3(msg) |
1895 | + |
1896 | +#endif |
1897 | + |
1898 | } |
1899 | } |
1900 | #endif |
1901 | |
1902 | === added file 'test/rbkt/ExpQueryResults/zorba/index/delete_from_collection_01.xml.res' |
1903 | --- test/rbkt/ExpQueryResults/zorba/index/delete_from_collection_01.xml.res 1970-01-01 00:00:00 +0000 |
1904 | +++ test/rbkt/ExpQueryResults/zorba/index/delete_from_collection_01.xml.res 2012-05-03 10:05:25 +0000 |
1905 | @@ -0,0 +1,1 @@ |
1906 | +<foo uri="1"/> |
1907 | |
1908 | === added file 'test/rbkt/ExpQueryResults/zorba/index/undo2.xml.res' |
1909 | --- test/rbkt/ExpQueryResults/zorba/index/undo2.xml.res 1970-01-01 00:00:00 +0000 |
1910 | +++ test/rbkt/ExpQueryResults/zorba/index/undo2.xml.res 2012-05-03 10:05:25 +0000 |
1911 | @@ -0,0 +1,2 @@ |
1912 | +<?xml version="1.0" encoding="UTF-8"?> |
1913 | +zerr:ZDDY0024<person id="1" key="5"/><person id="2" key="5"/><person id="1" key="5"/><person id="2" key="5"/> |
1914 | |
1915 | === added file 'test/rbkt/ExpQueryResults/zorba/index/undo3.xml.res' |
1916 | --- test/rbkt/ExpQueryResults/zorba/index/undo3.xml.res 1970-01-01 00:00:00 +0000 |
1917 | +++ test/rbkt/ExpQueryResults/zorba/index/undo3.xml.res 2012-05-03 10:05:25 +0000 |
1918 | @@ -0,0 +1,6 @@ |
1919 | +<?xml version="1.0" encoding="UTF-8"?> |
1920 | +zerr:ZDDY0024 |
1921 | +<person id="1" key="5"/><person id="2" key="5"/> |
1922 | + |
1923 | + |
1924 | +<person id="1" key="5"/><person id="2" key="5"/> |
1925 | |
1926 | === added file 'test/rbkt/ExpQueryResults/zorba/index/unique.xml.res' |
1927 | --- test/rbkt/ExpQueryResults/zorba/index/unique.xml.res 1970-01-01 00:00:00 +0000 |
1928 | +++ test/rbkt/ExpQueryResults/zorba/index/unique.xml.res 2012-05-03 10:05:25 +0000 |
1929 | @@ -0,0 +1,1 @@ |
1930 | +zerr:ZDDY0024 zerr:ZDDY0024<person id="5"/><person id="5"/> |
1931 | |
1932 | === added file 'test/rbkt/Queries/zorba/index/delete_from_collection_01.xq' |
1933 | --- test/rbkt/Queries/zorba/index/delete_from_collection_01.xq 1970-01-01 00:00:00 +0000 |
1934 | +++ test/rbkt/Queries/zorba/index/delete_from_collection_01.xq 2012-05-03 10:05:25 +0000 |
1935 | @@ -0,0 +1,13 @@ |
1936 | + |
1937 | +import module namespace seq = "http://www.foo.com/default" at "delete_from_collection_01.xqlib"; |
1938 | + |
1939 | +seq:init(); |
1940 | + |
1941 | +variable $foo := seq:index(); |
1942 | + |
1943 | +seq:reset(); |
1944 | + |
1945 | +variable $bar := seq:index(); |
1946 | + |
1947 | + |
1948 | +$foo, $bar |
1949 | |
1950 | === added file 'test/rbkt/Queries/zorba/index/delete_from_collection_01.xqlib' |
1951 | --- test/rbkt/Queries/zorba/index/delete_from_collection_01.xqlib 1970-01-01 00:00:00 +0000 |
1952 | +++ test/rbkt/Queries/zorba/index/delete_from_collection_01.xqlib 2012-05-03 10:05:25 +0000 |
1953 | @@ -0,0 +1,42 @@ |
1954 | +module namespace seq = "http://www.foo.com/default"; |
1955 | + |
1956 | +import module namespace ddl = "http://www.zorba-xquery.com/modules/store/static/collections/ddl"; |
1957 | + |
1958 | +import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml"; |
1959 | + |
1960 | +import module namespace iddl = "http://www.zorba-xquery.com/modules/store/static/indexes/ddl"; |
1961 | + |
1962 | +import module namespace idml = "http://www.zorba-xquery.com/modules/store/static/indexes/dml"; |
1963 | + |
1964 | +declare namespace an = "http://www.zorba-xquery.com/annotations"; |
1965 | + |
1966 | + |
1967 | +declare collection seq:counters as node()*; |
1968 | + |
1969 | + |
1970 | +declare %an:automatic %an:unique %an:value-equality index seq:counters-by-uri |
1971 | + on nodes dml:collection(xs:QName("seq:counters")) |
1972 | + by xs:string(./@uri) as xs:string; |
1973 | + |
1974 | + |
1975 | +declare %an:sequential function seq:init() |
1976 | +{ |
1977 | + ddl:create(xs:QName("seq:counters")); |
1978 | + iddl:create(xs:QName("seq:counters-by-uri")); |
1979 | + dml:insert-nodes(xs:QName("seq:counters"), <foo uri="1"/>); |
1980 | +}; |
1981 | + |
1982 | + |
1983 | +declare function seq:index () |
1984 | +{ |
1985 | + idml:probe-index-point-value(xs:QName("seq:counters-by-uri"), "1") |
1986 | +}; |
1987 | + |
1988 | + |
1989 | +declare %an:sequential function seq:reset () |
1990 | +{ |
1991 | + dml:delete-nodes(idml:probe-index-point-value(xs:QName("seq:counters-by-uri"), "1")); |
1992 | +}; |
1993 | + |
1994 | + |
1995 | + |
1996 | |
1997 | === added file 'test/rbkt/Queries/zorba/index/undo2.xq' |
1998 | --- test/rbkt/Queries/zorba/index/undo2.xq 1970-01-01 00:00:00 +0000 |
1999 | +++ test/rbkt/Queries/zorba/index/undo2.xq 2012-05-03 10:05:25 +0000 |
2000 | @@ -0,0 +1,43 @@ |
2001 | +import module namespace u = "http://www.zorba-xquery.com/unique-index" at "undo2.xqlib"; |
2002 | + |
2003 | +import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml"; |
2004 | +import module namespace idml = "http://www.zorba-xquery.com/modules/store/static/indexes/dml"; |
2005 | + |
2006 | +declare namespace zerr = "http://www.zorba-xquery.com/errors"; |
2007 | +declare namespace err = "http://www.w3.org/2005/xqt-errors"; |
2008 | + |
2009 | +u:create-db(); |
2010 | + |
2011 | +dml:insert-nodes($u:auctions1, <person id="1" key="5"/>); |
2012 | +dml:insert-nodes($u:auctions1, <person id="2" key="5"/>); |
2013 | + |
2014 | +try |
2015 | +{{ |
2016 | + ( |
2017 | + dml:insert-nodes($u:auctions1, <person id="3" key="1"/>), |
2018 | + |
2019 | + insert node <foo/> into dml:collection($u:auctions1)[1], |
2020 | + |
2021 | + dml:insert-nodes($u:auctions1, <person id="4" key="5"/>), |
2022 | + |
2023 | + replace value of node dml:collection($u:auctions1)[1]/@key with "1", |
2024 | + |
2025 | + dml:insert-nodes($u:auctions2, <person id="1"/>), |
2026 | + dml:insert-nodes($u:auctions2, <person id="1"/>)); |
2027 | + () |
2028 | +}} |
2029 | +catch * |
2030 | +{ |
2031 | + $err:code |
2032 | +} |
2033 | +, |
2034 | + |
2035 | +dml:collection($u:auctions1) |
2036 | +, |
2037 | +idml:probe-index-point-value($u:PersonId1, "1") |
2038 | +, |
2039 | +idml:probe-index-point-value($u:PersonId1, "3") |
2040 | +, |
2041 | +idml:probe-index-point-value($u:PersonId1, "5") |
2042 | +, |
2043 | +dml:collection($u:auctions2) |
2044 | |
2045 | === added file 'test/rbkt/Queries/zorba/index/undo2.xqlib' |
2046 | --- test/rbkt/Queries/zorba/index/undo2.xqlib 1970-01-01 00:00:00 +0000 |
2047 | +++ test/rbkt/Queries/zorba/index/undo2.xqlib 2012-05-03 10:05:25 +0000 |
2048 | @@ -0,0 +1,36 @@ |
2049 | +module namespace auctions = "http://www.zorba-xquery.com/unique-index"; |
2050 | + |
2051 | +import module namespace ddl = "http://www.zorba-xquery.com/modules/store/static/collections/ddl"; |
2052 | +import module namespace iddl = "http://www.zorba-xquery.com/modules/store/static/indexes/ddl"; |
2053 | +import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml"; |
2054 | +import module namespace idml = "http://www.zorba-xquery.com/modules/store/static/indexes/dml"; |
2055 | + |
2056 | +declare namespace an = "http://www.zorba-xquery.com/annotations"; |
2057 | + |
2058 | +declare variable $auctions:auctions1 := xs:QName("auctions:auctions1"); |
2059 | +declare variable $auctions:PersonId1 := xs:QName("auctions:PersonId1"); |
2060 | +declare variable $auctions:auctions2 := xs:QName("auctions:auctions2"); |
2061 | +declare variable $auctions:PersonId2 := xs:QName("auctions:PersonId2"); |
2062 | + |
2063 | +declare %an:ordered collection auctions:auctions1 as node()*; |
2064 | + |
2065 | +declare %an:automatic %an:value-equality index auctions:PersonId1 |
2066 | +on nodes dml:collection(xs:QName("auctions:auctions1")) |
2067 | +by xs:string(./@key) as xs:string; |
2068 | + |
2069 | +declare %an:ordered collection auctions:auctions2 as node()*; |
2070 | + |
2071 | +declare %an:unique %an:automatic %an:value-range index auctions:PersonId2 |
2072 | +on nodes dml:collection(xs:QName("auctions:auctions2")) |
2073 | +by xs:string(./@id) as xs:string; |
2074 | + |
2075 | +declare %an:sequential function auctions:create-db() |
2076 | +{ |
2077 | + ddl:create($auctions:auctions1); |
2078 | + |
2079 | + ddl:create($auctions:auctions2); |
2080 | + |
2081 | + iddl:create($auctions:PersonId1); |
2082 | + |
2083 | + iddl:create($auctions:PersonId2); |
2084 | +}; |
2085 | |
2086 | === added file 'test/rbkt/Queries/zorba/index/undo3.xq' |
2087 | --- test/rbkt/Queries/zorba/index/undo3.xq 1970-01-01 00:00:00 +0000 |
2088 | +++ test/rbkt/Queries/zorba/index/undo3.xq 2012-05-03 10:05:25 +0000 |
2089 | @@ -0,0 +1,59 @@ |
2090 | +import module namespace u = "http://www.zorba-xquery.com/unique-index" at "undo2.xqlib"; |
2091 | + |
2092 | +import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml"; |
2093 | +import module namespace idml = "http://www.zorba-xquery.com/modules/store/static/indexes/dml"; |
2094 | + |
2095 | +declare namespace zerr = "http://www.zorba-xquery.com/errors"; |
2096 | +declare namespace err = "http://www.w3.org/2005/xqt-errors"; |
2097 | + |
2098 | +u:create-db(); |
2099 | + |
2100 | +dml:insert-nodes($u:auctions1, <person id="1" key="5"/>); |
2101 | +dml:insert-nodes($u:auctions1, <person id="2" key="5"/>); |
2102 | + |
2103 | +try |
2104 | +{{ |
2105 | + ( |
2106 | + dml:insert-nodes($u:auctions1, <person id="3" key="1"/>), |
2107 | + |
2108 | + insert node <foo/> into dml:collection($u:auctions1)[1], |
2109 | + |
2110 | + dml:insert-nodes($u:auctions1, <person id="4" key="5"/>), |
2111 | + |
2112 | + replace value of node dml:collection($u:auctions1)[1]/@key with "1", |
2113 | + |
2114 | + dml:delete-nodes-first($u:auctions1, 1), |
2115 | + |
2116 | + dml:insert-nodes($u:auctions2, <person id="1"/>), |
2117 | + dml:insert-nodes($u:auctions2, <person id="1"/>)); |
2118 | + () |
2119 | +}} |
2120 | +catch * |
2121 | +{ |
2122 | + $err:code |
2123 | +} |
2124 | +, |
2125 | +" |
2126 | +" |
2127 | +, |
2128 | +dml:collection($u:auctions1) |
2129 | +, |
2130 | +" |
2131 | +" |
2132 | +, |
2133 | +idml:probe-index-point-value($u:PersonId1, "1") |
2134 | +, |
2135 | +" |
2136 | +" |
2137 | +, |
2138 | +idml:probe-index-point-value($u:PersonId1, "3") |
2139 | +, |
2140 | +" |
2141 | +" |
2142 | +, |
2143 | +idml:probe-index-point-value($u:PersonId1, "5") |
2144 | +, |
2145 | +" |
2146 | +" |
2147 | +, |
2148 | +dml:collection($u:auctions2) |
2149 | |
2150 | === added file 'test/rbkt/Queries/zorba/index/unique.xq' |
2151 | --- test/rbkt/Queries/zorba/index/unique.xq 1970-01-01 00:00:00 +0000 |
2152 | +++ test/rbkt/Queries/zorba/index/unique.xq 2012-05-03 10:05:25 +0000 |
2153 | @@ -0,0 +1,50 @@ |
2154 | +import module namespace u = "http://www.zorba-xquery.com/unique-index" at "unique.xqlib"; |
2155 | + |
2156 | +import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml"; |
2157 | +import module namespace idml = "http://www.zorba-xquery.com/modules/store/static/indexes/dml"; |
2158 | + |
2159 | +declare namespace zerr = "http://www.zorba-xquery.com/errors"; |
2160 | +declare namespace err = "http://www.w3.org/2005/xqt-errors"; |
2161 | + |
2162 | +u:create-db(); |
2163 | + |
2164 | +dml:insert-nodes($u:auctions1, <person id="5"/>); |
2165 | + |
2166 | +try |
2167 | +{{ |
2168 | + (dml:insert-nodes($u:auctions1, <person id="1"/>), |
2169 | + dml:insert-nodes($u:auctions1, <person id="1"/>)); |
2170 | + () |
2171 | +}} |
2172 | +catch * |
2173 | +{ |
2174 | + $err:code |
2175 | +} |
2176 | +, |
2177 | + |
2178 | +try |
2179 | +{{ |
2180 | + ( |
2181 | + dml:insert-nodes($u:auctions1, <person id="1"/>), |
2182 | + dml:insert-nodes($u:auctions1, <person id="3"/>), |
2183 | + dml:delete-nodes-first($u:auctions1, 1), |
2184 | + |
2185 | + dml:insert-nodes($u:auctions2, <person id="1"/>), |
2186 | + dml:insert-nodes($u:auctions2, <person id="1"/>)); |
2187 | + () |
2188 | +}} |
2189 | +catch * |
2190 | +{ |
2191 | + $err:code |
2192 | +} |
2193 | +, |
2194 | + |
2195 | +dml:collection($u:auctions1) |
2196 | +, |
2197 | +idml:probe-index-point-value($u:PersonId1, "1") |
2198 | +, |
2199 | +idml:probe-index-point-value($u:PersonId1, "3") |
2200 | +, |
2201 | +idml:probe-index-point-value($u:PersonId1, "5") |
2202 | +, |
2203 | +dml:collection($u:auctions2) |
2204 | |
2205 | === added file 'test/rbkt/Queries/zorba/index/unique.xqlib' |
2206 | --- test/rbkt/Queries/zorba/index/unique.xqlib 1970-01-01 00:00:00 +0000 |
2207 | +++ test/rbkt/Queries/zorba/index/unique.xqlib 2012-05-03 10:05:25 +0000 |
2208 | @@ -0,0 +1,37 @@ |
2209 | +module namespace auctions = "http://www.zorba-xquery.com/unique-index"; |
2210 | + |
2211 | +import module namespace ddl = "http://www.zorba-xquery.com/modules/store/static/collections/ddl"; |
2212 | +import module namespace iddl = "http://www.zorba-xquery.com/modules/store/static/indexes/ddl"; |
2213 | +import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml"; |
2214 | +import module namespace idml = "http://www.zorba-xquery.com/modules/store/static/indexes/dml"; |
2215 | + |
2216 | +declare namespace an = "http://www.zorba-xquery.com/annotations"; |
2217 | + |
2218 | +declare variable $auctions:auctions1 := xs:QName("auctions:auctions1"); |
2219 | +declare variable $auctions:PersonId1 := xs:QName("auctions:PersonId1"); |
2220 | +declare variable $auctions:auctions2 := xs:QName("auctions:auctions2"); |
2221 | +declare variable $auctions:PersonId2 := xs:QName("auctions:PersonId2"); |
2222 | + |
2223 | +declare %an:ordered collection auctions:auctions1 as node()*; |
2224 | + |
2225 | +declare %an:unique %an:automatic %an:value-equality index auctions:PersonId1 |
2226 | +on nodes dml:collection(xs:QName("auctions:auctions1")) |
2227 | +by xs:string(./@id) as xs:string; |
2228 | + |
2229 | + |
2230 | +declare %an:ordered collection auctions:auctions2 as node()*; |
2231 | + |
2232 | +declare %an:unique %an:automatic %an:value-range index auctions:PersonId2 |
2233 | +on nodes dml:collection(xs:QName("auctions:auctions2")) |
2234 | +by xs:string(./@id) as xs:string; |
2235 | + |
2236 | +declare %an:sequential function auctions:create-db() |
2237 | +{ |
2238 | + ddl:create($auctions:auctions1); |
2239 | + |
2240 | + ddl:create($auctions:auctions2); |
2241 | + |
2242 | + iddl:create($auctions:PersonId1); |
2243 | + |
2244 | + iddl:create($auctions:PersonId2); |
2245 | +}; |
Attempt to merge into lp:zorba failed due to conflicts:
text conflict in ChangeLog