Merge lp:~zorba-coders/zorba/markos-scratch into lp:zorba

Proposed by Markos Zaharioudakis
Status: Merged
Merged at revision: 11594
Proposed branch: lp:~zorba-coders/zorba/markos-scratch
Merge into: lp:zorba
Diff against target: 872 lines (+318/-193)
13 files modified
modules/org/jsoniq/www/functions.xq (+0/-24)
src/compiler/rewriter/rules/flwor_rules.cpp (+17/-2)
src/compiler/translator/translator.cpp (+119/-63)
src/functions/func_jsoniq_functions_impl.cpp (+35/-0)
src/functions/pregenerated/func_jsoniq_functions.cpp (+12/-12)
src/functions/pregenerated/func_jsoniq_functions.h (+12/-6)
src/functions/pregenerated/function_enum.h (+2/-2)
src/runtime/json/jsoniq_functions_impl.cpp (+72/-69)
src/runtime/spec/json/jsoniq_functions.xml (+9/-6)
test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter (+31/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/xray/ppm_10.iter (+5/-5)
test/rbkt/Queries/zorba/jsoniq/member_01.xq (+2/-2)
test/rbkt/Queries/zorba/jsoniq/pair_01.xq (+2/-2)
To merge this branch: bzr merge lp:~zorba-coders/zorba/markos-scratch
Reviewer Review Type Date Requested Status
Markos Zaharioudakis Approve
Review via email: mp+179411@code.launchpad.net

Commit message

don't do unnecessary implicit iteration for jsoniq navigation

Description of the change

don't do unnecessary implicit iteration for jsoniq navigation

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

Validation queue starting for the following merge proposals:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/179411

Progress dashboard at http://jenkins.lambda.nu/view/ValidationQueue

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

Validation queue result for https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/179411

Stage "TestZorbaUbuntu" failed.
1 tests failed (8403 total tests run).

Check test results at http://jenkins.lambda.nu/job/TestZorbaUbuntu/195/testReport/ to view the results.

11200. By Markos Zaharioudakis

don't do unnecessary implicit iteration for jsoniq navigation

11201. By Markos Zaharioudakis

don't do unnecessary implicit iteration for jsoniq navigation

11202. By Markos Zaharioudakis

merge from trunk

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

Validation queue starting for the following merge proposals:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/179411

Progress dashboard at http://jenkins.lambda.nu/view/ValidationQueue

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

Validation queue result for https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/179411

Stage "TestZorbaUbuntu" failed.
1 tests failed (8402 total tests run).

Check test results at http://jenkins.lambda.nu/job/TestZorbaUbuntu/202/testReport/ to view the results.

11203. By Markos Zaharioudakis

merge from trunk

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

Validation queue starting for the following merge proposals:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/179411

Progress dashboard at http://jenkins.lambda.nu/view/ValidationQueue

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

Validation queue succeeded - proposal merged!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'modules/org/jsoniq/www/functions.xq'
2--- modules/org/jsoniq/www/functions.xq 2013-08-09 08:27:30 +0000
3+++ modules/org/jsoniq/www/functions.xq 2013-08-12 10:27:34 +0000
4@@ -197,18 +197,6 @@
5
6
7 (:~
8- : Returns the value of a JSON Pair with a given name within a given JSON object.
9- : If no such pair exists in the object, returns the empty sequence.
10- :
11- : @param $o A JSON Object.
12- : @param $name The name of the pair whose value is to be retrieved
13- : @return the value of specified pair within the given object, or the empty sequence.
14- :)
15-(: obsolete - use $o($name) instead :)
16-declare function jn:value($o as item(), $name as item()?) as item()? external;
17-
18-
19-(:~
20 : Creates an object from the specified pairs of another given object.
21 : Specifically, for each name in $names, if the object $o has a pair with
22 : that name, then a copy of that pair is included in the new object.
23@@ -231,18 +219,6 @@
24
25
26 (:~
27- : Returns the member of an Array at the specified position (starting from 1).
28- : If the position is out of bounds of the array, returns the empty sequence.
29- :
30- : @param $a A JSON Array.
31- : @param $p The position in the array.
32- : @return The member at the specified position, or empty sequence.
33- :)
34-(: obsolete - use $a($p) or $a[[$p]] instead :)
35-declare function jn:member($a as item(), $p as item()?) as item()? external;
36-
37-
38-(:~
39 : Returns the items belonging to the arrays found inside a given sequence
40 : of items. The items are returned in an implementation-defined order.
41 :
42
43=== modified file 'src/compiler/rewriter/rules/flwor_rules.cpp'
44--- src/compiler/rewriter/rules/flwor_rules.cpp 2013-06-14 04:50:39 +0000
45+++ src/compiler/rewriter/rules/flwor_rules.cpp 2013-08-12 10:27:34 +0000
46@@ -462,7 +462,8 @@
47 // since one value is still returned, count variables are changed to 1
48 subst_vars(rCtx,
49 static_cast<count_clause*>(clause)->get_var(),
50- rCtx.theEM->create_const_expr(sctx, udf, loc, numeric_consts<xs_integer>::one()),
51+ rCtx.theEM->create_const_expr(sctx, udf, loc,
52+ numeric_consts<xs_integer>::one()),
53 2);
54
55 theFlwor->remove_clause(0);
56@@ -537,7 +538,21 @@
57 if (is_trivial_expr(varDomExpr))
58 {
59 numRefs = 2;
60- return isSafeVar;
61+
62+ if (isSafeVar)
63+ {
64+ return true;
65+ }
66+ else
67+ {
68+ expr* retExpr = theFlwor->get_return_expr();
69+ xqtref_t type = retExpr->get_return_type_with_empty_input(var);
70+
71+ return TypeOps::is_equal(theFlwor->get_type_manager(),
72+ *type,
73+ *GENV_TYPESYSTEM.EMPTY_TYPE,
74+ retExpr->get_loc());
75+ }
76 }
77
78 // If set to true, then it is unsafe to fold, but we may still be able to
79
80=== modified file 'src/compiler/translator/translator.cpp'
81--- src/compiler/translator/translator.cpp 2013-08-02 18:29:44 +0000
82+++ src/compiler/translator/translator.cpp 2013-08-12 10:27:34 +0000
83@@ -10833,24 +10833,39 @@
84
85 for_clause* sourceClause = static_cast<for_clause*>(flworExpr->get_clause(0));
86
87- expr* flworVarExpr =
88- CREATE(wrapper)(theRootSctx, theUDF, loc, sourceClause->get_var());
89-
90+ expr* arrayExpr = sourceClause->get_expr();
91 expr* selectorExpr = static_cast<json_array_expr*>(predExpr)->get_expr();
92
93- std::vector<expr*> args(2);
94- args[0] = flworVarExpr;
95- args[1] = selectorExpr;
96-
97- expr* accessorExpr =
98- generate_fn_body(BUILTIN_FUNC(FN_JSONIQ_MEMBER_2), args, loc);
99-
100- assert(accessorExpr->get_expr_kind() == fo_expr_kind);
101-
102- flworExpr->set_return_expr(accessorExpr);
103-
104- push_nodestack(flworExpr);
105- pop_scope();
106+ xqtref_t domainType = arrayExpr->get_return_type();
107+
108+ if (domainType->max_card() > 1)
109+ {
110+ expr* flworVarExpr =
111+ CREATE(wrapper)(theRootSctx, theUDF, loc, sourceClause->get_var());
112+
113+ std::vector<expr*> args(2);
114+ args[0] = flworVarExpr;
115+ args[1] = selectorExpr;
116+
117+ expr* accessorExpr =
118+ generate_fn_body(BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2), args, loc);
119+
120+ flworExpr->set_return_expr(accessorExpr);
121+
122+ push_nodestack(flworExpr);
123+ pop_scope();
124+ }
125+ else
126+ {
127+ std::vector<expr*> args(2);
128+ args[0] = arrayExpr;
129+ args[1] = selectorExpr;
130+
131+ expr* accessorExpr =
132+ generate_fn_body(BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2), args, loc);
133+
134+ push_nodestack(accessorExpr);
135+ }
136
137 return;
138 }
139@@ -10889,7 +10904,7 @@
140 {
141 fo_expr* pointExpr =
142 CREATE(fo)(sourceExpr->get_sctx(), theUDF, sourceExpr->get_loc(),
143- BUILTIN_FUNC(FN_JSONIQ_MEMBER_2),
144+ BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2),
145 arrayExpr,
146 predExpr);
147
148@@ -11072,27 +11087,42 @@
149
150 assert(selectExpr && objectExpr);
151
152- flwor_expr* flworExpr = wrap_expr_in_flwor(objectExpr, false);
153-
154- for_clause* fc = static_cast<for_clause*>(flworExpr->get_clause(0));
155-
156- expr* flworVarExpr = CREATE(wrapper)(theRootSctx, theUDF, loc, fc->get_var());
157-
158- expr* accessorExpr;
159-
160- std::vector<expr*> args(2);
161- args[0] = flworVarExpr;
162- args[1] = selectExpr;
163-
164- accessorExpr = generate_fn_body(BUILTIN_FUNC(FN_JSONIQ_VALUE_2), args, loc);
165-
166- assert(accessorExpr->get_expr_kind() == fo_expr_kind);
167-
168- flworExpr->set_return_expr(accessorExpr);
169-
170- pop_scope();
171-
172- push_nodestack(flworExpr);
173+ xqtref_t domainType = objectExpr->get_return_type();
174+
175+ if (domainType->max_card() > 1)
176+ {
177+ flwor_expr* flworExpr = wrap_expr_in_flwor(objectExpr, false);
178+
179+ for_clause* fc = static_cast<for_clause*>(flworExpr->get_clause(0));
180+
181+ expr* flworVarExpr = CREATE(wrapper)(theRootSctx, theUDF, loc, fc->get_var());
182+
183+ std::vector<expr*> args(2);
184+ args[0] = flworVarExpr;
185+ args[1] = selectExpr;
186+
187+ expr* accessorExpr =
188+ generate_fn_body(BUILTIN_FUNC(OP_ZORBA_OBJECT_VALUE_2), args, loc);
189+
190+ assert(accessorExpr->get_expr_kind() == fo_expr_kind);
191+
192+ flworExpr->set_return_expr(accessorExpr);
193+
194+ pop_scope();
195+
196+ push_nodestack(flworExpr);
197+ }
198+ else
199+ {
200+ std::vector<expr*> args(2);
201+ args[0] = objectExpr;
202+ args[1] = selectExpr;
203+
204+ expr* accessorExpr =
205+ generate_fn_body(BUILTIN_FUNC(OP_ZORBA_OBJECT_VALUE_2), args, loc);
206+
207+ push_nodestack(accessorExpr);
208+ }
209 }
210
211
212@@ -12191,14 +12221,14 @@
213
214 break;
215 }
216- case FunctionConsts::FN_JSONIQ_VALUE_2:
217+ case FunctionConsts::OP_ZORBA_OBJECT_VALUE_2:
218 {
219 arguments[1] =
220 create_cast_expr(loc, arguments[1], theRTM.STRING_TYPE_ONE, true, true);
221
222 break;
223 }
224- case FunctionConsts::FN_JSONIQ_MEMBER_2:
225+ case FunctionConsts::OP_ZORBA_ARRAY_MEMBER_2:
226 {
227 arguments[1] =
228 create_cast_expr(loc, arguments[1], theRTM.INTEGER_TYPE_ONE, true, true);
229@@ -12466,6 +12496,8 @@
230 expr* sourceExpr = pop_nodestack();
231 ZORBA_ASSERT(sourceExpr != 0);
232
233+ xqtref_t srcType = sourceExpr->get_return_type();
234+
235 TypeManager* tm = sourceExpr->get_type_manager();
236
237 // special case: partial function invocation
238@@ -12481,18 +12513,28 @@
239 }
240 }
241
242- // Implementing implicit iteration over the sequence returned by the source expr
243- flwor_expr* flworExpr = wrap_expr_in_flwor(sourceExpr, false);
244-
245- for_clause* fc = static_cast<for_clause*>(flworExpr->get_clause(0));
246-
247- expr* flworVarExpr = CREATE(wrapper)(theRootSctx, theUDF, loc, fc->get_var());
248-
249- xqtref_t srcType = sourceExpr->get_return_type();
250+ bool isJSON =
251+ (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ITEM_TYPE_STAR) && numArgs <= 1);
252+
253+ bool implicitIter =
254+ (srcType->get_quantifier() != TypeConstants::QUANT_ONE &&
255+ (srcType->max_card() > 1 || !isJSON));
256+
257+ flwor_expr* flworExpr;
258+
259+ // Implementing implicit iteration over the sequence returned by the source expr
260+ if (implicitIter)
261+ {
262+ flworExpr = wrap_expr_in_flwor(sourceExpr, false);
263+
264+ for_clause* fc = static_cast<for_clause*>(flworExpr->get_clause(0));
265+
266+ sourceExpr = CREATE(wrapper)(theRootSctx, theUDF, loc, fc->get_var());
267+ }
268
269 // Note: if numArgs > 1 and the input contains a json item, DynamicFnCallIterator
270 // will raise an error. However, no error will be raised if the input is empty.
271- if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ITEM_TYPE_STAR) && numArgs <= 1)
272+ if (isJSON)
273 {
274 function* func;
275 expr* accessorExpr;
276@@ -12501,11 +12543,11 @@
277 {
278 if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ARRAY_TYPE_STAR))
279 {
280- func = BUILTIN_FUNC(FN_JSONIQ_MEMBER_2);
281+ func = BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2);
282 }
283 else if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_OBJECT_TYPE_STAR))
284 {
285- func = BUILTIN_FUNC(FN_JSONIQ_VALUE_2);
286+ func = BUILTIN_FUNC(OP_ZORBA_OBJECT_VALUE_2);
287 }
288 else
289 {
290@@ -12524,32 +12566,46 @@
291 }
292 else
293 {
294- func = BUILTIN_FUNC(OP_ZORBA_JSON_ITEM_ACCESSOR_1);
295+ func = BUILTIN_FUNC(OP_ZORBA_JSON_ITEM_ACCESSOR_1);
296 }
297 }
298
299- arguments.insert(arguments.begin(), flworVarExpr);
300-
301+ arguments.insert(arguments.begin(), sourceExpr);
302+
303 accessorExpr = generate_fn_body(func, arguments, loc);
304+
305+ if (implicitIter)
306+ {
307+ flworExpr->set_return_expr(accessorExpr);
308
309- flworExpr->set_return_expr(accessorExpr);
310+ pop_scope();
311+
312+ push_nodestack(flworExpr);
313+ }
314+ else
315+ {
316+ push_nodestack(accessorExpr);
317+ }
318 }
319 else
320 {
321 expr* dynFuncInvocation =
322 CREATE(dynamic_function_invocation)(theRootSctx, theUDF, loc,
323- flworVarExpr,
324+ sourceExpr,
325 arguments);
326-
327- flworExpr->set_return_expr(dynFuncInvocation);
328+ if (implicitIter)
329+ {
330+ flworExpr->set_return_expr(dynFuncInvocation);
331+ pop_scope();
332+ push_nodestack(flworExpr);
333+ }
334+ else
335+ {
336+ push_nodestack(dynFuncInvocation);
337+ }
338 }
339-
340- pop_scope();
341-
342- push_nodestack(flworExpr);
343 }
344
345-
346 /*******************************************************************************
347 LiteralFunctionItem ::= QName "#" IntegerLiteral
348 ********************************************************************************/
349
350=== modified file 'src/functions/func_jsoniq_functions_impl.cpp'
351--- src/functions/func_jsoniq_functions_impl.cpp 2013-06-08 05:33:57 +0000
352+++ src/functions/func_jsoniq_functions_impl.cpp 2013-08-12 10:27:34 +0000
353@@ -31,6 +31,41 @@
354 namespace zorba
355 {
356
357+/*******************************************************************************
358+
359+********************************************************************************/
360+xqtref_t op_zorba_json_item_accessor::getReturnType(const fo_expr* caller) const
361+{
362+ if (caller->get_arg(0)->get_return_type()->max_card() == 0)
363+ return GENV_TYPESYSTEM.EMPTY_TYPE;
364+
365+ return theSignature.returnType();
366+}
367+
368+
369+/*******************************************************************************
370+
371+********************************************************************************/
372+xqtref_t op_zorba_object_value::getReturnType(const fo_expr* caller) const
373+{
374+ if (caller->get_arg(0)->get_return_type()->max_card() == 0)
375+ return GENV_TYPESYSTEM.EMPTY_TYPE;
376+
377+ return theSignature.returnType();
378+}
379+
380+
381+/*******************************************************************************
382+
383+********************************************************************************/
384+xqtref_t op_zorba_array_member::getReturnType(const fo_expr* caller) const
385+{
386+ if (caller->get_arg(0)->get_return_type()->max_card() == 0)
387+ return GENV_TYPESYSTEM.EMPTY_TYPE;
388+
389+ return theSignature.returnType();
390+}
391+
392
393 /*******************************************************************************
394
395
396=== modified file 'src/functions/pregenerated/func_jsoniq_functions.cpp'
397--- src/functions/pregenerated/func_jsoniq_functions.cpp 2013-08-09 09:20:54 +0000
398+++ src/functions/pregenerated/func_jsoniq_functions.cpp 2013-08-12 10:27:34 +0000
399@@ -83,7 +83,7 @@
400 return new SingleObjectNamesIterator(sctx, loc, argv[0]);
401 }
402
403-PlanIter_t fn_jsoniq_value::codegen(
404+PlanIter_t op_zorba_object_value::codegen(
405 CompilerCB*,
406 static_context* sctx,
407 const QueryLoc& loc,
408@@ -103,7 +103,7 @@
409 return new JSONObjectProjectIterator(sctx, loc, argv[0], argv[1]);
410 }
411
412-PlanIter_t fn_jsoniq_member::codegen(
413+PlanIter_t op_zorba_array_member::codegen(
414 CompilerCB*,
415 static_context* sctx,
416 const QueryLoc& loc,
417@@ -319,7 +319,7 @@
418 {
419 DECL_WITH_KIND(sctx, op_zorba_json_item_accessor,
420 (createQName("http://zorba.io/internal/zorba-ops","","json-item-accessor"),
421- GENV_TYPESYSTEM.ITEM_TYPE_ONE,
422+ GENV_TYPESYSTEM.ITEM_TYPE_QUESTION,
423 GENV_TYPESYSTEM.ITEM_TYPE_STAR),
424 FunctionConsts::OP_ZORBA_JSON_ITEM_ACCESSOR_1);
425
426@@ -331,7 +331,7 @@
427 {
428 DECL_WITH_KIND(sctx, op_zorba_json_item_accessor,
429 (createQName("http://zorba.io/internal/zorba-ops","","json-item-accessor"),
430- GENV_TYPESYSTEM.ITEM_TYPE_ONE,
431+ GENV_TYPESYSTEM.ITEM_TYPE_QUESTION,
432 GENV_TYPESYSTEM.ITEM_TYPE_QUESTION,
433 GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
434 FunctionConsts::OP_ZORBA_JSON_ITEM_ACCESSOR_2);
435@@ -366,12 +366,12 @@
436
437
438 {
439- DECL_WITH_KIND(sctx, fn_jsoniq_value,
440- (createQName("http://jsoniq.org/functions","","value"),
441- GENV_TYPESYSTEM.ITEM_TYPE_ONE,
442+ DECL_WITH_KIND(sctx, op_zorba_object_value,
443+ (createQName("http://zorba.io/internal/zorba-ops","","object-value"),
444+ GENV_TYPESYSTEM.ITEM_TYPE_QUESTION,
445 GENV_TYPESYSTEM.ITEM_TYPE_QUESTION,
446 GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
447- FunctionConsts::FN_JSONIQ_VALUE_2);
448+ FunctionConsts::OP_ZORBA_OBJECT_VALUE_2);
449
450 }
451
452@@ -392,12 +392,12 @@
453
454
455 {
456- DECL_WITH_KIND(sctx, fn_jsoniq_member,
457- (createQName("http://jsoniq.org/functions","","member"),
458- GENV_TYPESYSTEM.ITEM_TYPE_ONE,
459+ DECL_WITH_KIND(sctx, op_zorba_array_member,
460+ (createQName("http://zorba.io/internal/zorba-ops","","array-member"),
461+ GENV_TYPESYSTEM.ITEM_TYPE_QUESTION,
462 GENV_TYPESYSTEM.ITEM_TYPE_QUESTION,
463 GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
464- FunctionConsts::FN_JSONIQ_MEMBER_2);
465+ FunctionConsts::OP_ZORBA_ARRAY_MEMBER_2);
466
467 }
468
469
470=== modified file 'src/functions/pregenerated/func_jsoniq_functions.h'
471--- src/functions/pregenerated/func_jsoniq_functions.h 2013-06-08 05:33:57 +0000
472+++ src/functions/pregenerated/func_jsoniq_functions.h 2013-08-12 10:27:34 +0000
473@@ -125,6 +125,8 @@
474
475 }
476
477+ xqtref_t getReturnType(const fo_expr* caller) const;
478+
479 bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
480
481 bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
482@@ -173,17 +175,19 @@
483 };
484
485
486-//fn-jsoniq:value
487-class fn_jsoniq_value : public function
488+//op-zorba:object-value
489+class op_zorba_object_value : public function
490 {
491 public:
492- fn_jsoniq_value(const signature& sig, FunctionConsts::FunctionKind kind)
493+ op_zorba_object_value(const signature& sig, FunctionConsts::FunctionKind kind)
494 :
495 function(sig, kind)
496 {
497
498 }
499
500+ xqtref_t getReturnType(const fo_expr* caller) const;
501+
502 bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
503
504 bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
505@@ -211,17 +215,19 @@
506 };
507
508
509-//fn-jsoniq:member
510-class fn_jsoniq_member : public function
511+//op-zorba:array-member
512+class op_zorba_array_member : public function
513 {
514 public:
515- fn_jsoniq_member(const signature& sig, FunctionConsts::FunctionKind kind)
516+ op_zorba_array_member(const signature& sig, FunctionConsts::FunctionKind kind)
517 :
518 function(sig, kind)
519 {
520
521 }
522
523+ xqtref_t getReturnType(const fo_expr* caller) const;
524+
525 bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
526
527 bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
528
529=== modified file 'src/functions/pregenerated/function_enum.h'
530--- src/functions/pregenerated/function_enum.h 2013-07-26 21:05:40 +0000
531+++ src/functions/pregenerated/function_enum.h 2013-08-12 10:27:34 +0000
532@@ -263,9 +263,9 @@
533 OP_ZORBA_JSON_ITEM_ACCESSOR_2,
534 FN_JSONIQ_KEYS_1,
535 OP_ZORBA_KEYS_1,
536- FN_JSONIQ_VALUE_2,
537+ OP_ZORBA_OBJECT_VALUE_2,
538 FN_JSONIQ_PROJECT_2,
539- FN_JSONIQ_MEMBER_2,
540+ OP_ZORBA_ARRAY_MEMBER_2,
541 FN_JSONIQ_MEMBERS_1,
542 OP_ZORBA_MEMBERS_1,
543 FN_JSONIQ_SIZE_1,
544
545=== modified file 'src/runtime/json/jsoniq_functions_impl.cpp'
546--- src/runtime/json/jsoniq_functions_impl.cpp 2013-06-18 18:55:33 +0000
547+++ src/runtime/json/jsoniq_functions_impl.cpp 2013-08-12 10:27:34 +0000
548@@ -985,9 +985,9 @@
549
550
551 /*******************************************************************************
552- op_zorba:json-item-accessor($i as item(), $sel as item()) as item()?
553+ op_zorba:json-item-accessor($i as item()?, $sel as item()?) as item()?
554
555- op_zorba:json-item-accessor($i as item()) as item()?
556+ op_zorba:json-item-accessor($i as item()?) as item()*
557
558 These two are zorba internal functions that are introduced by the translator
559 when translating a dynamic function invocation (DFI) expr and we know statically
560@@ -1008,60 +1008,61 @@
561 JSONItemAccessorIteratorState* state;
562 DEFAULT_STACK_INIT(JSONItemAccessorIteratorState, state, planState);
563
564- consumeNext(input, theChildren[0].getp(), planState);
565-
566- if (input->isArray())
567- {
568- if (theChildren.size() == 2 &&
569- consumeNext(selector, theChildren[1].getp(), planState))
570- {
571- GenericCast::castToBuiltinAtomic(selector2,
572- selector,
573- store::XS_INTEGER,
574- NULL,
575- loc);
576-
577- result = input->getArrayValue(selector2->getIntegerValue());
578-
579- STACK_PUSH(result != 0, state);
580- }
581- else
582- {
583- state->theIterator = input->getArrayValues();
584-
585- state->theIterator->open();
586- while (state->theIterator->next(result))
587- {
588- STACK_PUSH(true, state);
589- }
590- state->theIterator->close();
591- }
592- }
593- else if (input->isObject())
594- {
595- if (theChildren.size() == 2 &&
596- consumeNext(selector, theChildren[1].getp(), planState))
597- {
598- GenericCast::castToBuiltinAtomic(selector2,
599- selector,
600- store::XS_STRING,
601- NULL,
602- loc);
603-
604- result = input->getObjectValue(selector2);
605-
606- STACK_PUSH(result != 0, state);
607- }
608- else
609- {
610- state->theIterator = input->getObjectKeys();
611-
612- state->theIterator->open();
613- while (state->theIterator->next(result))
614- {
615- STACK_PUSH(true, state);
616- }
617- state->theIterator->close();
618+ if (consumeNext(input, theChildren[0].getp(), planState))
619+ {
620+ if (input->isArray())
621+ {
622+ if (theChildren.size() == 2 &&
623+ consumeNext(selector, theChildren[1].getp(), planState))
624+ {
625+ GenericCast::castToBuiltinAtomic(selector2,
626+ selector,
627+ store::XS_INTEGER,
628+ NULL,
629+ loc);
630+
631+ result = input->getArrayValue(selector2->getIntegerValue());
632+
633+ STACK_PUSH(result != 0, state);
634+ }
635+ else
636+ {
637+ state->theIterator = input->getArrayValues();
638+
639+ state->theIterator->open();
640+ while (state->theIterator->next(result))
641+ {
642+ STACK_PUSH(true, state);
643+ }
644+ state->theIterator->close();
645+ }
646+ }
647+ else if (input->isObject())
648+ {
649+ if (theChildren.size() == 2 &&
650+ consumeNext(selector, theChildren[1].getp(), planState))
651+ {
652+ GenericCast::castToBuiltinAtomic(selector2,
653+ selector,
654+ store::XS_STRING,
655+ NULL,
656+ loc);
657+
658+ result = input->getObjectValue(selector2);
659+
660+ STACK_PUSH(result != 0, state);
661+ }
662+ else
663+ {
664+ state->theIterator = input->getObjectKeys();
665+
666+ state->theIterator->open();
667+ while (state->theIterator->next(result))
668+ {
669+ STACK_PUSH(true, state);
670+ }
671+ state->theIterator->close();
672+ }
673 }
674 }
675
676@@ -1190,15 +1191,16 @@
677 PlanIteratorState* state;
678 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
679
680- consumeNext(input, theChild0.getp(), planState);
681-
682- if (input->isObject())
683+ if (consumeNext(input, theChild0.getp(), planState))
684 {
685- if (consumeNext(name, theChild1.getp(), planState))
686+ if (input->isObject())
687 {
688- result = input->getObjectValue(name);
689-
690+ if (consumeNext(name, theChild1.getp(), planState))
691+ {
692+ result = input->getObjectValue(name);
693+
694 STACK_PUSH(result != NULL, state);
695+ }
696 }
697 }
698
699@@ -1308,15 +1310,16 @@
700 PlanIteratorState* state;
701 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
702
703- consumeNext(input, theChild0.getp(), planState);
704-
705- if (input->isArray())
706+ if (consumeNext(input, theChild0.getp(), planState))
707 {
708- if (consumeNext(position, theChild1.getp(), planState))
709+ if (input->isArray())
710 {
711- result = input->getArrayValue(position->getIntegerValue());
712-
713- STACK_PUSH(result != 0, state);
714+ if (consumeNext(position, theChild1.getp(), planState))
715+ {
716+ result = input->getArrayValue(position->getIntegerValue());
717+
718+ STACK_PUSH(result != 0, state);
719+ }
720 }
721 }
722
723
724=== modified file 'src/runtime/spec/json/jsoniq_functions.xml'
725--- src/runtime/spec/json/jsoniq_functions.xml 2013-06-18 18:55:33 +0000
726+++ src/runtime/spec/json/jsoniq_functions.xml 2013-08-12 10:27:34 +0000
727@@ -240,17 +240,18 @@
728 <zorba:function isDeterministic="true">
729
730 <zorba:signature localname="json-item-accessor" prefix="op-zorba">
731- <zorba:param>item()</zorba:param>
732+ <zorba:param>item()?</zorba:param>
733 <zorba:output>item()*</zorba:output>
734 </zorba:signature>
735
736 <zorba:signature localname="json-item-accessor" prefix="op-zorba">
737- <zorba:param>item()</zorba:param>
738+ <zorba:param>item()?</zorba:param>
739 <zorba:param>item()?</zorba:param>
740 <zorba:output>item()?</zorba:output>
741 </zorba:signature>
742
743 <zorba:methods>
744+ <zorba:getReturnType/>
745 <zorba:propagatesInputNodes producer="0"/>
746 <zorba:mustCopyInputNodes value="false"/>
747 </zorba:methods>
748@@ -338,13 +339,14 @@
749
750 <zorba:function isDeterministic="true">
751
752- <zorba:signature localname="value" prefix="fn-jsoniq">
753- <zorba:param>item()</zorba:param>
754+ <zorba:signature localname="object-value" prefix="op-zorba">
755+ <zorba:param>item()?</zorba:param>
756 <zorba:param>item()?</zorba:param>
757 <zorba:output>item()?</zorba:output>
758 </zorba:signature>
759
760 <zorba:methods>
761+ <zorba:getReturnType/>
762 <zorba:propagatesInputNodes producer="0"/>
763 <zorba:mustCopyInputNodes value="false"/>
764 </zorba:methods>
765@@ -386,13 +388,14 @@
766
767 <zorba:function isDeterministic="true">
768
769- <zorba:signature localname="member" prefix="fn-jsoniq">
770- <zorba:param>item()</zorba:param>
771+ <zorba:signature localname="array-member" prefix="op-zorba">
772+ <zorba:param>item()?</zorba:param>
773 <zorba:param>item()?</zorba:param>
774 <zorba:output>item()?</zorba:output>
775 </zorba:signature>
776
777 <zorba:methods>
778+ <zorba:getReturnType/>
779 <zorba:propagatesInputNodes producer="0"/>
780 <zorba:mustCopyInputNodes value="false"/>
781 </zorba:methods>
782
783=== added directory 'test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq'
784=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter'
785--- test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter 1970-01-01 00:00:00 +0000
786+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter 2013-08-12 10:27:34 +0000
787@@ -0,0 +1,31 @@
788+Iterator tree for main query:
789+<flwor::FLWORIterator>
790+ <LetVariable name="j" materialize="true">
791+ <TreatIterator quant="?">
792+ <JSONParseIterator>
793+ <SingletonIterator value="xs:string([ "foo", "bar" ])"/>
794+ </JSONParseIterator>
795+ </TreatIterator>
796+ </LetVariable>
797+ <ReturnClause>
798+ <FnConcatIterator>
799+ <FnEmptyIterator>
800+ <JSONItemAccessorIterator>
801+ <LetVarIterator varname="j"/>
802+ <SingletonIterator value="xs:integer(0)"/>
803+ </JSONItemAccessorIterator>
804+ </FnEmptyIterator>
805+ <JSONItemAccessorIterator>
806+ <LetVarIterator varname="j"/>
807+ <SingletonIterator value="xs:integer(1)"/>
808+ </JSONItemAccessorIterator>
809+ <FnEmptyIterator>
810+ <JSONItemAccessorIterator>
811+ <LetVarIterator varname="j"/>
812+ <SingletonIterator value="xs:integer(3)"/>
813+ </JSONItemAccessorIterator>
814+ </FnEmptyIterator>
815+ </FnConcatIterator>
816+ </ReturnClause>
817+</flwor::FLWORIterator>
818+
819
820=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/xray/ppm_10.iter'
821--- test/rbkt/ExpCompilerResults/IterPlan/zorba/xray/ppm_10.iter 2013-05-24 16:34:11 +0000
822+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/xray/ppm_10.iter 2013-08-12 10:27:34 +0000
823@@ -1321,8 +1321,8 @@
824 Iterator tree for shapes:intersect-plane:
825 <flwor::TupleStreamIterator>
826 <flwor::WhereIterator>
827- <flwor::ForIterator>
828- <ForVariable name="$$context-item"/>
829+ <flwor::LetIterator>
830+ <LetVariable name="$$temp3" materialize="true"/>
831 <flwor::WhereIterator>
832 <flwor::ForIterator>
833 <ForVariable name="denom"/>
834@@ -1422,13 +1422,13 @@
835 <ForVarIterator varname="denom"/>
836 </SpecificNumArithIterator_DivideOperation_DOUBLE>
837 </SpecificNumArithIterator_SubtractOperation_DOUBLE>
838- </flwor::ForIterator>
839+ </flwor::LetIterator>
840 <TypedValueCompareIterator_DOUBLE>
841- <ForVarIterator varname="$$context-item"/>
842+ <LetVarIterator varname="$$temp3"/>
843 <SingletonIterator value="xs:double(0)"/>
844 </TypedValueCompareIterator_DOUBLE>
845 </flwor::WhereIterator>
846- <ForVarIterator varname="$$context-item"/>
847+ <LetVarIterator varname="$$temp3"/>
848 </flwor::TupleStreamIterator>
849
850 Iterator tree for shapes:intersect-sphere:
851
852=== modified file 'test/rbkt/Queries/zorba/jsoniq/member_01.xq'
853--- test/rbkt/Queries/zorba/jsoniq/member_01.xq 2013-02-07 17:24:36 +0000
854+++ test/rbkt/Queries/zorba/jsoniq/member_01.xq 2013-08-12 10:27:34 +0000
855@@ -1,4 +1,4 @@
856 import module namespace j = "http://jsoniq.org/functions";
857
858-let $j := j:parse-json('[ "foo", "bar" ]')
859-return (empty(j:member($j, 0)), j:member($j, 1), empty(j:member($j, 3)))
860+let $j as item()? := j:parse-json('[ "foo", "bar" ]')
861+return (empty($j(0)), $j(1), empty($j(3)))
862
863=== modified file 'test/rbkt/Queries/zorba/jsoniq/pair_01.xq'
864--- test/rbkt/Queries/zorba/jsoniq/pair_01.xq 2013-02-07 17:24:36 +0000
865+++ test/rbkt/Queries/zorba/jsoniq/pair_01.xq 2013-08-12 10:27:34 +0000
866@@ -1,5 +1,5 @@
867 import module namespace j = "http://jsoniq.org/functions";
868
869-let $j := j:parse-json('{ "foo": "bar" }')
870-return (empty(j:value($j, "bar")), j:value($j, "foo"))
871+let $j as object()? := j:parse-json('{ "foo": "bar" }')
872+return (empty($j("bar")), $j("foo"))
873

Subscribers

People subscribed via source and target branches