← Back to team overview

zorba-coders team mailing list archive

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

 

Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/markos-scratch into lp:zorba.

Commit message:
don't do unnecessary implicit iteration for jsoniq navigation

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/179411

don't do unnecessary implicit iteration for jsoniq navigation
-- 
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/179411
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'modules/org/jsoniq/www/functions.xq'
--- modules/org/jsoniq/www/functions.xq	2013-06-19 14:19:40 +0000
+++ modules/org/jsoniq/www/functions.xq	2013-08-09 10:32:03 +0000
@@ -197,18 +197,6 @@
 
 
 (:~
- : Returns the value of a JSON Pair with a given name within a given JSON object.
- : If no such pair exists in the object, returns the empty sequence.
- :
- : @param $o A JSON Object.
- : @param $name The name of the pair whose value is to be retrieved
- : @return the value of specified pair within the given object, or the empty sequence.
- :)
-(: obsolete - use $o($name) instead :)
-declare function jn:value($o as item(), $name as item()?) as item()? external;
-
-
-(:~
  : Creates an object from the specified pairs of another given object. 
  : Specifically, for each name in $names, if the object $o has a pair with
  : that name, then a copy of that pair is included in the new object.
@@ -231,18 +219,6 @@
 
 
 (:~
- : Returns the member of an Array at the specified position (starting from 1).
- : If the position is out of bounds of the array, returns the empty sequence.
- :
- : @param $a A JSON Array.
- : @param $p The position in the array.
- : @return The member at the specified position, or empty sequence.
- :)
-(: obsolete - use $a($p) or $a[[$p]] instead :)
-declare function jn:member($a as item(), $p as item()?) as item()? external;
-
-
-(:~
  : Returns the items belonging to the arrays found inside a given sequence
  : of items. The items are returned in an implementation-defined order.
  :

=== modified file 'src/compiler/rewriter/rules/flwor_rules.cpp'
--- src/compiler/rewriter/rules/flwor_rules.cpp	2013-06-14 04:50:39 +0000
+++ src/compiler/rewriter/rules/flwor_rules.cpp	2013-08-09 10:32:03 +0000
@@ -462,7 +462,8 @@
       // since one value is still returned, count variables are changed to 1
       subst_vars(rCtx,
                  static_cast<count_clause*>(clause)->get_var(),
-                 rCtx.theEM->create_const_expr(sctx, udf, loc, numeric_consts<xs_integer>::one()),
+                 rCtx.theEM->create_const_expr(sctx, udf, loc,
+                                               numeric_consts<xs_integer>::one()),
                  2);
 
       theFlwor->remove_clause(0);
@@ -537,7 +538,21 @@
   if (is_trivial_expr(varDomExpr))
   {
     numRefs = 2;
-    return isSafeVar;
+    
+    if (isSafeVar)
+    {
+      return true;
+    }
+    else
+    {
+      expr* retExpr = theFlwor->get_return_expr();
+      xqtref_t type = retExpr->get_return_type_with_empty_input(var);
+        
+      return TypeOps::is_equal(theFlwor->get_type_manager(),
+                               *type,
+                               *GENV_TYPESYSTEM.EMPTY_TYPE,
+                               retExpr->get_loc());
+    }
   }
 
   // If set to true, then it is unsafe to fold, but we may still be able to

=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp	2013-08-02 18:29:44 +0000
+++ src/compiler/translator/translator.cpp	2013-08-09 10:32:03 +0000
@@ -10843,7 +10843,7 @@
     args[1] = selectorExpr;
 
     expr* accessorExpr =
-    generate_fn_body(BUILTIN_FUNC(FN_JSONIQ_MEMBER_2), args, loc);
+    generate_fn_body(BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2), args, loc);
 
     assert(accessorExpr->get_expr_kind() == fo_expr_kind);
 
@@ -10889,7 +10889,7 @@
           {
             fo_expr* pointExpr = 
             CREATE(fo)(sourceExpr->get_sctx(), theUDF, sourceExpr->get_loc(),
-                       BUILTIN_FUNC(FN_JSONIQ_MEMBER_2),
+                       BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2),
                        arrayExpr,
                        predExpr);
             
@@ -11072,27 +11072,42 @@
 
   assert(selectExpr && objectExpr);
 
-  flwor_expr* flworExpr = wrap_expr_in_flwor(objectExpr, false);
-
-  for_clause* fc = static_cast<for_clause*>(flworExpr->get_clause(0));
-
-  expr* flworVarExpr = CREATE(wrapper)(theRootSctx, theUDF, loc, fc->get_var());
-
-  expr* accessorExpr;
-
-  std::vector<expr*> args(2);
-  args[0] = flworVarExpr;
-  args[1] = selectExpr;
-
-  accessorExpr = generate_fn_body(BUILTIN_FUNC(FN_JSONIQ_VALUE_2), args, loc);
-
-  assert(accessorExpr->get_expr_kind() == fo_expr_kind);
-
-  flworExpr->set_return_expr(accessorExpr);
-
-  pop_scope();
-
-  push_nodestack(flworExpr);
+  xqtref_t domainType = objectExpr->get_return_type();
+
+  if (domainType->max_card() > 1)
+  {
+    flwor_expr* flworExpr = wrap_expr_in_flwor(objectExpr, false);
+
+    for_clause* fc = static_cast<for_clause*>(flworExpr->get_clause(0));
+
+    expr* flworVarExpr = CREATE(wrapper)(theRootSctx, theUDF, loc, fc->get_var());
+
+    std::vector<expr*> args(2);
+    args[0] = flworVarExpr;
+    args[1] = selectExpr;
+
+    expr* accessorExpr =
+    generate_fn_body(BUILTIN_FUNC(OP_ZORBA_OBJECT_VALUE_2), args, loc);
+
+    assert(accessorExpr->get_expr_kind() == fo_expr_kind);
+
+    flworExpr->set_return_expr(accessorExpr);
+
+    pop_scope();
+
+    push_nodestack(flworExpr);
+  }
+  else
+  {
+    std::vector<expr*> args(2);
+    args[0] = objectExpr;
+    args[1] = selectExpr;
+
+    expr* accessorExpr =
+    generate_fn_body(BUILTIN_FUNC(OP_ZORBA_OBJECT_VALUE_2), args, loc);
+
+    push_nodestack(accessorExpr);
+  }
 }
 
 
@@ -12191,14 +12206,14 @@
 
     break;
   }
-  case FunctionConsts::FN_JSONIQ_VALUE_2:
+  case FunctionConsts::OP_ZORBA_OBJECT_VALUE_2:
   {
     arguments[1] = 
     create_cast_expr(loc, arguments[1], theRTM.STRING_TYPE_ONE, true, true);
 
     break;
   }
-  case FunctionConsts::FN_JSONIQ_MEMBER_2:
+  case FunctionConsts::OP_ZORBA_ARRAY_MEMBER_2:
   {
     arguments[1] =
     create_cast_expr(loc, arguments[1], theRTM.INTEGER_TYPE_ONE, true, true);
@@ -12501,11 +12516,11 @@
     {
       if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ARRAY_TYPE_STAR))
       {
-        func = BUILTIN_FUNC(FN_JSONIQ_MEMBER_2);
+        func = BUILTIN_FUNC(OP_ZORBA_ARRAY_MEMBER_2);
       }
       else if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_OBJECT_TYPE_STAR))
       {
-        func = BUILTIN_FUNC(FN_JSONIQ_VALUE_2);
+        func = BUILTIN_FUNC(OP_ZORBA_OBJECT_VALUE_2);
       }
       else
       {

=== modified file 'src/functions/func_jsoniq_functions_impl.cpp'
--- src/functions/func_jsoniq_functions_impl.cpp	2013-06-08 05:33:57 +0000
+++ src/functions/func_jsoniq_functions_impl.cpp	2013-08-09 10:32:03 +0000
@@ -31,6 +31,41 @@
 namespace zorba
 {
 
+/*******************************************************************************
+
+********************************************************************************/
+xqtref_t op_zorba_json_item_accessor::getReturnType(const fo_expr* caller) const
+{
+  if (caller->get_arg(0)->get_return_type()->max_card() == 0)
+    return GENV_TYPESYSTEM.EMPTY_TYPE;
+
+  return theSignature.returnType();
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+xqtref_t op_zorba_object_value::getReturnType(const fo_expr* caller) const
+{
+  if (caller->get_arg(0)->get_return_type()->max_card() == 0)
+    return GENV_TYPESYSTEM.EMPTY_TYPE;
+
+  return theSignature.returnType();
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+xqtref_t op_zorba_array_member::getReturnType(const fo_expr* caller) const
+{
+  if (caller->get_arg(0)->get_return_type()->max_card() == 0)
+    return GENV_TYPESYSTEM.EMPTY_TYPE;
+
+  return theSignature.returnType();
+}
+
 
 /*******************************************************************************
 

=== modified file 'src/functions/pregenerated/func_jsoniq_functions.cpp'
--- src/functions/pregenerated/func_jsoniq_functions.cpp	2013-06-08 05:33:57 +0000
+++ src/functions/pregenerated/func_jsoniq_functions.cpp	2013-08-09 10:32:03 +0000
@@ -83,7 +83,7 @@
   return new SingleObjectNamesIterator(sctx, loc, argv[0]);
 }
 
-PlanIter_t fn_jsoniq_value::codegen(
+PlanIter_t op_zorba_object_value::codegen(
   CompilerCB*,
   static_context* sctx,
   const QueryLoc& loc,
@@ -103,7 +103,7 @@
   return new JSONObjectProjectIterator(sctx, loc, argv[0], argv[1]);
 }
 
-PlanIter_t fn_jsoniq_member::codegen(
+PlanIter_t op_zorba_array_member::codegen(
   CompilerCB*,
   static_context* sctx,
   const QueryLoc& loc,
@@ -319,7 +319,7 @@
       {
     DECL_WITH_KIND(sctx, op_zorba_json_item_accessor,
         (createQName("http://www.zorba-xquery.com/internal/zorba-ops","","json-item-accessor";), 
-        GENV_TYPESYSTEM.ITEM_TYPE_ONE, 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
         GENV_TYPESYSTEM.ITEM_TYPE_STAR),
         FunctionConsts::OP_ZORBA_JSON_ITEM_ACCESSOR_1);
 
@@ -331,7 +331,7 @@
       {
     DECL_WITH_KIND(sctx, op_zorba_json_item_accessor,
         (createQName("http://www.zorba-xquery.com/internal/zorba-ops","","json-item-accessor";), 
-        GENV_TYPESYSTEM.ITEM_TYPE_ONE, 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
         GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
         GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
         FunctionConsts::OP_ZORBA_JSON_ITEM_ACCESSOR_2);
@@ -366,12 +366,12 @@
 
 
       {
-    DECL_WITH_KIND(sctx, fn_jsoniq_value,
-        (createQName("http://jsoniq.org/functions","","value";), 
-        GENV_TYPESYSTEM.ITEM_TYPE_ONE, 
+    DECL_WITH_KIND(sctx, op_zorba_object_value,
+        (createQName("http://www.zorba-xquery.com/internal/zorba-ops","","object-value";), 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
         GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
         GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
-        FunctionConsts::FN_JSONIQ_VALUE_2);
+        FunctionConsts::OP_ZORBA_OBJECT_VALUE_2);
 
   }
 
@@ -392,12 +392,12 @@
 
 
       {
-    DECL_WITH_KIND(sctx, fn_jsoniq_member,
-        (createQName("http://jsoniq.org/functions","","member";), 
-        GENV_TYPESYSTEM.ITEM_TYPE_ONE, 
+    DECL_WITH_KIND(sctx, op_zorba_array_member,
+        (createQName("http://www.zorba-xquery.com/internal/zorba-ops","","array-member";), 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
         GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
         GENV_TYPESYSTEM.ITEM_TYPE_QUESTION),
-        FunctionConsts::FN_JSONIQ_MEMBER_2);
+        FunctionConsts::OP_ZORBA_ARRAY_MEMBER_2);
 
   }
 

=== modified file 'src/functions/pregenerated/func_jsoniq_functions.h'
--- src/functions/pregenerated/func_jsoniq_functions.h	2013-06-08 05:33:57 +0000
+++ src/functions/pregenerated/func_jsoniq_functions.h	2013-08-09 10:32:03 +0000
@@ -125,6 +125,8 @@
 
   }
 
+  xqtref_t getReturnType(const fo_expr* caller) const;
+
   bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
 
   bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
@@ -173,17 +175,19 @@
 };
 
 
-//fn-jsoniq:value
-class fn_jsoniq_value : public function
+//op-zorba:object-value
+class op_zorba_object_value : public function
 {
 public:
-  fn_jsoniq_value(const signature& sig, FunctionConsts::FunctionKind kind)
+  op_zorba_object_value(const signature& sig, FunctionConsts::FunctionKind kind)
     : 
     function(sig, kind)
   {
 
   }
 
+  xqtref_t getReturnType(const fo_expr* caller) const;
+
   bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
 
   bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
@@ -211,17 +215,19 @@
 };
 
 
-//fn-jsoniq:member
-class fn_jsoniq_member : public function
+//op-zorba:array-member
+class op_zorba_array_member : public function
 {
 public:
-  fn_jsoniq_member(const signature& sig, FunctionConsts::FunctionKind kind)
+  op_zorba_array_member(const signature& sig, FunctionConsts::FunctionKind kind)
     : 
     function(sig, kind)
   {
 
   }
 
+  xqtref_t getReturnType(const fo_expr* caller) const;
+
   bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
 
   bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }

=== modified file 'src/functions/pregenerated/function_enum.h'
--- src/functions/pregenerated/function_enum.h	2013-07-26 21:05:40 +0000
+++ src/functions/pregenerated/function_enum.h	2013-08-09 10:32:03 +0000
@@ -263,9 +263,9 @@
   OP_ZORBA_JSON_ITEM_ACCESSOR_2,
   FN_JSONIQ_KEYS_1,
   OP_ZORBA_KEYS_1,
-  FN_JSONIQ_VALUE_2,
+  OP_ZORBA_OBJECT_VALUE_2,
   FN_JSONIQ_PROJECT_2,
-  FN_JSONIQ_MEMBER_2,
+  OP_ZORBA_ARRAY_MEMBER_2,
   FN_JSONIQ_MEMBERS_1,
   OP_ZORBA_MEMBERS_1,
   FN_JSONIQ_SIZE_1,

=== modified file 'src/runtime/json/jsoniq_functions_impl.cpp'
--- src/runtime/json/jsoniq_functions_impl.cpp	2013-06-18 18:55:33 +0000
+++ src/runtime/json/jsoniq_functions_impl.cpp	2013-08-09 10:32:03 +0000
@@ -985,9 +985,9 @@
 
 
 /*******************************************************************************
-  op_zorba:json-item-accessor($i as item(), $sel as item()) as item()?
+  op_zorba:json-item-accessor($i as item()?, $sel as item()?) as item()?
 
-  op_zorba:json-item-accessor($i as item()) as item()?
+  op_zorba:json-item-accessor($i as item()?) as item()*
 
   These two are zorba internal functions that are introduced by the translator
   when translating a dynamic function invocation (DFI) expr and we know statically
@@ -1008,60 +1008,61 @@
   JSONItemAccessorIteratorState* state;
   DEFAULT_STACK_INIT(JSONItemAccessorIteratorState, state, planState);
 
-  consumeNext(input, theChildren[0].getp(), planState);
-
-  if (input->isArray())
-  {
-    if (theChildren.size() == 2 &&
-        consumeNext(selector, theChildren[1].getp(), planState))
-    {
-      GenericCast::castToBuiltinAtomic(selector2,
-                                       selector,
-                                       store::XS_INTEGER,
-                                       NULL,
-                                       loc);
-
-      result = input->getArrayValue(selector2->getIntegerValue());
-
-      STACK_PUSH(result != 0, state);
-    }
-    else
-    {
-      state->theIterator = input->getArrayValues();
-
-      state->theIterator->open();
-      while (state->theIterator->next(result))
-      {
-        STACK_PUSH(true, state);
-      }
-      state->theIterator->close();
-    }
-  }
-  else if (input->isObject())
-  {
-    if (theChildren.size() == 2 &&
-        consumeNext(selector, theChildren[1].getp(), planState))
-    {
-      GenericCast::castToBuiltinAtomic(selector2,
-                                       selector,
-                                       store::XS_STRING,
-                                       NULL,
-                                       loc);
-
-      result = input->getObjectValue(selector2);
-
-      STACK_PUSH(result != 0, state);
-    }
-    else
-    {
-      state->theIterator = input->getObjectKeys();
-
-      state->theIterator->open();
-      while (state->theIterator->next(result))
-      {
-        STACK_PUSH(true, state);
-      }
-      state->theIterator->close();
+  if (consumeNext(input, theChildren[0].getp(), planState))
+  {
+    if (input->isArray())
+    {
+      if (theChildren.size() == 2 &&
+          consumeNext(selector, theChildren[1].getp(), planState))
+      {
+        GenericCast::castToBuiltinAtomic(selector2,
+                                         selector,
+                                         store::XS_INTEGER,
+                                         NULL,
+                                         loc);
+
+        result = input->getArrayValue(selector2->getIntegerValue());
+        
+        STACK_PUSH(result != 0, state);
+      }
+      else
+      {
+        state->theIterator = input->getArrayValues();
+        
+        state->theIterator->open();
+        while (state->theIterator->next(result))
+        {
+          STACK_PUSH(true, state);
+        }
+        state->theIterator->close();
+      }
+    }
+    else if (input->isObject())
+    {
+      if (theChildren.size() == 2 &&
+          consumeNext(selector, theChildren[1].getp(), planState))
+      {
+        GenericCast::castToBuiltinAtomic(selector2,
+                                         selector,
+                                         store::XS_STRING,
+                                         NULL,
+                                         loc);
+        
+        result = input->getObjectValue(selector2);
+        
+        STACK_PUSH(result != 0, state);
+      }
+      else
+      {
+        state->theIterator = input->getObjectKeys();
+        
+        state->theIterator->open();
+        while (state->theIterator->next(result))
+        {
+          STACK_PUSH(true, state);
+        }
+        state->theIterator->close();
+      }
     }
   }
 
@@ -1190,15 +1191,16 @@
   PlanIteratorState* state;
   DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
 
-  consumeNext(input, theChild0.getp(), planState);
-
-  if (input->isObject())
+  if (consumeNext(input, theChild0.getp(), planState))
   {
-    if (consumeNext(name, theChild1.getp(), planState))
+    if (input->isObject())
     {
-      result = input->getObjectValue(name);
-
+      if (consumeNext(name, theChild1.getp(), planState))
+      {
+        result = input->getObjectValue(name);
+        
       STACK_PUSH(result != NULL, state);
+      }
     }
   }
 
@@ -1308,15 +1310,16 @@
   PlanIteratorState* state;
   DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
 
-  consumeNext(input, theChild0.getp(), planState);
-
-  if (input->isArray())
+  if (consumeNext(input, theChild0.getp(), planState))
   {
-    if (consumeNext(position, theChild1.getp(), planState))
+    if (input->isArray())
     {
-      result = input->getArrayValue(position->getIntegerValue());
-
-      STACK_PUSH(result != 0, state);
+      if (consumeNext(position, theChild1.getp(), planState))
+      {
+        result = input->getArrayValue(position->getIntegerValue());
+        
+        STACK_PUSH(result != 0, state);
+      }
     }
   }
 

=== modified file 'src/runtime/spec/json/jsoniq_functions.xml'
--- src/runtime/spec/json/jsoniq_functions.xml	2013-06-18 18:55:33 +0000
+++ src/runtime/spec/json/jsoniq_functions.xml	2013-08-09 10:32:03 +0000
@@ -240,17 +240,18 @@
   <zorba:function isDeterministic="true">
 
     <zorba:signature localname="json-item-accessor" prefix="op-zorba">
-      <zorba:param>item()</zorba:param>
+      <zorba:param>item()?</zorba:param>
       <zorba:output>item()*</zorba:output>
     </zorba:signature>
 
     <zorba:signature localname="json-item-accessor" prefix="op-zorba">
-      <zorba:param>item()</zorba:param>
+      <zorba:param>item()?</zorba:param>
       <zorba:param>item()?</zorba:param>
       <zorba:output>item()?</zorba:output>
     </zorba:signature>
 
     <zorba:methods>
+      <zorba:getReturnType/>
       <zorba:propagatesInputNodes producer="0"/>
       <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
@@ -338,13 +339,14 @@
 
   <zorba:function isDeterministic="true">
 
-    <zorba:signature localname="value" prefix="fn-jsoniq">
-      <zorba:param>item()</zorba:param>
+    <zorba:signature localname="object-value" prefix="op-zorba">
+      <zorba:param>item()?</zorba:param>
       <zorba:param>item()?</zorba:param>
       <zorba:output>item()?</zorba:output>
     </zorba:signature>
 
     <zorba:methods>
+      <zorba:getReturnType/>
       <zorba:propagatesInputNodes producer="0"/>
       <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>
@@ -386,13 +388,14 @@
 
   <zorba:function isDeterministic="true">
 
-    <zorba:signature localname="member" prefix="fn-jsoniq">
-      <zorba:param>item()</zorba:param>
+    <zorba:signature localname="array-member" prefix="op-zorba">
+      <zorba:param>item()?</zorba:param>
       <zorba:param>item()?</zorba:param>
       <zorba:output>item()?</zorba:output>
     </zorba:signature>
 
     <zorba:methods>
+      <zorba:getReturnType/>
       <zorba:propagatesInputNodes producer="0"/>
       <zorba:mustCopyInputNodes value="false"/>
     </zorba:methods>

=== added directory 'test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq'
=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/jsoniq/member_01.iter	2013-08-09 10:32:03 +0000
@@ -0,0 +1,31 @@
+Iterator tree for main query:
+<flwor::FLWORIterator>
+  <LetVariable name="j" materialize="true">
+    <TreatIterator quant="?">
+      <JSONParseIterator>
+        <SingletonIterator value="xs:string([ "foo", "bar" ])"/>
+      </JSONParseIterator>
+    </TreatIterator>
+  </LetVariable>
+  <ReturnClause>
+    <FnConcatIterator>
+      <FnEmptyIterator>
+        <JSONItemAccessorIterator>
+          <LetVarIterator varname="j"/>
+          <SingletonIterator value="xs:integer(0)"/>
+        </JSONItemAccessorIterator>
+      </FnEmptyIterator>
+      <JSONItemAccessorIterator>
+        <LetVarIterator varname="j"/>
+        <SingletonIterator value="xs:integer(1)"/>
+      </JSONItemAccessorIterator>
+      <FnEmptyIterator>
+        <JSONItemAccessorIterator>
+          <LetVarIterator varname="j"/>
+          <SingletonIterator value="xs:integer(3)"/>
+        </JSONItemAccessorIterator>
+      </FnEmptyIterator>
+    </FnConcatIterator>
+  </ReturnClause>
+</flwor::FLWORIterator>
+

=== modified file 'test/rbkt/Queries/zorba/jsoniq/member_01.xq'
--- test/rbkt/Queries/zorba/jsoniq/member_01.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/jsoniq/member_01.xq	2013-08-09 10:32:03 +0000
@@ -1,4 +1,4 @@
 import module namespace j = "http://jsoniq.org/functions";;
 
-let $j := j:parse-json('[ "foo", "bar" ]')
-return (empty(j:member($j, 0)), j:member($j, 1), empty(j:member($j, 3)))
+let $j as item()? := j:parse-json('[ "foo", "bar" ]')
+return (empty($j(0)), $j(1), empty($j(3)))

=== modified file 'test/rbkt/Queries/zorba/jsoniq/pair_01.xq'
--- test/rbkt/Queries/zorba/jsoniq/pair_01.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/jsoniq/pair_01.xq	2013-08-09 10:32:03 +0000
@@ -1,5 +1,5 @@
 import module namespace j = "http://jsoniq.org/functions";;
 
-let $j := j:parse-json('{ "foo": "bar" }')
-return (empty(j:value($j, "bar")), j:value($j, "foo"))
+let $j as object()? := j:parse-json('{ "foo": "bar" }')
+return (empty($j("bar")), $j("foo"))
 


Follow ups