← 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:
allow item()* as the input of jn:keys and jn:members functions

Requested reviews:
  Markos Zaharioudakis (markos-za)

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

allow item()* as the input of jn:keys and jn:members functions
-- 
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/168232
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2013-06-06 18:33:17 +0000
+++ ChangeLog	2013-06-08 05:35:32 +0000
@@ -4,7 +4,7 @@
 version 3.0
 
 New Features:
-
+  
 Optimizations:
   * Implemented hoisting optimization for general FLWOR.
   * Implemented flwor-merge optimization for general FLWOR.
@@ -25,7 +25,13 @@
   * Fixed bug #1188100 (regex issues with 'q' flag in fn:tokenize)
   * Fixed invalid memory access error occuring during sequence type matching
     for user-defined types.
-
+  * jn:members function takes item()* as aparameter (instead of item())
+  * jn:keys function takes item()* as aparameter (instead of item())
+  * Object/array navigation allows item()* as the type of the input sequence
+    (doing implicit iteration over the input sequence and skipping items
+     that are not objects/arrays).
+  * Bug fix: selector value in object/array navigation is always cast to
+    string/integer
 
 version 2.9
 

=== modified file 'modules/org/jsoniq/www/functions.xq'
--- modules/org/jsoniq/www/functions.xq	2013-06-05 00:37:35 +0000
+++ modules/org/jsoniq/www/functions.xq	2013-06-08 05:35:32 +0000
@@ -193,7 +193,7 @@
  : @param $o A JSON Object.
  : @return The names of pairs in the object.
  :)
-declare function jn:keys($o as item()) as xs:string* external;
+declare function jn:keys($o as item()*) as xs:string* external;
 
 
 (:~
@@ -248,7 +248,7 @@
  : @param $a A JSON Array.
  : @return The members of the specified array.
  :)
-declare function jn:members($o as item()) as item()* external;
+declare function jn:members($o as item()*) as item()* external;
 
 
 (:~

=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp	2013-06-05 07:26:13 +0000
+++ src/compiler/translator/translator.cpp	2013-06-08 05:35:32 +0000
@@ -12093,6 +12093,20 @@
 
     break;
   }
+  case FunctionConsts::FN_JSONIQ_KEYS_1:
+  {
+    if (arguments[0]->get_return_type()->max_card() <= 1)
+      f = BUILTIN_FUNC(OP_ZORBA_KEYS_1);
+
+    break;
+  }
+  case FunctionConsts::FN_JSONIQ_MEMBERS_1:
+  {
+    if (arguments[0]->get_return_type()->max_card() <= 1)
+      f = BUILTIN_FUNC(OP_ZORBA_MEMBERS_1);
+
+    break;
+  }
   case FunctionConsts::FN_CONCAT_N:
   {
     if (numArgs < 2)
@@ -12380,11 +12394,11 @@
     {
       if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ARRAY_TYPE_STAR))
       {
-        func = BUILTIN_FUNC(FN_JSONIQ_MEMBERS_1);
+        func = BUILTIN_FUNC(OP_ZORBA_MEMBERS_1);
       }
       else if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_OBJECT_TYPE_STAR))
       {
-        func = BUILTIN_FUNC(FN_JSONIQ_KEYS_1);
+        func = BUILTIN_FUNC(OP_ZORBA_KEYS_1);
       }
       else
       {

=== modified file 'src/functions/func_jsoniq_functions_impl.cpp'
--- src/functions/func_jsoniq_functions_impl.cpp	2013-02-07 17:24:36 +0000
+++ src/functions/func_jsoniq_functions_impl.cpp	2013-06-08 05:35:32 +0000
@@ -31,7 +31,39 @@
 namespace zorba
 {
 
-#ifdef ZORBA_WITH_JSON
+
+/*******************************************************************************
+
+********************************************************************************/
+PlanIter_t fn_jsoniq_keys::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& arg) const
+{
+  if (arg.get_return_type()->max_card() <= 1)
+    return new SingleObjectNamesIterator(sctx, loc, argv[0]);
+
+  return new JSONObjectNamesIterator(sctx, loc, argv[0]);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+PlanIter_t fn_jsoniq_members::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& arg) const
+{
+  if (arg.get_return_type()->max_card() <= 1)
+    return new SingleArrayMembersIterator(sctx, loc, argv[0]);
+
+  return new JSONArrayMembersIterator(sctx, loc, argv[0]);
+}
 
 
 /*******************************************************************************
@@ -174,8 +206,6 @@
 }
 
 
-#endif // ZORBA_WITH_JSON
-
 } /* namespace zorba */
 
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/functions/pregenerated/func_jsoniq_functions.cpp'
--- src/functions/pregenerated/func_jsoniq_functions.cpp	2013-06-05 00:37:35 +0000
+++ src/functions/pregenerated/func_jsoniq_functions.cpp	2013-06-08 05:35:32 +0000
@@ -72,14 +72,15 @@
   return new JSONItemAccessorIterator(sctx, loc, argv);
 }
 
-PlanIter_t fn_jsoniq_keys::codegen(
+
+PlanIter_t op_zorba_keys::codegen(
   CompilerCB*,
   static_context* sctx,
   const QueryLoc& loc,
   std::vector<PlanIter_t>& argv,
   expr& ann) const
 {
-  return new JSONObjectNamesIterator(sctx, loc, argv[0]);
+  return new SingleObjectNamesIterator(sctx, loc, argv[0]);
 }
 
 PlanIter_t fn_jsoniq_value::codegen(
@@ -112,14 +113,15 @@
   return new JSONArrayMemberIterator(sctx, loc, argv[0], argv[1]);
 }
 
-PlanIter_t fn_jsoniq_members::codegen(
+
+PlanIter_t op_zorba_members::codegen(
   CompilerCB*,
   static_context* sctx,
   const QueryLoc& loc,
   std::vector<PlanIter_t>& argv,
   expr& ann) const
 {
-  return new JSONArrayMembersIterator(sctx, loc, argv[0]);
+  return new SingleArrayMembersIterator(sctx, loc, argv[0]);
 }
 
 PlanIter_t fn_jsoniq_size::codegen(
@@ -342,7 +344,7 @@
       {
     DECL_WITH_KIND(sctx, fn_jsoniq_keys,
         (createQName("http://jsoniq.org/functions","","keys";), 
-        GENV_TYPESYSTEM.ITEM_TYPE_ONE, 
+        GENV_TYPESYSTEM.ITEM_TYPE_STAR, 
         GENV_TYPESYSTEM.STRING_TYPE_STAR),
         FunctionConsts::FN_JSONIQ_KEYS_1);
 
@@ -352,6 +354,18 @@
 
 
       {
+    DECL_WITH_KIND(sctx, op_zorba_keys,
+        (createQName("http://www.zorba-xquery.com/internal/zorba-ops","","keys";), 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
+        GENV_TYPESYSTEM.STRING_TYPE_STAR),
+        FunctionConsts::OP_ZORBA_KEYS_1);
+
+  }
+
+
+
+
+      {
     DECL_WITH_KIND(sctx, fn_jsoniq_value,
         (createQName("http://jsoniq.org/functions","","value";), 
         GENV_TYPESYSTEM.ITEM_TYPE_ONE, 
@@ -393,7 +407,7 @@
       {
     DECL_WITH_KIND(sctx, fn_jsoniq_members,
         (createQName("http://jsoniq.org/functions","","members";), 
-        GENV_TYPESYSTEM.ITEM_TYPE_ONE, 
+        GENV_TYPESYSTEM.ITEM_TYPE_STAR, 
         GENV_TYPESYSTEM.ITEM_TYPE_STAR),
         FunctionConsts::FN_JSONIQ_MEMBERS_1);
 
@@ -403,6 +417,18 @@
 
 
       {
+    DECL_WITH_KIND(sctx, op_zorba_members,
+        (createQName("http://www.zorba-xquery.com/internal/zorba-ops","","members";), 
+        GENV_TYPESYSTEM.ITEM_TYPE_QUESTION, 
+        GENV_TYPESYSTEM.ITEM_TYPE_STAR),
+        FunctionConsts::OP_ZORBA_MEMBERS_1);
+
+  }
+
+
+
+
+      {
     DECL_WITH_KIND(sctx, fn_jsoniq_size,
         (createQName("http://jsoniq.org/functions","","size";), 
         GENV_TYPESYSTEM.JSON_ARRAY_TYPE_ONE, 

=== modified file 'src/functions/pregenerated/func_jsoniq_functions.h'
--- src/functions/pregenerated/func_jsoniq_functions.h	2013-06-05 00:37:35 +0000
+++ src/functions/pregenerated/func_jsoniq_functions.h	2013-06-08 05:35:32 +0000
@@ -148,6 +148,27 @@
 
   bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
+  bool isMap(csize producer) const { return producer == 0; }
+
+  CODEGEN_DECL();
+};
+
+
+//op-zorba:keys
+class op_zorba_keys : public function
+{
+public:
+  op_zorba_keys(const signature& sig, FunctionConsts::FunctionKind kind)
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool propagatesInputNodes(expr* fo, csize producer) const { return false; }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
   CODEGEN_DECL();
 };
 
@@ -224,6 +245,27 @@
 
   bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
 
+  bool isMap(csize producer) const { return producer == 0; }
+
+  CODEGEN_DECL();
+};
+
+
+//op-zorba:members
+class op_zorba_members : public function
+{
+public:
+  op_zorba_members(const signature& sig, FunctionConsts::FunctionKind kind)
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool propagatesInputNodes(expr* fo, csize producer) const { return producer == 0; }
+
+  bool mustCopyInputNodes(expr* fo, csize producer) const { return false; }
+
   CODEGEN_DECL();
 };
 

=== modified file 'src/functions/pregenerated/function_enum.h'
--- src/functions/pregenerated/function_enum.h	2013-06-05 07:26:13 +0000
+++ src/functions/pregenerated/function_enum.h	2013-06-08 05:35:32 +0000
@@ -255,10 +255,12 @@
   OP_ZORBA_JSON_ITEM_ACCESSOR_1,
   OP_ZORBA_JSON_ITEM_ACCESSOR_2,
   FN_JSONIQ_KEYS_1,
+  OP_ZORBA_KEYS_1,
   FN_JSONIQ_VALUE_2,
   FN_JSONIQ_PROJECT_2,
   FN_JSONIQ_MEMBER_2,
   FN_JSONIQ_MEMBERS_1,
+  OP_ZORBA_MEMBERS_1,
   FN_JSONIQ_SIZE_1,
   FN_JSONIQ_FLATTEN_1,
   FN_JSONIQ_NULL_0,

=== modified file 'src/runtime/json/jsoniq_functions_impl.cpp'
--- src/runtime/json/jsoniq_functions_impl.cpp	2013-06-05 00:37:35 +0000
+++ src/runtime/json/jsoniq_functions_impl.cpp	2013-06-08 05:35:32 +0000
@@ -1072,7 +1072,61 @@
 
 
 /*******************************************************************************
-  json:names($o as item()) as xs:string*
+  op-zorba:names($o as item()) as xs:string*
+********************************************************************************/
+bool SingleObjectNamesIterator::nextImpl(
+    store::Item_t& result,
+    PlanState& planState) const
+{
+  store::Item_t input;
+
+  SingleObjectNamesIteratorState* state;
+  DEFAULT_STACK_INIT(SingleObjectNamesIteratorState, state, planState);
+
+  if (consumeNext(input, theChild.getp(), planState))
+  {
+    if (input->isObject())
+    {
+      state->theNames = input->getObjectKeys();
+      state->theNames->open();
+
+      while (state->theNames->next(result))
+      {
+        STACK_PUSH (true, state);
+      }
+      state->theNames = NULL;
+    }
+  }
+
+  STACK_END(state);
+}
+
+
+bool SingleObjectNamesIterator::count(
+  store::Item_t& result,
+  PlanState& planState) const
+{
+  store::Item_t obj;
+  xs_integer count(0);
+
+  SingleObjectNamesIteratorState* state;
+  DEFAULT_STACK_INIT(SingleObjectNamesIteratorState, state, planState);
+
+  if (consumeNext(obj, theChild.getp(), planState))
+  {
+    if (obj->isObject())
+    {
+      count = obj->getNumObjectPairs();
+    }
+  }
+
+  STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, count), state);
+  STACK_END(state);
+}
+
+
+/*******************************************************************************
+  jn:names($o as item()*) as xs:string*
 ********************************************************************************/
 bool JSONObjectNamesIterator::nextImpl(
     store::Item_t& result,
@@ -1083,18 +1137,19 @@
   JSONObjectNamesIteratorState* state;
   DEFAULT_STACK_INIT(JSONObjectNamesIteratorState, state, planState);
 
-  consumeNext(input, theChild.getp(), planState);
-
-  if (input->isObject())
+  while (consumeNext(input, theChild.getp(), planState))
   {
-    state->theNames = input->getObjectKeys();
-    state->theNames->open();
-
-    while (state->theNames->next(result))
+    if (input->isObject())
     {
-      STACK_PUSH (true, state);
+      state->theNames = input->getObjectKeys();
+      state->theNames->open();
+
+      while (state->theNames->next(result))
+      {
+        STACK_PUSH (true, state);
+      }
+      state->theNames = NULL;
     }
-    state->theNames = NULL;
   }
 
   STACK_END(state);
@@ -1106,20 +1161,17 @@
   PlanState& planState) const
 {
   store::Item_t obj;
-  xs_integer count;
+  xs_integer count(0);
 
   JSONObjectNamesIteratorState* state;
   DEFAULT_STACK_INIT(JSONObjectNamesIteratorState, state, planState);
 
-  ZORBA_ASSERT(consumeNext(obj, theChild.getp(), planState));
-
-  if (obj->isObject())
-  {
-    count = obj->getNumObjectPairs();
-  }
-  else
-  {
-    count = 0;
+  while (consumeNext(obj, theChild.getp(), planState))
+  {
+    if (obj->isObject())
+    {
+      count += obj->getNumObjectPairs();
+    }
   }
 
   STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, count), state);
@@ -1278,7 +1330,62 @@
 
 
 /*******************************************************************************
-  json:members($a as item()) as item()*
+  op-zorba:members($a as item()?) as item()*
+********************************************************************************/
+bool SingleArrayMembersIterator::nextImpl(
+  store::Item_t& result,
+  PlanState& planState) const
+{
+  store::Item_t array;
+
+  JSONArrayMembersIteratorState* state;
+  DEFAULT_STACK_INIT(JSONArrayMembersIteratorState, state, planState);
+
+  if (consumeNext(array, theChild.getp(), planState))
+  {
+    if (array->isArray())
+    {
+      state->theMembers = array->getArrayValues();
+
+      state->theMembers->open();
+      while (state->theMembers->next(result))
+      {
+        STACK_PUSH(true, state);
+      }
+      state->theMembers->close();
+    }
+  }
+
+  STACK_END(state);
+}
+
+
+bool SingleArrayMembersIterator::count(
+  store::Item_t& result,
+  PlanState& planState) const
+{
+  store::Item_t array;
+  xs_integer count(0);
+
+  JSONArrayMembersIteratorState* state;
+  DEFAULT_STACK_INIT(JSONArrayMembersIteratorState, state, planState);
+
+  if (consumeNext(array, theChild.getp(), planState))
+  {
+    if (array->isArray())
+    {
+      count = array->getArraySize();
+    }
+  }
+
+  STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, count), state);
+
+  STACK_END(state);
+}
+
+
+/*******************************************************************************
+  jn:members($a as item()*) as item()*
 ********************************************************************************/
 bool JSONArrayMembersIterator::nextImpl(
   store::Item_t& result,
@@ -1289,18 +1396,19 @@
   JSONArrayMembersIteratorState* state;
   DEFAULT_STACK_INIT(JSONArrayMembersIteratorState, state, planState);
 
-  consumeNext(array, theChild.getp(), planState);
-
-  if (array->isArray())
+  while (consumeNext(array, theChild.getp(), planState))
   {
-    state->theMembers = array->getArrayValues();
-
-    state->theMembers->open();
-    while (state->theMembers->next(result))
+    if (array->isArray())
     {
-      STACK_PUSH(true, state);
+      state->theMembers = array->getArrayValues();
+
+      state->theMembers->open();
+      while (state->theMembers->next(result))
+      {
+        STACK_PUSH(true, state);
+      }
+      state->theMembers->close();
     }
-    state->theMembers->close();
   }
 
   STACK_END(state);
@@ -1312,21 +1420,20 @@
   PlanState& planState) const
 {
   store::Item_t array;
+  xs_integer count(0);
 
   JSONArrayMembersIteratorState* state;
   DEFAULT_STACK_INIT(JSONArrayMembersIteratorState, state, planState);
 
-  ZORBA_ASSERT(consumeNext(array, theChild.getp(), planState));
-
-  if (array->isArray())
-  {
-    STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, array->getArraySize()), state);
-  }
-  else
-  {
-    STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, xs_integer(0)), state);
-  }
-
+  while (consumeNext(array, theChild.getp(), planState))
+  {
+    if (array->isArray())
+    {
+      count += array->getArraySize();
+    }
+  }
+
+  STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, count), state);
   STACK_END(state);
 }
 

=== modified file 'src/runtime/json/pregenerated/jsoniq_functions.cpp'
--- src/runtime/json/pregenerated/jsoniq_functions.cpp	2013-06-05 00:37:35 +0000
+++ src/runtime/json/pregenerated/jsoniq_functions.cpp	2013-06-08 05:35:32 +0000
@@ -250,6 +250,42 @@
 // </JSONObjectNamesIterator>
 
 
+// <SingleObjectNamesIterator>
+SERIALIZABLE_CLASS_VERSIONS(SingleObjectNamesIterator)
+
+void SingleObjectNamesIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (UnaryBaseIterator<SingleObjectNamesIterator, SingleObjectNamesIteratorState>*)this);
+}
+
+
+void SingleObjectNamesIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  theChild->accept(v);
+
+  v.endVisit(*this);
+}
+
+SingleObjectNamesIterator::~SingleObjectNamesIterator() {}
+
+SingleObjectNamesIteratorState::SingleObjectNamesIteratorState() {}
+
+SingleObjectNamesIteratorState::~SingleObjectNamesIteratorState() {}
+
+
+void SingleObjectNamesIteratorState::init(PlanState& planState) {
+  PlanIteratorState::init(planState);
+}
+
+void SingleObjectNamesIteratorState::reset(PlanState& planState) {
+  PlanIteratorState::reset(planState);
+}
+// </SingleObjectNamesIterator>
+
+
 // <JSONObjectValueIterator>
 SERIALIZABLE_CLASS_VERSIONS(JSONObjectValueIterator)
 
@@ -361,6 +397,42 @@
 // </JSONArrayMembersIterator>
 
 
+// <SingleArrayMembersIterator>
+SERIALIZABLE_CLASS_VERSIONS(SingleArrayMembersIterator)
+
+void SingleArrayMembersIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (UnaryBaseIterator<SingleArrayMembersIterator, SingleArrayMembersIteratorState>*)this);
+}
+
+
+void SingleArrayMembersIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  theChild->accept(v);
+
+  v.endVisit(*this);
+}
+
+SingleArrayMembersIterator::~SingleArrayMembersIterator() {}
+
+SingleArrayMembersIteratorState::SingleArrayMembersIteratorState() {}
+
+SingleArrayMembersIteratorState::~SingleArrayMembersIteratorState() {}
+
+
+void SingleArrayMembersIteratorState::init(PlanState& planState) {
+  PlanIteratorState::init(planState);
+}
+
+void SingleArrayMembersIteratorState::reset(PlanState& planState) {
+  PlanIteratorState::reset(planState);
+}
+// </SingleArrayMembersIterator>
+
+
 // <JSONArraySizeIterator>
 SERIALIZABLE_CLASS_VERSIONS(JSONArraySizeIterator)
 

=== modified file 'src/runtime/json/pregenerated/jsoniq_functions.h'
--- src/runtime/json/pregenerated/jsoniq_functions.h	2013-06-05 00:37:35 +0000
+++ src/runtime/json/pregenerated/jsoniq_functions.h	2013-06-08 05:35:32 +0000
@@ -327,6 +327,51 @@
  * 
  * Author: 
  */
+class SingleObjectNamesIteratorState : public PlanIteratorState
+{
+public:
+  store::Iterator_t theNames; //
+
+  SingleObjectNamesIteratorState();
+
+  ~SingleObjectNamesIteratorState();
+
+  void init(PlanState&);
+  void reset(PlanState&);
+};
+
+class SingleObjectNamesIterator : public UnaryBaseIterator<SingleObjectNamesIterator, SingleObjectNamesIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(SingleObjectNamesIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(SingleObjectNamesIterator,
+    UnaryBaseIterator<SingleObjectNamesIterator, SingleObjectNamesIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  SingleObjectNamesIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& child)
+    : 
+    UnaryBaseIterator<SingleObjectNamesIterator, SingleObjectNamesIteratorState>(sctx, loc, child)
+  {}
+
+  virtual ~SingleObjectNamesIterator();
+
+public:
+  bool count(store::Item_t& result, PlanState& planState) const;
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ * 
+ * Author: 
+ */
 class JSONObjectValueIterator : public BinaryBaseIterator<JSONObjectValueIterator, PlanIteratorState>
 { 
 public:
@@ -462,6 +507,51 @@
  * 
  * Author: 
  */
+class SingleArrayMembersIteratorState : public PlanIteratorState
+{
+public:
+  store::Iterator_t theMembers; //
+
+  SingleArrayMembersIteratorState();
+
+  ~SingleArrayMembersIteratorState();
+
+  void init(PlanState&);
+  void reset(PlanState&);
+};
+
+class SingleArrayMembersIterator : public UnaryBaseIterator<SingleArrayMembersIterator, SingleArrayMembersIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(SingleArrayMembersIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(SingleArrayMembersIterator,
+    UnaryBaseIterator<SingleArrayMembersIterator, SingleArrayMembersIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  SingleArrayMembersIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    PlanIter_t& child)
+    : 
+    UnaryBaseIterator<SingleArrayMembersIterator, SingleArrayMembersIteratorState>(sctx, loc, child)
+  {}
+
+  virtual ~SingleArrayMembersIterator();
+
+public:
+  bool count(store::Item_t& result, PlanState& planState) const;
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ * 
+ * Author: 
+ */
 class JSONArraySizeIterator : public UnaryBaseIterator<JSONArraySizeIterator, PlanIteratorState>
 { 
 public:

=== modified file 'src/runtime/pregenerated/iterator_enum.h'
--- src/runtime/pregenerated/iterator_enum.h	2013-06-05 07:26:13 +0000
+++ src/runtime/pregenerated/iterator_enum.h	2013-06-08 05:35:32 +0000
@@ -170,10 +170,12 @@
   TYPE_JSONDocIterator,
   TYPE_JSONItemAccessorIterator,
   TYPE_JSONObjectNamesIterator,
+  TYPE_SingleObjectNamesIterator,
   TYPE_JSONObjectValueIterator,
   TYPE_JSONObjectProjectIterator,
   TYPE_JSONArrayMemberIterator,
   TYPE_JSONArrayMembersIterator,
+  TYPE_SingleArrayMembersIterator,
   TYPE_JSONArraySizeIterator,
   TYPE_JSONArrayFlattenIterator,
   TYPE_JSONNullIterator,

=== modified file 'src/runtime/spec/json/jsoniq_functions.xml'
--- src/runtime/spec/json/jsoniq_functions.xml	2013-06-05 00:37:35 +0000
+++ src/runtime/spec/json/jsoniq_functions.xml	2013-06-08 05:35:32 +0000
@@ -269,10 +269,44 @@
 -->
 <zorba:iterator name="JSONObjectNamesIterator" arity="unary">
 
-  <zorba:function isDeterministic="true">
+  <zorba:function isDeterministic="true"
+                  generateCodegen="false">
 
     <zorba:signature localname="keys" prefix="fn-jsoniq">
-      <zorba:param>item()</zorba:param>
+      <zorba:param>item()*</zorba:param>
+      <zorba:output>xs:string*</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:propagatesInputNodes value="false"/>
+      <zorba:mustCopyInputNodes value="false"/>
+      <zorba:isMap producer="0"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+  <zorba:state>
+    <zorba:member type="store::Iterator_t" name="theNames" brief=""/>
+  </zorba:state>
+
+  <zorba:method name="count" const="true" return="bool">
+     <zorba:param name="result" type="store::Item_t&amp;"/>
+     <zorba:param name="planState" type="PlanState&amp;"/>
+  </zorba:method>
+
+</zorba:iterator>
+
+
+<!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="SingleObjectNamesIterator" arity="unary">
+
+  <zorba:function isDeterministic="true">
+
+    <zorba:signature localname="keys" prefix="op-zorba">
+      <zorba:param>item()?</zorba:param>
       <zorba:output>xs:string*</zorba:output>
     </zorba:signature>
 
@@ -373,10 +407,44 @@
 -->
 <zorba:iterator name="JSONArrayMembersIterator" arity="unary">
 
-  <zorba:function isDeterministic="true">
+  <zorba:function isDeterministic="true"
+                  generateCodegen="false">
 
     <zorba:signature localname="members" prefix="fn-jsoniq">
-      <zorba:param>item()</zorba:param>
+      <zorba:param>item()*</zorba:param>
+      <zorba:output>item()*</zorba:output>
+    </zorba:signature>
+
+    <zorba:methods>
+      <zorba:propagatesInputNodes producer="0"/>
+      <zorba:mustCopyInputNodes value="false"/>
+      <zorba:isMap producer="0"/>
+    </zorba:methods>
+
+  </zorba:function>
+
+  <zorba:state>
+    <zorba:member type="store::Iterator_t" name="theMembers" brief=""/>
+  </zorba:state>
+
+  <zorba:method name="count" const="true" return="bool">
+     <zorba:param name="result" type="store::Item_t&amp;"/>
+     <zorba:param name="planState" type="PlanState&amp;"/>
+  </zorba:method>
+
+</zorba:iterator>
+
+
+<!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="SingleArrayMembersIterator" arity="unary">
+
+  <zorba:function isDeterministic="true">
+
+    <zorba:signature localname="members" prefix="op-zorba">
+      <zorba:param>item()?</zorba:param>
       <zorba:output>item()*</zorba:output>
     </zorba:signature>
 

=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
--- src/runtime/visitors/pregenerated/planiter_visitor.h	2013-06-05 07:26:13 +0000
+++ src/runtime/visitors/pregenerated/planiter_visitor.h	2013-06-08 05:35:32 +0000
@@ -346,6 +346,8 @@
 
     class JSONObjectNamesIterator;
 
+    class SingleObjectNamesIterator;
+
     class JSONObjectValueIterator;
 
     class JSONObjectProjectIterator;
@@ -354,6 +356,8 @@
 
     class JSONArrayMembersIterator;
 
+    class SingleArrayMembersIterator;
+
     class JSONArraySizeIterator;
 
     class JSONArrayFlattenIterator;
@@ -1227,6 +1231,9 @@
     virtual void beginVisit ( const JSONObjectNamesIterator& ) = 0;
     virtual void endVisit   ( const JSONObjectNamesIterator& ) = 0;
 
+    virtual void beginVisit ( const SingleObjectNamesIterator& ) = 0;
+    virtual void endVisit   ( const SingleObjectNamesIterator& ) = 0;
+
     virtual void beginVisit ( const JSONObjectValueIterator& ) = 0;
     virtual void endVisit   ( const JSONObjectValueIterator& ) = 0;
 
@@ -1239,6 +1246,9 @@
     virtual void beginVisit ( const JSONArrayMembersIterator& ) = 0;
     virtual void endVisit   ( const JSONArrayMembersIterator& ) = 0;
 
+    virtual void beginVisit ( const SingleArrayMembersIterator& ) = 0;
+    virtual void endVisit   ( const SingleArrayMembersIterator& ) = 0;
+
     virtual void beginVisit ( const JSONArraySizeIterator& ) = 0;
     virtual void endVisit   ( const JSONArraySizeIterator& ) = 0;
 

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
--- src/runtime/visitors/pregenerated/printer_visitor.cpp	2013-06-05 07:26:13 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.cpp	2013-06-08 05:35:32 +0000
@@ -2097,6 +2097,20 @@
 // </JSONObjectNamesIterator>
 
 
+// <SingleObjectNamesIterator>
+void PrinterVisitor::beginVisit ( const SingleObjectNamesIterator& a) {
+  thePrinter.startBeginVisit("SingleObjectNamesIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const SingleObjectNamesIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </SingleObjectNamesIterator>
+
+
 // <JSONObjectValueIterator>
 void PrinterVisitor::beginVisit ( const JSONObjectValueIterator& a) {
   thePrinter.startBeginVisit("JSONObjectValueIterator", ++theId);
@@ -2153,6 +2167,20 @@
 // </JSONArrayMembersIterator>
 
 
+// <SingleArrayMembersIterator>
+void PrinterVisitor::beginVisit ( const SingleArrayMembersIterator& a) {
+  thePrinter.startBeginVisit("SingleArrayMembersIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const SingleArrayMembersIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </SingleArrayMembersIterator>
+
+
 // <JSONArraySizeIterator>
 void PrinterVisitor::beginVisit ( const JSONArraySizeIterator& a) {
   thePrinter.startBeginVisit("JSONArraySizeIterator", ++theId);

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
--- src/runtime/visitors/pregenerated/printer_visitor.h	2013-06-05 07:26:13 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.h	2013-06-08 05:35:32 +0000
@@ -529,6 +529,9 @@
     void beginVisit( const JSONObjectNamesIterator& );
     void endVisit  ( const JSONObjectNamesIterator& );
 
+    void beginVisit( const SingleObjectNamesIterator& );
+    void endVisit  ( const SingleObjectNamesIterator& );
+
     void beginVisit( const JSONObjectValueIterator& );
     void endVisit  ( const JSONObjectValueIterator& );
 
@@ -541,6 +544,9 @@
     void beginVisit( const JSONArrayMembersIterator& );
     void endVisit  ( const JSONArrayMembersIterator& );
 
+    void beginVisit( const SingleArrayMembersIterator& );
+    void endVisit  ( const SingleArrayMembersIterator& );
+
     void beginVisit( const JSONArraySizeIterator& );
     void endVisit  ( const JSONArraySizeIterator& );
 

=== modified file 'test/rbkt/ExpQueryResults/zorba/jsoniq/members_02.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/members_02.xml.res	2013-03-15 19:28:34 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/members_02.xml.res	2013-06-08 05:35:32 +0000
@@ -1,1 +1,1 @@
-true
+true true

=== modified file 'test/rbkt/Queries/zorba/jsoniq/members_02.xq'
--- test/rbkt/Queries/zorba/jsoniq/members_02.xq	2013-03-15 19:28:34 +0000
+++ test/rbkt/Queries/zorba/jsoniq/members_02.xq	2013-06-08 05:35:32 +0000
@@ -1,1 +1,4 @@
 empty([]())
+,
+empty(jn:members(()))
+


Follow ups