Merge lp:~zorba-coders/zorba/substring-intopt into lp:zorba

Proposed by Markos Zaharioudakis
Status: Merged
Approved by: Matthias Brantner
Approved revision: 10558
Merged at revision: 10551
Proposed branch: lp:~zorba-coders/zorba/substring-intopt
Merge into: lp:zorba
Diff against target: 1687 lines (+562/-197)
18 files modified
src/compiler/rewriter/rules/type_rules.cpp (+51/-40)
src/compiler/translator/translator.cpp (+19/-11)
src/functions/func_sequences_impl.cpp (+49/-49)
src/functions/func_strings_impl.cpp (+16/-3)
src/functions/pregenerated/func_strings.cpp (+37/-0)
src/functions/pregenerated/func_strings.h (+18/-0)
src/functions/pregenerated/function_enum.h (+2/-0)
src/runtime/spec/strings/strings.xml (+28/-6)
src/runtime/strings/pregenerated/strings.cpp (+28/-0)
src/runtime/strings/pregenerated/strings.h (+36/-0)
src/runtime/strings/strings_impl.cpp (+230/-88)
src/runtime/visitors/planiter_visitor_impl_code.h (+1/-0)
src/runtime/visitors/pregenerated/planiter_visitor.h (+5/-0)
src/runtime/visitors/pregenerated/printer_visitor.cpp (+14/-0)
src/runtime/visitors/pregenerated/printer_visitor.h (+3/-0)
src/runtime/visitors/printer_visitor_impl.h (+1/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/string/SubstringFunc/SubstringFunc2.iter (+10/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/string/SubstringFunc/SubstringFunc3.iter (+14/-0)
To merge this branch: bzr merge lp:~zorba-coders/zorba/substring-intopt
Reviewer Review Type Date Requested Status
Matthias Brantner Approve
Markos Zaharioudakis Approve
Review via email: mp+81949@code.launchpad.net

Commit message

Optimization of the fn:substring function in the case when its $start and $length arguments are integers.

Description of the change

Optimization of the fn:substring function in the case when its $start and $length arguments are integers.

To post a comment you must log in.
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job substring-intopt-2011-11-14T16-49-05.505Z is finished. The final status was:

All tests succeeded!

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1. Got: 2 Pending.

Revision history for this message
Markos Zaharioudakis (markos-za) wrote :

Some cleanup is needed:

1. The specialize method on the fn:substring function is not needed anymore
2. In the translator, the code that handles fn:subsequence and fn:substring is almost the same, and the 2 cases should be unified (like it is done in type_rules.cpp).

Also, SubstringIntOptIterator::nextImp() should use xs_integer, instead of xs_int, for start and len.

Revision history for this message
Carlos Manuel Lopez (charlie-lobo) wrote :

Did the changes, though the use of xs_integer instead of xs_int didn't work as elegantly as I expected. Can be easily undone though.

Revision history for this message
Matthias Brantner (matthias-brantner) wrote :

xs:integer has infinite precision. zstring's size_t is usually much smaller. Hence, I think we have to cast down to size_t and do range checking. If the integer is too big, the raised exception should be caught and a query location of the corresponding argument should be added.

Revision history for this message
Markos Zaharioudakis (markos-za) :
review: Approve
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

The attempt to merge lp:~zorba-coders/zorba/substring-intopt into lp:zorba failed. Below is the output from the failed tests.

CMake Error at /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake:272 (message):
  Validation queue job substring-intopt-2011-11-21T23-02-12.07Z is finished.
  The final status was:

  3 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Revision history for this message
Matthias Brantner (matthias-brantner) :
review: Approve
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job substring-intopt-2011-11-22T03-58-27.713Z is finished. The final status was:

All tests succeeded!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/compiler/rewriter/rules/type_rules.cpp'
2--- src/compiler/rewriter/rules/type_rules.cpp 2011-07-01 05:22:12 +0000
3+++ src/compiler/rewriter/rules/type_rules.cpp 2011-11-18 17:46:28 +0000
4@@ -1,12 +1,12 @@
5 /*
6 * Copyright 2006-2008 The FLWOR Foundation.
7- *
8+ *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12- *
13+ *
14 * http://www.apache.org/licenses/LICENSE-2.0
15- *
16+ *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20@@ -40,7 +40,7 @@
21 #include "diagnostics/assert.h"
22
23
24-namespace zorba
25+namespace zorba
26 {
27
28 static expr_t wrap_in_num_promotion(expr* arg, xqtref_t oldt, xqtref_t t);
29@@ -51,14 +51,14 @@
30
31
32 #if 0
33-RULE_REWRITE_POST(InferUDFTypes)
34+RULE_REWRITE_POST(InferUDFTypes)
35 {
36 if (node->get_expr_kind() != fo_expr_kind)
37 return NULL;
38
39 fo_expr* fo = static_cast<fo_expr*>(node);
40 user_function* udf = dynamic_cast<user_function*>(fo->get_func());
41-
42+
43 if (udf == NULL)
44 return NULL;
45
46@@ -93,11 +93,11 @@
47 TypeManager* tm = sctx->get_typemanager();
48 RootTypeManager& rtm = GENV_TYPESYSTEM;
49
50- if (node->get_expr_kind() == fo_expr_kind)
51+ if (node->get_expr_kind() == fo_expr_kind)
52 {
53 fo_expr* fo = static_cast<fo_expr *>(node);
54
55- if (fo->get_func()->getKind() == FunctionConsts::FN_BOOLEAN_1)
56+ if (fo->get_func()->getKind() == FunctionConsts::FN_BOOLEAN_1)
57 {
58 expr_t arg = fo->get_arg(0);
59 xqtref_t arg_type = arg->get_return_type();
60@@ -107,7 +107,7 @@
61 return NULL;
62 }
63
64- if (fo->get_func()->getKind() == FunctionConsts::FN_DATA_1)
65+ if (fo->get_func()->getKind() == FunctionConsts::FN_DATA_1)
66 {
67 expr_t arg = fo->get_arg(0);
68 xqtref_t arg_type = arg->get_return_type();
69@@ -121,7 +121,7 @@
70 cast_base_expr* pe;
71
72 // Note: the if cond is true for promote_expr, treat_expr, and cast_expr
73- if ((pe = dynamic_cast<cast_base_expr *>(node)) != NULL)
74+ if ((pe = dynamic_cast<cast_base_expr *>(node)) != NULL)
75 {
76 expr_t arg = pe->get_input();
77 xqtref_t arg_type = arg->get_return_type();
78@@ -143,7 +143,7 @@
79 (node->get_expr_kind() != cast_expr_kind &&
80 TypeOps::is_subtype(tm, *arg_type, *target_type, arg->get_loc())))
81 return arg;
82-
83+
84 xqtref_t arg_ptype = TypeOps::prime_type(tm, *arg_type);
85 xqtref_t target_ptype = TypeOps::prime_type(tm, *target_type);
86
87@@ -166,7 +166,7 @@
88 {
89 treat_expr* te = static_cast<treat_expr *> (pe);
90
91- if (te->get_check_prime() &&
92+ if (te->get_check_prime() &&
93 TypeOps::is_subtype(tm, *arg_ptype, *target_ptype, arg->get_loc()))
94 {
95 te->set_check_prime(false);
96@@ -205,7 +205,7 @@
97
98 static_context* sctx = node->get_sctx();
99
100- if (node->get_expr_kind() == fo_expr_kind)
101+ if (node->get_expr_kind() == fo_expr_kind)
102 {
103 fo_expr* fo = static_cast<fo_expr *>(node);
104 const function* fn = fo->get_func();
105@@ -219,7 +219,7 @@
106 {
107 expr_t argExpr = fo->get_arg(0);
108 xqtref_t argType = argExpr->get_return_type();
109- std::vector<xqtref_t> argTypes;
110+ std::vector<xqtref_t> argTypes;
111 argTypes.push_back(argType);
112
113 function* replacement = fn->specialize(sctx, argTypes);
114@@ -236,7 +236,7 @@
115 argExpr->get_loc(),
116 argExpr,
117 rtm.DOUBLE_TYPE_STAR);
118-
119+
120 fo->set_arg(0, promoteExpr);
121 }
122
123@@ -248,7 +248,7 @@
124 {
125 expr_t argExpr = fo->get_arg(0);
126 xqtref_t argType = argExpr->get_return_type();
127- std::vector<xqtref_t> argTypes;
128+ std::vector<xqtref_t> argTypes;
129 argTypes.push_back(argType);
130
131 function* replacement = fn->specialize(sctx, argTypes);
132@@ -259,7 +259,9 @@
133 }
134 }
135 else if (fnKind == FunctionConsts::FN_SUBSEQUENCE_2 ||
136- fnKind == FunctionConsts::FN_SUBSEQUENCE_3)
137+ fnKind == FunctionConsts::FN_SUBSEQUENCE_3 ||
138+ fnKind == FunctionConsts::FN_SUBSTRING_2 ||
139+ fnKind == FunctionConsts::FN_SUBSTRING_3)
140 {
141 expr_t posExpr = fo->get_arg(1);
142 if (posExpr->get_expr_kind() == promote_expr_kind)
143@@ -286,18 +288,26 @@
144 if (TypeOps::is_subtype(tm, *posType, *rtm.INTEGER_TYPE_ONE, posLoc) &&
145 TypeOps::is_subtype(tm, *lenType, *rtm.INTEGER_TYPE_ONE, lenLoc))
146 {
147- fo->set_func(GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_3));
148+ if (fnKind == FunctionConsts::FN_SUBSTRING_3)
149+ fo->set_func(GET_BUILTIN_FUNCTION(OP_SUBSTRING_INT_3));
150+ else
151+ fo->set_func(GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_3));
152+
153 fo->set_arg(1, posExpr);
154 fo->set_arg(1, lenExpr);
155 }
156 }
157 else if (TypeOps::is_subtype(tm, *posType, *rtm.INTEGER_TYPE_ONE, posLoc))
158 {
159- fo->set_func(GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_2));
160+ if (fnKind == FunctionConsts::FN_SUBSTRING_2)
161+ fo->set_func(GET_BUILTIN_FUNCTION(OP_SUBSTRING_INT_2));
162+ else
163+ fo->set_func(GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_2));
164+
165 fo->set_arg(1, posExpr);
166 }
167 }
168- else if (fo->num_args() == 2)
169+ else if (fo->num_args() == 2)
170 {
171 expr* arg0 = fo->get_arg(0);
172 expr* arg1 = fo->get_arg(1);
173@@ -317,7 +327,7 @@
174 if (specialize_numeric(fo, sctx) != NULL)
175 return node;
176 }
177- else if (props.specializeCmp() && fn->isComparisonFunction())
178+ else if (props.specializeCmp() && fn->isComparisonFunction())
179 {
180 if (fn->isGeneralComparisonFunction())
181 {
182@@ -325,39 +335,39 @@
183 argTypes.push_back(t0);
184 argTypes.push_back(t1);
185 function* replacement = fn->specialize(sctx, argTypes);
186- if (replacement != NULL)
187+ if (replacement != NULL)
188 {
189 fo->set_func(replacement);
190 return node;
191 }
192 }
193- else if (fn->isValueComparisonFunction())
194+ else if (fn->isValueComparisonFunction())
195 {
196 xqtref_t string_type = rtm.STRING_TYPE_QUESTION;
197 bool string_cmp = true;
198 expr_t nargs[2];
199
200- for (int i = 0; i < 2; ++i)
201+ for (int i = 0; i < 2; ++i)
202 {
203 expr* arg = (i == 0 ? arg0 : arg1);
204 xqtref_t type = (i == 0 ? t0 : t1);
205 const QueryLoc& loc = arg->get_loc();
206
207- if (TypeOps::is_subtype(tm, *type, *rtm.UNTYPED_ATOMIC_TYPE_QUESTION, loc))
208+ if (TypeOps::is_subtype(tm, *type, *rtm.UNTYPED_ATOMIC_TYPE_QUESTION, loc))
209 {
210 nargs[i] = new cast_expr(arg->get_sctx(),
211 arg->get_loc(),
212 arg,
213 string_type);
214 }
215- else if (! TypeOps::is_subtype(tm, *type, *string_type, loc))
216+ else if (! TypeOps::is_subtype(tm, *type, *string_type, loc))
217 {
218 string_cmp = false;
219 break;
220 }
221 }
222
223- if (string_cmp)
224+ if (string_cmp)
225 {
226 for (int i = 0; i < 2; i++)
227 {
228@@ -369,13 +379,13 @@
229 argTypes.push_back(string_type);
230 argTypes.push_back(string_type);
231 function* replacement = fn->specialize(sctx, argTypes);
232- if (replacement != NULL)
233+ if (replacement != NULL)
234 {
235 fo->set_func(replacement);
236 return node;
237- }
238+ }
239 }
240- else if (TypeOps::is_numeric(tm, *t0) && TypeOps::is_numeric(tm, *t1))
241+ else if (TypeOps::is_numeric(tm, *t0) && TypeOps::is_numeric(tm, *t1))
242 {
243 xqtref_t aType = specialize_numeric(fo, sctx);
244 if (aType != NULL)
245@@ -454,23 +464,23 @@
246 xqtref_t t0 = arg0->get_return_type();
247 xqtref_t t1 = arg1->get_return_type();
248
249- xqtref_t aType =
250+ xqtref_t aType =
251 TypeOps::arithmetic_type(tm,
252 *t0,
253 *t1,
254 fn->arithmeticKind() == ArithmeticConsts::DIVISION);
255-
256+
257 if (!TypeOps::is_numeric(tm, *aType))
258 {
259 return NULL;
260 }
261
262- std::vector<xqtref_t> argTypes;
263- argTypes.push_back(aType);
264- argTypes.push_back(aType);
265-
266+ std::vector<xqtref_t> argTypes;
267+ argTypes.push_back(aType);
268+ argTypes.push_back(aType);
269+
270 function* replacement = fn->specialize(sctx, argTypes);
271- if (replacement != NULL)
272+ if (replacement != NULL)
273 {
274 fo->set_func(replacement);
275
276@@ -482,7 +492,7 @@
277
278 if (newArg1 != NULL)
279 fo->set_arg(1, newArg1);
280-
281+
282 return aType;
283 }
284
285@@ -490,7 +500,7 @@
286 }
287
288
289-static expr_t wrap_in_num_promotion(expr* arg, xqtref_t oldt, xqtref_t t)
290+static expr_t wrap_in_num_promotion(expr* arg, xqtref_t oldt, xqtref_t t)
291 {
292 TypeManager* tm = arg->get_type_manager();
293
294@@ -512,7 +522,7 @@
295 }
296
297
298-static function* flip_value_cmp(FunctionConsts::FunctionKind kind)
299+static function* flip_value_cmp(FunctionConsts::FunctionKind kind)
300 {
301 FunctionConsts::FunctionKind newKind;
302
303@@ -594,3 +604,4 @@
304
305 }
306 /* vim:set et sw=2 ts=2: */
307+/* vim:set et sw=2 ts=2: */
308
309=== modified file 'src/compiler/translator/translator.cpp'
310--- src/compiler/translator/translator.cpp 2011-11-16 04:02:48 +0000
311+++ src/compiler/translator/translator.cpp 2011-11-18 17:46:28 +0000
312@@ -3204,7 +3204,7 @@
313 signature sig(qnameItem, paramTypes, returnType, isVariadic);
314
315 // Get the scripting kind of the function
316- bool isSequential = (theAnnotations ?
317+ bool isSequential = (theAnnotations ?
318 ZANN_CONTAINS(zann_sequential) :
319 false);
320
321@@ -4173,12 +4173,12 @@
322 if (theAnnotations)
323 {
324 if (ZANN_CONTAINS(zann_general_equality) ||
325- ZANN_CONTAINS(zann_general_range))
326+ ZANN_CONTAINS(zann_general_range))
327 {
328 index->setGeneral(true);
329 }
330 if (ZANN_CONTAINS(zann_general_range) ||
331- ZANN_CONTAINS(zann_value_range))
332+ ZANN_CONTAINS(zann_value_range))
333 {
334 index->setMethod(IndexDecl::TREE);
335 }
336@@ -7245,7 +7245,7 @@
337 /*******************************************************************************
338 QuantifiedExpr ::= ("some" | "every") QVarInDeclList "satisfies" ExprSingle
339
340- QVarInDeclList ::= "$" VarName TypeDeclaration? "in" ExprSingle
341+ QVarInDeclList ::= "$" VarName TypeDeclaration? "in" ExprSingle
342 ("," "$" VarName TypeDeclaration? "in" ExprSingle)*
343
344 A universally quantified expr is translated into a flwor expr:
345@@ -9190,13 +9190,13 @@
346 fo_expr_t condExpr;
347 std::vector<expr_t> condOperands(3);
348
349- condOperands[0] =
350+ condOperands[0] =
351 new instanceof_expr(theRootSctx, loc, predvar, rtm.DECIMAL_TYPE_QUESTION, true);
352
353- condOperands[1] =
354+ condOperands[1] =
355 new instanceof_expr(theRootSctx, loc, predvar, rtm.DOUBLE_TYPE_QUESTION, true);
356
357- condOperands[2] =
358+ condOperands[2] =
359 new instanceof_expr(theRootSctx, loc, predvar, rtm.FLOAT_TYPE_QUESTION, true);
360
361 condExpr = new fo_expr(theRootSctx, loc, GET_BUILTIN_FUNCTION(OP_OR_N), condOperands);
362@@ -9695,6 +9695,8 @@
363 }
364 case FunctionConsts::FN_SUBSEQUENCE_2:
365 case FunctionConsts::FN_SUBSEQUENCE_3:
366+ case FunctionConsts::FN_SUBSTRING_2:
367+ case FunctionConsts::FN_SUBSTRING_3:
368 {
369 std::reverse(arguments.begin(), arguments.end());
370
371@@ -9704,7 +9706,10 @@
372 {
373 if (TypeOps::is_subtype(tm, *posType, *GENV_TYPESYSTEM.INTEGER_TYPE_STAR, loc))
374 {
375- f = GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_2);
376+ if(f->getKind() == FunctionConsts::FN_SUBSTRING_2)
377+ f = GET_BUILTIN_FUNCTION(OP_SUBSTRING_INT_2);
378+ else
379+ f = GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_2);
380 }
381 }
382 else
383@@ -9714,7 +9719,10 @@
384 if (TypeOps::is_subtype(tm, *posType, *GENV_TYPESYSTEM.INTEGER_TYPE_STAR, loc) &&
385 TypeOps::is_subtype(tm, *lenType, *GENV_TYPESYSTEM.INTEGER_TYPE_STAR, loc))
386 {
387- f = GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_3);
388+ if(f->getKind() == FunctionConsts::FN_SUBSTRING_3)
389+ f = GET_BUILTIN_FUNCTION(OP_SUBSTRING_INT_3);
390+ else
391+ f = GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_3);
392 }
393 }
394
395@@ -10359,11 +10367,11 @@
396 rchandle<QName> qname = v.getQName();
397 uint32_t arity = 0;
398
399- try
400+ try
401 {
402 arity = to_xs_unsignedInt(v.getArity());
403 }
404- catch ( std::range_error const& )
405+ catch ( std::range_error const& )
406 {
407 RAISE_ERROR(err::XPST0017, loc,
408 ERROR_PARAMS(v.getArity(), ZED(NoParseFnArity)));
409
410=== modified file 'src/functions/func_sequences_impl.cpp'
411--- src/functions/func_sequences_impl.cpp 2011-10-19 15:28:51 +0000
412+++ src/functions/func_sequences_impl.cpp 2011-11-18 17:46:28 +0000
413@@ -286,55 +286,6 @@
414
415
416 /******************************************************************************
417-fn:count
418-*******************************************************************************/
419-PlanIter_t fn_count::codegen(
420- CompilerCB*,
421- static_context* sctx,
422- const QueryLoc& loc,
423- std::vector<PlanIter_t>& argv,
424- AnnotationHolder& ann) const
425-{
426- const std::type_info& counted_type = typeid(*argv[0]);
427-
428- if (typeid(ZorbaCollectionIterator) == counted_type)
429- {
430- ZorbaCollectionIterator& collection =
431- static_cast<ZorbaCollectionIterator&>(*argv[0]);
432-
433- if (collection.isDynamic())
434- {
435- return new CountCollectionIterator(sctx,
436- loc,
437- collection.getChildren(),
438- CountCollectionIterator::ZORBADYNAMIC);
439- }
440- else
441- {
442- return new CountCollectionIterator(sctx,
443- loc,
444- collection.getChildren(),
445- CountCollectionIterator::ZORBASTATIC);
446- }
447- }
448- else if (typeid(FnCollectionIterator) == counted_type)
449- {
450- FnCollectionIterator& collection =
451- static_cast<FnCollectionIterator&>(*argv[0]);
452-
453- return new CountCollectionIterator(sctx,
454- loc,
455- collection.getChildren(),
456- CountCollectionIterator::W3C);
457- }
458- else
459- {
460- return new FnCountIterator(sctx, loc, argv);
461- }
462-}
463-
464-
465-/******************************************************************************
466
467 *******************************************************************************/
468 xqtref_t op_zorba_subsequence_int::getReturnType(
469@@ -510,6 +461,55 @@
470 }
471
472
473+/******************************************************************************
474+fn:count
475+*******************************************************************************/
476+PlanIter_t fn_count::codegen(
477+ CompilerCB*,
478+ static_context* sctx,
479+ const QueryLoc& loc,
480+ std::vector<PlanIter_t>& argv,
481+ AnnotationHolder& ann) const
482+{
483+ const std::type_info& counted_type = typeid(*argv[0]);
484+
485+ if (typeid(ZorbaCollectionIterator) == counted_type)
486+ {
487+ ZorbaCollectionIterator& collection =
488+ static_cast<ZorbaCollectionIterator&>(*argv[0]);
489+
490+ if (collection.isDynamic())
491+ {
492+ return new CountCollectionIterator(sctx,
493+ loc,
494+ collection.getChildren(),
495+ CountCollectionIterator::ZORBADYNAMIC);
496+ }
497+ else
498+ {
499+ return new CountCollectionIterator(sctx,
500+ loc,
501+ collection.getChildren(),
502+ CountCollectionIterator::ZORBASTATIC);
503+ }
504+ }
505+ else if (typeid(FnCollectionIterator) == counted_type)
506+ {
507+ FnCollectionIterator& collection =
508+ static_cast<FnCollectionIterator&>(*argv[0]);
509+
510+ return new CountCollectionIterator(sctx,
511+ loc,
512+ collection.getChildren(),
513+ CountCollectionIterator::W3C);
514+ }
515+ else
516+ {
517+ return new FnCountIterator(sctx, loc, argv);
518+ }
519+}
520+
521+
522 /*******************************************************************************
523
524 ********************************************************************************/
525
526=== modified file 'src/functions/func_strings_impl.cpp'
527--- src/functions/func_strings_impl.cpp 2011-06-14 17:26:33 +0000
528+++ src/functions/func_strings_impl.cpp 2011-11-18 17:46:28 +0000
529@@ -15,8 +15,16 @@
530 */
531 #include "stdafx.h"
532
533+#include "common/shared_types.h"
534+#include "types/typeops.h"
535+
536+#include "functions/function.h"
537+#include "functions/function_impl.h"
538+
539 #include "functions/func_strings.h"
540
541+#include "system/globalenv.h"
542+
543 #include "compiler/expression/expr_consts.h"
544
545
546@@ -28,19 +36,24 @@
547 ********************************************************************************/
548 BoolAnnotationValue fn_concat::ignoresSortedNodes(
549 expr* fo,
550- ulong input) const
551+ ulong input) const
552 {
553 return ANNOTATION_TRUE;
554 }
555
556
557 BoolAnnotationValue fn_concat::ignoresDuplicateNodes(
558- expr* fo,
559- ulong input) const
560+ expr* fo,
561+ ulong input) const
562 {
563 return ANNOTATION_TRUE;
564 }
565
566+function* fn_substring::specialize( static_context* sctx,
567+ const std::vector<xqtref_t>& argTypes) const
568+{
569+ return NULL;
570+}
571
572 }
573
574
575=== modified file 'src/functions/pregenerated/func_strings.cpp'
576--- src/functions/pregenerated/func_strings.cpp 2011-11-09 05:42:08 +0000
577+++ src/functions/pregenerated/func_strings.cpp 2011-11-18 17:46:28 +0000
578@@ -110,6 +110,16 @@
579 return new SubstringIterator(sctx, loc, argv);
580 }
581
582+PlanIter_t op_substring_int::codegen(
583+ CompilerCB*,
584+ static_context* sctx,
585+ const QueryLoc& loc,
586+ std::vector<PlanIter_t>& argv,
587+ AnnotationHolder& ann) const
588+{
589+ return new SubstringIntOptIterator(sctx, loc, argv);
590+}
591+
592 PlanIter_t fn_string_length::codegen(
593 CompilerCB*,
594 static_context* sctx,
595@@ -443,6 +453,33 @@
596 {
597
598
599+ DECL_WITH_KIND(sctx, op_substring_int,
600+ (createQName("http://www.zorba-xquery.com/internal/xquery-ops","","substring_int"),
601+ GENV_TYPESYSTEM.STRING_TYPE_QUESTION,
602+ GENV_TYPESYSTEM.INTEGER_TYPE_ONE,
603+ GENV_TYPESYSTEM.STRING_TYPE_ONE),
604+ FunctionConsts::OP_SUBSTRING_INT_2);
605+
606+ }
607+
608+
609+ {
610+
611+
612+ DECL_WITH_KIND(sctx, op_substring_int,
613+ (createQName("http://www.zorba-xquery.com/internal/xquery-ops","","substring_int"),
614+ GENV_TYPESYSTEM.STRING_TYPE_QUESTION,
615+ GENV_TYPESYSTEM.INTEGER_TYPE_ONE,
616+ GENV_TYPESYSTEM.INTEGER_TYPE_ONE,
617+ GENV_TYPESYSTEM.STRING_TYPE_ONE),
618+ FunctionConsts::OP_SUBSTRING_INT_3);
619+
620+ }
621+
622+
623+ {
624+
625+
626 DECL_WITH_KIND(sctx, fn_string_length,
627 (createQName("http://www.w3.org/2005/xpath-functions","","string-length"),
628 GENV_TYPESYSTEM.INTEGER_TYPE_ONE),
629
630=== modified file 'src/functions/pregenerated/func_strings.h'
631--- src/functions/pregenerated/func_strings.h 2011-11-09 05:42:08 +0000
632+++ src/functions/pregenerated/func_strings.h 2011-11-18 17:46:28 +0000
633@@ -141,6 +141,24 @@
634
635 }
636
637+ bool specializable() const { return true; }
638+
639+ function* specialize( static_context* sctx,
640+ const std::vector<xqtref_t>& argTypes) const;
641+
642+ CODEGEN_DECL();
643+};
644+
645+
646+//op:substring_int
647+class op_substring_int : public function
648+{
649+public:
650+ op_substring_int(const signature& sig, FunctionConsts::FunctionKind kind)
651+ : function(sig, kind) {
652+
653+}
654+
655 CODEGEN_DECL();
656 };
657
658
659=== modified file 'src/functions/pregenerated/function_enum.h'
660--- src/functions/pregenerated/function_enum.h 2011-11-15 08:23:20 +0000
661+++ src/functions/pregenerated/function_enum.h 2011-11-18 17:46:28 +0000
662@@ -338,6 +338,8 @@
663 FN_STRING_JOIN_2,
664 FN_SUBSTRING_2,
665 FN_SUBSTRING_3,
666+ OP_SUBSTRING_INT_2,
667+ OP_SUBSTRING_INT_3,
668 FN_STRING_LENGTH_0,
669 FN_STRING_LENGTH_1,
670 FN_NORMALIZE_SPACE_0,
671
672=== modified file 'src/runtime/spec/strings/strings.xml'
673--- src/runtime/spec/strings/strings.xml 2011-06-17 14:40:56 +0000
674+++ src/runtime/spec/strings/strings.xml 2011-11-18 17:46:28 +0000
675@@ -11,7 +11,7 @@
676 xmlns:zorba="http://www.zorba-xquery.com"
677 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
678 xsi:schemaLocation="http://www.zorba-xquery.com ../runtime.xsd">
679-
680+
681 <zorba:header>
682 <zorba:include form="Quoted">zorbautils/checked_vector.h</zorba:include>
683 <zorba:include form="Quoted">zorbatypes/schema_types.h</zorba:include>
684@@ -181,17 +181,39 @@
685 fn:substring
686 </zorba:description>
687
688+ <zorba:function specializable="true">
689+ <zorba:signature localname="substring" prefix="fn">
690+ <zorba:param>xs:string?</zorba:param>
691+ <zorba:param>xs:double</zorba:param>
692+ <zorba:output>xs:string</zorba:output>
693+ </zorba:signature>
694+
695+ <zorba:signature localname="substring" prefix="fn">
696+ <zorba:param>xs:string?</zorba:param>
697+ <zorba:param>xs:double</zorba:param>
698+ <zorba:param>xs:double</zorba:param>
699+ <zorba:output>xs:string</zorba:output>
700+ </zorba:signature>
701+ </zorba:function>
702+</zorba:iterator>
703+
704+<zorba:iterator name="SubstringIntOptIterator">
705+
706+ <zorba:description author="Zorba Team">
707+ fn:substring
708+ </zorba:description>
709+
710 <zorba:function>
711- <zorba:signature localname="substring" prefix="fn">
712+ <zorba:signature localname="substring_int" prefix="op">
713 <zorba:param>xs:string?</zorba:param>
714- <zorba:param>xs:double</zorba:param>
715+ <zorba:param>xs:integer</zorba:param>
716 <zorba:output>xs:string</zorba:output>
717 </zorba:signature>
718
719- <zorba:signature localname="substring" prefix="fn">
720+ <zorba:signature localname="substring_int" prefix="op">
721 <zorba:param>xs:string?</zorba:param>
722- <zorba:param>xs:double</zorba:param>
723- <zorba:param>xs:double</zorba:param>
724+ <zorba:param>xs:integer</zorba:param>
725+ <zorba:param>xs:integer</zorba:param>
726 <zorba:output>xs:string</zorba:output>
727 </zorba:signature>
728 </zorba:function>
729
730=== modified file 'src/runtime/strings/pregenerated/strings.cpp'
731--- src/runtime/strings/pregenerated/strings.cpp 2011-10-19 15:28:51 +0000
732+++ src/runtime/strings/pregenerated/strings.cpp 2011-11-18 17:46:28 +0000
733@@ -232,6 +232,34 @@
734 // </SubstringIterator>
735
736
737+// <SubstringIntOptIterator>
738+const char* SubstringIntOptIterator::class_name_str = "SubstringIntOptIterator";
739+SubstringIntOptIterator::class_factory<SubstringIntOptIterator>
740+SubstringIntOptIterator::g_class_factory;
741+
742+const serialization::ClassVersion
743+SubstringIntOptIterator::class_versions[] ={{ 1, 0x000905, false}};
744+
745+const int SubstringIntOptIterator::class_versions_count =
746+sizeof(SubstringIntOptIterator::class_versions)/sizeof(struct serialization::ClassVersion);
747+
748+void SubstringIntOptIterator::accept(PlanIterVisitor& v) const {
749+ v.beginVisit(*this);
750+
751+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
752+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
753+ for ( ; lIter != lEnd; ++lIter ){
754+ (*lIter)->accept(v);
755+ }
756+
757+ v.endVisit(*this);
758+}
759+
760+SubstringIntOptIterator::~SubstringIntOptIterator() {}
761+
762+// </SubstringIntOptIterator>
763+
764+
765 // <StringLengthIterator>
766 const char* StringLengthIterator::class_name_str = "StringLengthIterator";
767 StringLengthIterator::class_factory<StringLengthIterator>
768
769=== modified file 'src/runtime/strings/pregenerated/strings.h'
770--- src/runtime/strings/pregenerated/strings.h 2011-10-19 15:28:51 +0000
771+++ src/runtime/strings/pregenerated/strings.h 2011-11-18 17:46:28 +0000
772@@ -303,6 +303,42 @@
773
774 /**
775 *
776+ * fn:substring
777+ *
778+ * Author: Zorba Team
779+ */
780+class SubstringIntOptIterator : public NaryBaseIterator<SubstringIntOptIterator, PlanIteratorState>
781+{
782+public:
783+ SERIALIZABLE_CLASS(SubstringIntOptIterator);
784+
785+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(SubstringIntOptIterator,
786+ NaryBaseIterator<SubstringIntOptIterator, PlanIteratorState>);
787+
788+ void serialize( ::zorba::serialization::Archiver& ar)
789+ {
790+ serialize_baseclass(ar,
791+ (NaryBaseIterator<SubstringIntOptIterator, PlanIteratorState>*)this);
792+ }
793+
794+ SubstringIntOptIterator(
795+ static_context* sctx,
796+ const QueryLoc& loc,
797+ std::vector<PlanIter_t>& children)
798+ :
799+ NaryBaseIterator<SubstringIntOptIterator, PlanIteratorState>(sctx, loc, children)
800+ {}
801+
802+ virtual ~SubstringIntOptIterator();
803+
804+ void accept(PlanIterVisitor& v) const;
805+
806+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
807+};
808+
809+
810+/**
811+ *
812 * fn:string-length
813 *
814 * Author: Zorba Team
815
816=== modified file 'src/runtime/strings/strings_impl.cpp'
817--- src/runtime/strings/strings_impl.cpp 2011-08-10 18:58:11 +0000
818+++ src/runtime/strings/strings_impl.cpp 2011-11-18 17:46:28 +0000
819@@ -1,12 +1,12 @@
820 /*
821 * Copyright 2006-2008 The FLWOR Foundation.
822- *
823+ *
824 * Licensed under the Apache License, Version 2.0 (the "License");
825 * you may not use this file except in compliance with the License.
826 * You may obtain a copy of the License at
827- *
828+ *
829 * http://www.apache.org/licenses/LICENSE-2.0
830- *
831+ *
832 * Unless required by applicable law or agreed to in writing, software
833 * distributed under the License is distributed on an "AS IS" BASIS,
834 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
835@@ -60,7 +60,7 @@
836 * fn:codepoints-to-string($arg as xs:integer*) as xs:string
837 *_______________________________________________________________________*/
838 bool
839-CodepointsToStringIterator::nextImpl(store::Item_t& result, PlanState& planState) const
840+CodepointsToStringIterator::nextImpl(store::Item_t& result, PlanState& planState) const
841 {
842 store::Item_t item;
843 zstring resStr;
844@@ -108,7 +108,7 @@
845 */
846 bool StringToCodepointsIterator::nextImpl(
847 store::Item_t& result,
848- PlanState& planState) const
849+ PlanState& planState) const
850 {
851 // TODO Optimization for large strings: large strings mean that a large
852 // integer vector should be stored in the state that is not good.
853@@ -118,19 +118,19 @@
854 StringToCodepointsIteratorState* state;
855 DEFAULT_STACK_INIT(StringToCodepointsIteratorState, state, planState);
856
857- if (consumeNext(item, theChildren [0].getp(), planState ))
858+ if (consumeNext(item, theChildren [0].getp(), planState ))
859 {
860 item->getStringValue2(inputStr);
861
862 if (!inputStr.empty())
863 {
864 utf8::to_codepoints(inputStr, &state->theResult);
865-
866+
867 while (state->theIterator < state->theResult.size())
868 {
869- GENV_ITEMFACTORY->createInteger(
870+ GENV_ITEMFACTORY->createInteger(
871 result,
872- Integer(state->theResult[state->theIterator])
873+ Integer(state->theResult[state->theIterator])
874 );
875
876 STACK_PUSH(true, state );
877@@ -171,7 +171,7 @@
878 *_______________________________________________________________________*/
879 bool CompareStrIterator::nextImpl(
880 store::Item_t& result,
881- PlanState& planState) const
882+ PlanState& planState) const
883 {
884 store::Item_t n0;
885 store::Item_t n1;
886@@ -181,7 +181,7 @@
887 PlanIteratorState* state;
888 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
889
890- if (consumeNext(n0, theChildren[0].getp(), planState ))
891+ if (consumeNext(n0, theChildren[0].getp(), planState ))
892 {
893 if (consumeNext(n1, theChildren[1].getp(), planState ))
894 {
895@@ -199,7 +199,7 @@
896 }
897
898 res = utf8::compare(n0->getStringValue(), n1->getStringValue(), coll);
899-
900+
901 res = (res < 0 ? -1 : (res > 0 ? 1 : 0));
902
903 GENV_ITEMFACTORY->createInteger(result, Integer(res));
904@@ -222,7 +222,7 @@
905 *_______________________________________________________________________*/
906 bool CodepointEqualIterator::nextImpl(
907 store::Item_t& result,
908- PlanState& planState) const
909+ PlanState& planState) const
910 {
911 store::Item_t item0;
912 store::Item_t item1;
913@@ -230,9 +230,9 @@
914 PlanIteratorState* state;
915 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
916
917- if (consumeNext(item0, theChildren [0].getp(), planState ))
918+ if (consumeNext(item0, theChildren [0].getp(), planState ))
919 {
920- if (consumeNext(item1, theChildren [1].getp(), planState ))
921+ if (consumeNext(item1, theChildren [1].getp(), planState ))
922 {
923 GENV_ITEMFACTORY->createBoolean(result,
924 item0->getStringValue() == item1->getStringValue());
925@@ -254,7 +254,7 @@
926 *_______________________________________________________________________*/
927 bool ConcatStrIterator::nextImpl(
928 store::Item_t& result,
929- PlanState& planState) const
930+ PlanState& planState) const
931 {
932 store::Item_t lItem;
933 std::stringstream lResStream;
934@@ -417,7 +417,12 @@
935 }
936 catch ( std::range_error const& )
937 {
938- istart = (xs_int)utf8_string<zstring>(strval).length();
939+ throw XQUERY_EXCEPTION(
940+ zerr::ZXQD0004_INVALID_PARAMETER,
941+ ERROR_PARAMS(ZED(ZXQD0004_NOT_WITHIN_RANGE),
942+ start),
943+ ERROR_LOC( loc )
944+ );
945 }
946 }
947 else
948@@ -456,7 +461,7 @@
949 bool lenItemExists = consumeNext(lenItem, theChildren[2], planState);
950
951 ZORBA_ASSERT(lenItemExists);
952-
953+
954 len = lenItem->getDoubleValue();
955
956 if (!len.isNaN())
957@@ -469,14 +474,19 @@
958 }
959 catch ( std::range_error const& )
960 {
961- ilen = (xs_int)(utf8_string<zstring>(strval).length() - istart + 1);
962+ throw XQUERY_EXCEPTION(
963+ zerr::ZXQD0004_INVALID_PARAMETER,
964+ ERROR_PARAMS(ZED(ZXQD0004_NOT_WITHIN_RANGE),
965+ len),
966+ ERROR_LOC( loc )
967+ );
968 }
969 }
970 else
971 {
972 ilen = (xs_int)(utf8_string<zstring>(strval).length() - istart + 1);
973 }
974-
975+
976 if( !(start + len).isNaN())
977 {
978 if (ilen >= 0)
979@@ -522,6 +532,142 @@
980 /**
981 *______________________________________________________________________
982 *
983+ * 7.4.3.1 fn:substring optimized for int arguments
984+ *
985+ *fn:substring($sourceString as xs:string?,
986+ * $startingLoc as xs:integer) as xs:string
987+ *fn:substring($sourceString as xs:string?,
988+ * $startingLoc as xs:integer,
989+ * $length as xs:integer) as xs:string
990+ *_______________________________________________________________________*/
991+bool SubstringIntOptIterator::nextImpl(
992+ store::Item_t& result,
993+ PlanState& planState) const
994+{
995+ store::Item_t stringItem;
996+ store::Item_t startItem;
997+ store::Item_t lenItem;
998+ zstring strval;
999+ zstring resStr;
1000+ xs_int start;
1001+ xs_int len;
1002+
1003+ PlanIteratorState* state;
1004+ DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
1005+
1006+ if (consumeNext(stringItem, theChildren[0].getp(), planState ))
1007+ {
1008+ stringItem->getStringValue2(strval);
1009+
1010+ if (!strval.empty())
1011+ {
1012+ bool startExists = consumeNext(startItem, theChildren[1], planState);
1013+
1014+ ZORBA_ASSERT(startExists);
1015+
1016+ // note: The first character of a string is located at position 1,
1017+ // not position 0.
1018+
1019+ try
1020+ {
1021+ start = to_xs_int(startItem->getIntegerValue());
1022+ }
1023+ catch ( std::range_error const& )
1024+ {
1025+ throw XQUERY_EXCEPTION(
1026+ zerr::ZXQD0004_INVALID_PARAMETER,
1027+ ERROR_PARAMS(ZED(ZXQD0004_NOT_WITHIN_RANGE),
1028+ lenItem->getIntegerValue()),
1029+ ERROR_LOC( loc )
1030+ );
1031+ }
1032+
1033+ if( theChildren.size() == 2)
1034+ {
1035+ if (start <= 0)
1036+ {
1037+ resStr = strval;
1038+ }
1039+ else
1040+ {
1041+ try
1042+ {
1043+ resStr = utf8_string<zstring>(strval).substr(start-1);
1044+ }
1045+ catch (...)
1046+ {
1047+ zstring::size_type numChars = utf8_string<zstring>(strval).length();
1048+ if (static_cast<zstring::size_type>(start) > numChars)
1049+ {
1050+ // result is the empty string
1051+ }
1052+ else
1053+ {
1054+ throw;
1055+ }
1056+ }
1057+ }
1058+ }
1059+ else
1060+ {
1061+ bool lenItemExists = consumeNext(lenItem, theChildren[2], planState);
1062+
1063+ ZORBA_ASSERT(lenItemExists);
1064+
1065+ try
1066+ {
1067+ len = to_xs_int(lenItem->getIntegerValue());
1068+ }
1069+ catch ( std::range_error const& )
1070+ {
1071+ throw XQUERY_EXCEPTION(
1072+ zerr::ZXQD0004_INVALID_PARAMETER,
1073+ ERROR_PARAMS(ZED(ZXQD0004_NOT_WITHIN_RANGE),
1074+ lenItem->getIntegerValue()),
1075+ ERROR_LOC( loc )
1076+ );
1077+ }
1078+
1079+ if (len >= 0)
1080+ {
1081+ if (start <= 0)
1082+ {
1083+ if ((len + start - 1) >= 0)
1084+ resStr = utf8_string<zstring>(strval).substr(0, start - 1 + len);
1085+ }
1086+ else
1087+ {
1088+ try
1089+ {
1090+ resStr = utf8_string<zstring>(strval).substr(start-1, len);
1091+ }
1092+ catch (...)
1093+ {
1094+ zstring::size_type numChars = utf8_string<zstring>(strval).length();
1095+ if (static_cast<zstring::size_type>(start) > numChars)
1096+ {
1097+ // result is the empty string
1098+ }
1099+ else
1100+ {
1101+ throw;
1102+ }
1103+ }
1104+ }
1105+ }
1106+ }
1107+ } // non empty string arg
1108+ } // non NULL string arg
1109+
1110+STACK_PUSH(GENV_ITEMFACTORY->createString(result, resStr), state);
1111+
1112+STACK_END (state);
1113+}
1114+
1115+
1116+/**
1117+ *______________________________________________________________________
1118+ *
1119 * 7.4.4 fn:string-length
1120 *
1121 *fn:string-length() as xs:integer
1122@@ -541,12 +687,8 @@
1123 {
1124 item->getStringValue2(strval);
1125
1126- STACK_PUSH(
1127- GENV_ITEMFACTORY->createInteger(
1128- result, Integer( utf8::length( strval ) )
1129- ),
1130- state
1131- );
1132+ STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, Integer(utf8::length(strval))),
1133+ state);
1134 }
1135 else
1136 {
1137@@ -566,7 +708,7 @@
1138 *fn:normalize-space($arg as xs:string?) as xs:string
1139 *_______________________________________________________________________*/
1140 bool NormalizeSpaceIterator::nextImpl(
1141- store::Item_t& result,
1142+ store::Item_t& result,
1143 PlanState& planState) const
1144 {
1145 store::Item_t item;
1146@@ -668,7 +810,7 @@
1147 // must push empty string due to return type of function
1148 STACK_PUSH(GENV_ITEMFACTORY->createString(result, resStr), state);
1149 }
1150-
1151+
1152 STACK_END (state);
1153 }
1154
1155@@ -716,7 +858,7 @@
1156 *_______________________________________________________________________*/
1157 bool LowerCaseIterator::nextImpl(
1158 store::Item_t& result,
1159- PlanState& planState) const
1160+ PlanState& planState) const
1161 {
1162 store::Item_t item;
1163 zstring resStr;
1164@@ -751,7 +893,7 @@
1165 * $transString as xs:string) as xs:string
1166 *_______________________________________________________________________*/
1167 bool TranslateIterator::nextImpl(
1168- store::Item_t& result,
1169+ store::Item_t& result,
1170 PlanState& planState) const
1171 {
1172 store::Item_t arg_item, map_item, trans_item;
1173@@ -812,7 +954,7 @@
1174
1175 res = GENV_ITEMFACTORY->createString(result, result_string);
1176 }
1177-
1178+
1179 if (!res)
1180 {
1181 res = GENV_ITEMFACTORY->createString(result, result_string);
1182@@ -832,7 +974,7 @@
1183 *_______________________________________________________________________*/
1184 bool EncodeForUriIterator::nextImpl(
1185 store::Item_t& result,
1186- PlanState& planState) const
1187+ PlanState& planState) const
1188 {
1189 store::Item_t item;
1190 zstring resStr;
1191@@ -841,7 +983,7 @@
1192 PlanIteratorState* state;
1193 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
1194
1195- if (consumeNext(item, theChildren [0].getp(), planState))
1196+ if (consumeNext(item, theChildren [0].getp(), planState))
1197 {
1198 item->getStringValue2(strval);
1199 uri::encode(strval, &resStr, true);
1200@@ -860,8 +1002,8 @@
1201 *fn:iri-to-uri($iri as xs:string?) as xs:string
1202 *_______________________________________________________________________*/
1203 bool IriToUriIterator::nextImpl(
1204- store::Item_t& result,
1205- PlanState& planState) const
1206+ store::Item_t& result,
1207+ PlanState& planState) const
1208 {
1209 store::Item_t item;
1210 zstring lStrIri;
1211@@ -894,8 +1036,8 @@
1212 *fn:escape-html-uri($uri as xs:string?) as xs:string
1213 *_______________________________________________________________________*/
1214 bool EscapeHtmlUriIterator::nextImpl(
1215- store::Item_t& result,
1216- PlanState& planState) const
1217+ store::Item_t& result,
1218+ PlanState& planState) const
1219 {
1220 store::Item_t item;
1221 zstring lStrUri;
1222@@ -932,8 +1074,8 @@
1223 * $collation as xs:string) as xs:boolean
1224 *_______________________________________________________________________*/
1225 bool ContainsIterator::nextImpl(
1226- store::Item_t& result,
1227- PlanState& planState) const
1228+ store::Item_t& result,
1229+ PlanState& planState) const
1230 {
1231 store::Item_t item0;
1232 store::Item_t item1;
1233@@ -954,7 +1096,7 @@
1234 {
1235 item1->getStringValue2(arg2);
1236 }
1237-
1238+
1239 if (arg2.empty())
1240 {
1241 STACK_PUSH( GENV_ITEMFACTORY->createBoolean(result, true), state );
1242@@ -979,7 +1121,7 @@
1243 }
1244 STACK_PUSH( GENV_ITEMFACTORY->createBoolean(result, resBool), state );
1245 }
1246-
1247+
1248 STACK_END (state);
1249 }
1250 /*end class ContainsIterator*/
1251@@ -997,7 +1139,7 @@
1252 *_______________________________________________________________________*/
1253 bool StartsWithIterator::nextImpl(
1254 store::Item_t& result,
1255- PlanState& planState) const
1256+ PlanState& planState) const
1257 {
1258 store::Item_t item0;
1259 store::Item_t item1;
1260@@ -1062,8 +1204,8 @@
1261 * $collation as xs:string) as xs:boolean
1262 *_______________________________________________________________________*/
1263 bool EndsWithIterator::nextImpl(
1264- store::Item_t& result,
1265- PlanState& planState) const
1266+ store::Item_t& result,
1267+ PlanState& planState) const
1268 {
1269 store::Item_t item0;
1270 store::Item_t item1;
1271@@ -1079,7 +1221,7 @@
1272 {
1273 item0->getStringValue2(arg1);
1274 }
1275-
1276+
1277 if (consumeNext(item1, theChildren[1].getp(), planState ))
1278 {
1279 item1->getStringValue2(arg2);
1280@@ -1110,7 +1252,7 @@
1281 }
1282 STACK_PUSH( GENV_ITEMFACTORY->createBoolean(result, resBool), state );
1283 }
1284-
1285+
1286 STACK_END (state);
1287 }
1288
1289@@ -1127,8 +1269,8 @@
1290 * $collation as xs:string) as xs:string
1291 *_______________________________________________________________________*/
1292 bool SubstringBeforeIterator::nextImpl(
1293- store::Item_t& result,
1294- PlanState& planState) const
1295+ store::Item_t& result,
1296+ PlanState& planState) const
1297 {
1298 store::Item_t item0;
1299 store::Item_t item1;
1300@@ -1195,8 +1337,8 @@
1301 * $collation as xs:string) as xs:string
1302 *_______________________________________________________________________*/
1303 bool SubstringAfterIterator::nextImpl(
1304- store::Item_t& result,
1305- PlanState& planState) const
1306+ store::Item_t& result,
1307+ PlanState& planState) const
1308 {
1309 store::Item_t item0;
1310 store::Item_t item1;
1311@@ -1270,7 +1412,7 @@
1312 * $flags as xs:string) as xs:boolean
1313 *_______________________________________________________________________*/
1314 bool FnMatchesIterator::nextImpl(
1315- store::Item_t& result,
1316+ store::Item_t& result,
1317 PlanState& planState) const
1318 {
1319 zstring input;
1320@@ -1278,7 +1420,7 @@
1321 zstring flags;
1322 store::Item_t item;
1323 bool res = false;
1324-
1325+
1326 PlanIteratorState* state;
1327 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
1328
1329@@ -1290,7 +1432,7 @@
1330
1331 item->getStringValue2(xquery_pattern);
1332
1333- if(theChildren.size() == 3)
1334+ if(theChildren.size() == 3)
1335 {
1336 if (!consumeNext(item, theChildren[2].getp(), planState))
1337 ZORBA_ASSERT (false);
1338@@ -1298,20 +1440,20 @@
1339 item->getStringValue2(flags);
1340 }
1341
1342- try
1343+ try
1344 {
1345 zstring lib_pattern;
1346 convert_xquery_re( xquery_pattern, &lib_pattern, flags.c_str() );
1347 res = utf8::match_part(input, lib_pattern, flags.c_str());
1348 }
1349- catch(XQueryException& ex)
1350+ catch(XQueryException& ex)
1351 {
1352 set_source( ex, loc );
1353 throw;
1354 }
1355
1356- STACK_PUSH(GENV_ITEMFACTORY->createBoolean(result, res), state);
1357-
1358+ STACK_PUSH(GENV_ITEMFACTORY->createBoolean(result, res), state);
1359+
1360 STACK_END(state);
1361 }
1362
1363@@ -1340,7 +1482,7 @@
1364 zstring resStr;
1365 store::Item_t item;
1366 bool tmp;
1367-
1368+
1369 PlanIteratorState* state;
1370 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
1371
1372@@ -1357,7 +1499,7 @@
1373
1374 item->getStringValue2(replacement);
1375
1376- if(theChildren.size() == 4)
1377+ if(theChildren.size() == 4)
1378 {
1379 if (!consumeNext(item, theChildren[3].getp(), planState))
1380 ZORBA_ASSERT (false);
1381@@ -1365,16 +1507,16 @@
1382 item->getStringValue2(flags);
1383 }
1384
1385- try
1386+ try
1387 {
1388 tmp = utf8::match_part(zstring(), pattern, flags.c_str());
1389 }
1390- catch(XQueryException& ex)
1391+ catch(XQueryException& ex)
1392 {
1393 set_source( ex, loc );
1394 throw;
1395 }
1396-
1397+
1398 if (tmp)
1399 throw XQUERY_EXCEPTION(
1400 err::FORX0003, ERROR_PARAMS( pattern ), ERROR_LOC( loc )
1401@@ -1448,20 +1590,20 @@
1402 );
1403 } // local scope
1404
1405- try
1406+ try
1407 {
1408 zstring lib_pattern;
1409 convert_xquery_re( pattern, &lib_pattern, flags.c_str() );
1410 utf8::replace_all(input, lib_pattern, flags.c_str(), replacement2, &resStr);
1411 }
1412- catch(XQueryException& ex)
1413+ catch(XQueryException& ex)
1414 {
1415 set_source( ex, loc );
1416 throw;
1417 }
1418-
1419+
1420 STACK_PUSH(GENV_ITEMFACTORY->createString(result, resStr), state);
1421-
1422+
1423 STACK_END (state);
1424 }
1425
1426@@ -1514,7 +1656,7 @@
1427 item->getStringValue2(strval);
1428 state->thePattern = strval.str();
1429
1430- if(theChildren.size() == 3)
1431+ if(theChildren.size() == 3)
1432 {
1433 if (!consumeNext(item, theChildren[2].getp(), planState))
1434 ZORBA_ASSERT (false);
1435@@ -1543,7 +1685,7 @@
1436
1437 while ((xs_unsignedInt)state->start_pos < state->theString.length ())
1438 {
1439- try
1440+ try
1441 {
1442 unicode::regex re;
1443 //
1444@@ -1558,7 +1700,7 @@
1445 if ( !got_next )
1446 break;
1447 }
1448- catch(XQueryException& ex)
1449+ catch(XQueryException& ex)
1450 {
1451 set_source( ex, loc );
1452 throw;
1453@@ -1588,7 +1730,7 @@
1454 * $flags as xs:string) as element(fn:analyze-string-result)
1455 *_______________________________________________________________________*/
1456
1457-static void copyUtf8Chars(const char *&sin,
1458+static void copyUtf8Chars(const char *&sin,
1459 int &utf8start,
1460 unsigned int &bytestart,
1461 int utf8end,
1462@@ -1605,10 +1747,10 @@
1463 }
1464 }
1465
1466-static void addNonMatchElement(store::Item_t &parent,
1467- int &match_end1,
1468+static void addNonMatchElement(store::Item_t &parent,
1469+ int &match_end1,
1470 unsigned int &match_end1_bytes,
1471- int match_start2,
1472+ int match_start2,
1473 const char *&strin)
1474 {
1475 store::Item_t non_match_elem;
1476@@ -1635,12 +1777,12 @@
1477 GENV_ITEMFACTORY->createTextNode(non_match_text_item, non_match_elem, non_match_str);
1478 }
1479
1480-static void addGroupElement(store::Item_t &parent,
1481+static void addGroupElement(store::Item_t &parent,
1482 store::Item_t &untyped_type_name,
1483 store::NsBindings &ns_binding,
1484 zstring &baseURI,
1485- int match_start2,
1486- int match_end2,
1487+ int match_start2,
1488+ int match_end2,
1489 unsigned int &match_end1_bytes,
1490 const char *&sin,
1491 unicode::regex &rx,
1492@@ -1695,9 +1837,9 @@
1493 {
1494 if(group_parent[i+1] > gparent)
1495 {
1496- addGroupElement(group_elem, untyped_type_name, ns_binding, baseURI,
1497- match_startg, match_endg, match_end1_bytes,
1498- sin, rx,
1499+ addGroupElement(group_elem, untyped_type_name, ns_binding, baseURI,
1500+ match_startg, match_endg, match_end1_bytes,
1501+ sin, rx,
1502 i, group_parent, nr_pattern_groups, i);
1503 continue;
1504 }
1505@@ -1719,8 +1861,8 @@
1506 }
1507 }
1508
1509-static void addMatchElement(store::Item_t &parent,
1510- int match_start2,
1511+static void addMatchElement(store::Item_t &parent,
1512+ int match_start2,
1513 unsigned int &match_end1_bytes,
1514 int match_end2,
1515 //utf8_string<zstring_p>::const_iterator& utf8_it,
1516@@ -1776,7 +1918,7 @@
1517 }
1518
1519 bool FnAnalyzeStringIterator::nextImpl(
1520- store::Item_t& result,
1521+ store::Item_t& result,
1522 PlanState& planState) const
1523 {
1524 bool is_input_stream = false;
1525@@ -1797,7 +1939,7 @@
1526 zstring xquery_pattern;
1527 zstring flags;
1528 store::Item_t item;
1529-
1530+
1531 PlanIteratorState* state;
1532 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
1533
1534@@ -1819,7 +1961,7 @@
1535
1536 item->getStringValue2(xquery_pattern);
1537
1538- if(theChildren.size() == 3)
1539+ if(theChildren.size() == 3)
1540 {
1541 if (!consumeNext(item, theChildren[2].getp(), planState))
1542 ZORBA_ASSERT (false);
1543@@ -1827,7 +1969,7 @@
1544 item->getStringValue2(flags);
1545 }
1546
1547- try
1548+ try
1549 {
1550 zstring lib_pattern;
1551 convert_xquery_re( xquery_pattern, &lib_pattern, flags.c_str() );
1552@@ -2017,14 +2159,14 @@
1553
1554 }while(is_input_stream && !reachedEnd);
1555 }
1556- catch(XQueryException& ex)
1557+ catch(XQueryException& ex)
1558 {
1559 set_source( ex, loc );
1560 throw;
1561 }
1562
1563- STACK_PUSH(true, state);
1564-
1565+ STACK_PUSH(true, state);
1566+
1567 STACK_END(state);
1568 }
1569
1570
1571=== modified file 'src/runtime/visitors/planiter_visitor_impl_code.h'
1572--- src/runtime/visitors/planiter_visitor_impl_code.h 2011-10-11 01:05:23 +0000
1573+++ src/runtime/visitors/planiter_visitor_impl_code.h 2011-11-18 17:46:28 +0000
1574@@ -357,4 +357,5 @@
1575 PLAN_ITER_VISITOR(FlowCtlIterator);
1576
1577 PLAN_ITER_VISITOR(CountCollectionIterator);
1578+
1579 /* vim:set et sw=2 ts=2: */
1580
1581=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
1582--- src/runtime/visitors/pregenerated/planiter_visitor.h 2011-11-15 08:23:20 +0000
1583+++ src/runtime/visitors/pregenerated/planiter_visitor.h 2011-11-18 17:46:28 +0000
1584@@ -540,6 +540,8 @@
1585
1586 class SubstringIterator;
1587
1588+ class SubstringIntOptIterator;
1589+
1590 class StringLengthIterator;
1591
1592 class NormalizeSpaceIterator;
1593@@ -1358,6 +1360,9 @@
1594 virtual void beginVisit ( const SubstringIterator& ) = 0;
1595 virtual void endVisit ( const SubstringIterator& ) = 0;
1596
1597+ virtual void beginVisit ( const SubstringIntOptIterator& ) = 0;
1598+ virtual void endVisit ( const SubstringIntOptIterator& ) = 0;
1599+
1600 virtual void beginVisit ( const StringLengthIterator& ) = 0;
1601 virtual void endVisit ( const StringLengthIterator& ) = 0;
1602
1603
1604=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
1605--- src/runtime/visitors/pregenerated/printer_visitor.cpp 2011-11-15 08:23:20 +0000
1606+++ src/runtime/visitors/pregenerated/printer_visitor.cpp 2011-11-18 17:46:28 +0000
1607@@ -3667,6 +3667,20 @@
1608 // </SubstringIterator>
1609
1610
1611+// <SubstringIntOptIterator>
1612+void PrinterVisitor::beginVisit ( const SubstringIntOptIterator& a) {
1613+ thePrinter.startBeginVisit("SubstringIntOptIterator", ++theId);
1614+ printCommons( &a, theId );
1615+ thePrinter.endBeginVisit( theId );
1616+}
1617+
1618+void PrinterVisitor::endVisit ( const SubstringIntOptIterator& ) {
1619+ thePrinter.startEndVisit();
1620+ thePrinter.endEndVisit();
1621+}
1622+// </SubstringIntOptIterator>
1623+
1624+
1625 // <StringLengthIterator>
1626 void PrinterVisitor::beginVisit ( const StringLengthIterator& a) {
1627 thePrinter.startBeginVisit("StringLengthIterator", ++theId);
1628
1629=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
1630--- src/runtime/visitors/pregenerated/printer_visitor.h 2011-11-15 08:23:20 +0000
1631+++ src/runtime/visitors/pregenerated/printer_visitor.h 2011-11-18 17:46:28 +0000
1632@@ -813,6 +813,9 @@
1633 void beginVisit( const SubstringIterator& );
1634 void endVisit ( const SubstringIterator& );
1635
1636+ void beginVisit( const SubstringIntOptIterator& );
1637+ void endVisit ( const SubstringIntOptIterator& );
1638+
1639 void beginVisit( const StringLengthIterator& );
1640 void endVisit ( const StringLengthIterator& );
1641
1642
1643=== modified file 'src/runtime/visitors/printer_visitor_impl.h'
1644--- src/runtime/visitors/printer_visitor_impl.h 2011-10-11 01:05:23 +0000
1645+++ src/runtime/visitors/printer_visitor_impl.h 2011-11-18 17:46:28 +0000
1646@@ -309,4 +309,5 @@
1647 DECLARE_VISITOR(FlowCtlIterator);
1648
1649 DECLARE_VISITOR(CountCollectionIterator);
1650+
1651 /* vim:set et sw=2 ts=2: */
1652
1653=== added directory 'test/rbkt/ExpCompilerResults/IterPlan/zorba/string'
1654=== added directory 'test/rbkt/ExpCompilerResults/IterPlan/zorba/string/SubstringFunc'
1655=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/string/SubstringFunc/SubstringFunc2.iter'
1656--- test/rbkt/ExpCompilerResults/IterPlan/zorba/string/SubstringFunc/SubstringFunc2.iter 1970-01-01 00:00:00 +0000
1657+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/string/SubstringFunc/SubstringFunc2.iter 2011-11-18 17:46:28 +0000
1658@@ -0,0 +1,10 @@
1659+Iterator tree for const-folded expr:
1660+<SubstringIntOptIterator>
1661+ <SingletonIterator value="xs:string(metadata)"/>
1662+ <SingletonIterator value="xs:integer(4)"/>
1663+ <SingletonIterator value="xs:integer(3)"/>
1664+</SubstringIntOptIterator>
1665+
1666+Iterator tree for main query:
1667+<SingletonIterator value="xs:string(ada)"/>
1668+
1669
1670=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/string/SubstringFunc/SubstringFunc3.iter'
1671--- test/rbkt/ExpCompilerResults/IterPlan/zorba/string/SubstringFunc/SubstringFunc3.iter 1970-01-01 00:00:00 +0000
1672+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/string/SubstringFunc/SubstringFunc3.iter 2011-11-18 17:46:28 +0000
1673@@ -0,0 +1,14 @@
1674+Iterator tree for const-folded expr:
1675+<SubstringIterator>
1676+ <SingletonIterator value="xs:string(12345)"/>
1677+ <PromoteIterator type="xs:double">
1678+ <SingletonIterator value="xs:decimal(1.5)"/>
1679+ </PromoteIterator>
1680+ <PromoteIterator type="xs:double">
1681+ <SingletonIterator value="xs:decimal(2.6)"/>
1682+ </PromoteIterator>
1683+</SubstringIterator>
1684+
1685+Iterator tree for main query:
1686+<SingletonIterator value="xs:string(234)"/>
1687+

Subscribers

People subscribed via source and target branches