← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~markos-za/zorba/indexes into lp:zorba

 

Markos Zaharioudakis has proposed merging lp:~markos-za/zorba/indexes into lp:zorba.

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~markos-za/zorba/indexes/+merge/78060
-- 
https://code.launchpad.net/~markos-za/zorba/indexes/+merge/78060
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'doc/zorba/xqddf.dox'
--- doc/zorba/xqddf.dox	2011-09-30 03:06:48 +0000
+++ doc/zorba/xqddf.dox	2011-10-04 08:30:40 +0000
@@ -1792,8 +1792,7 @@
 
 
 Probing an index means retrieving the domain nodes associated with a particular
-search condition, which is either a single key item/tuple, or a "range" of key
-items/tuples. Probing can be done via the xqddf functions 
+search condition Probing can be done via the xqddf functions 
 idml:probe-index-point-value, idml:probe-index-point-general, 
 idml:probe-index-range-value, or idml:probe-index-range-general.
 For each of these functions, the first argument is a QName identifying an index.
@@ -1802,9 +1801,9 @@
 of the invoking module; otherwise error <a href="#ERRZDDY0021">zerr:ZDDY0021</a>
 or <a href="#ERRZDDY0023">zerr:ZDDY0023</a> is raised, 
 respectively. All of the functions return their result sorted in document order 
-and without duplicate nodes. (For general probes, duplicate node elimination 
-is performed as part of the function implementation; for value probes, duplicate
-nodes cannot appear in the result, so no duplicate elimination is needed.)
+and without duplicate nodes.
+
+<strong>idml:probe-index-point-value</strong>
 
 <a name="probe_index_point_value" id="probe_index_point_value"></a>
 \code
@@ -1815,33 +1814,36 @@
 \endcode
 
 For the probe-index-point-value function, the search condition is specified as a
-number of <strong>search key items</strong> comprising a <strong>search key 
-tuple</strong>. A search key item is either an atomic item or the empty sequence.
-The number of search key items must be equal to the number of IndexKeySpecs found 
+number of <strong>search keys</strong> comprising a <strong>search 
+tuple</strong>. A search key is either an atomic item or the empty sequence.
+The number of search keys must be equal to the number of IndexKeySpecs found 
 in the index declaration [<a href="#ERRZDDY0025"> zerr:ZDDY0025</a>]. (Remember 
 that for general indexes, there can be only one IndexKeySpec, and as a result, 
 for general indexes, the probe-index-point-value function takes only one search 
-key item as input). Furthermore, the type of each search key item must match 
-the sequence type specified in the corresponding IndexKeyTypeDecl; otherwise, 
-a type error is raised [err:XPTY0004].
+value as input). Furthermore, for each search key that is not the empty sequence, 
+its type must match the sequence type specified in the corresponding IndexKeyTypeDecl;
+otherwise, a type error is raised [err:XPTY0004].
 
-The result of this function is either an error or the set of domain nodes that 
-satisfy the following xquery condition:
+The result of this function is either an error or the set of domain nodes for which 
+the following xquery condition returns true:
 
 \code
 $key1 eq $node/keyExpr1 and ... and $keyM eq $node/keyExprM
 \endcode
 
 where keyExpr<sub>i</sub> is the expression specified in the i-th keyspec 
-of the index.
+of the index. Notice that this definition implies that if any of search keys
+is the empty sequence, the result of the probe is also the empty sequence.
 
-In addition to the error conditions described already, the function may raise
+In addition to the error conditions described already, the function raises
 a type error [err:XPTY0004] if the index is general and (a) the multi-key flag
 of the index is true, or (b) the untyped flag of the index is true and the type of
-the search key item is something other than xs:untypedAtomic, xs:string, or 
+any non-empty search key is something other than xs:untypedAtomic, xs:string, or 
 xs:anyURI (or subtype of these).
 
 
+<strong>idml:probe-index-point-general</strong>
+
 <a name="probe_index_point_general" id="probe_index_point_general"></a>
 \code
   idml:probe-index-point-general($indexUri as xs:QName,
@@ -1849,13 +1851,14 @@
 \endcode
 
 This method is supported by general indexes only [<a href="#ERRZDDY0029">
-zerr:ZDDY0029</a>]. The search condition is specified as a sequence of
-atomic search key items. If the search sequence is non-empty, the type of each 
-atomic item in it must match the atomic type specified by the IndexKeyTypeDecl
-of the index; otherwise, a type error is raised [err:XPTY0004]. 
+zerr:ZDDY0029</a>]. The search condition is specified as a <strong>search 
+sequence</strong> consisting of an arbitrary number of <strong>search keys
+</strong>, where each search key is an atomic item. If the search sequence 
+is non-empty, the type of each search key must match the atomic type specified 
+by the IndexKeyTypeDecl of the index; otherwise, a type error is raised [err:XPTY0004]. 
 
-The result of this function is either an error or the set of domain nodes that 
-satisfy the following xquery condition:
+The result of this function is either an error or the set of domain nodes for which 
+the following xquery condition returns true:
 
 \code
 $keys = $node/keyExpr
@@ -1864,79 +1867,78 @@
 where keyExpr is the expression specified in the keyspec of the index.
 
 
+<strong>idml:probe-index-range-value</strong>
+
 <a name="probe_index_range_value" id="probe_index_range_value"></a>
 \code
-  probe-index-range-value($indexUri                 as xs:QName,
-                          $rangeLowerBound1         as xs:anyAtomicType?,
-                          $rangeUpperBound1         as xs:anyAtomicType?,
-                          $rangeHaveLowerBound1     as xs:boolean,
-                          $rangeHaveupperBound1     as xs:boolean,
-                          $rangeLowerBoundIncluded1 as xs:boolean,
-                          $rangeupperBoundIncluded1 as xs:boolean,
+  probe-index-range-value($indexUri            as xs:QName,
+                          $lowerBound1         as xs:anyAtomicType?,
+                          $upperBound1         as xs:anyAtomicType?,
+                          $haveLowerBound1     as xs:boolean,
+                          $haveUpperBound1     as xs:boolean,
+                          $lowerBoundIncluded1 as xs:boolean,
+                          $upperBoundIncluded1 as xs:boolean,
                           ....,
-                          $rangeLowerBoundM         as xs:anyAtomicType?,
-                          $rangeUpperBoundM         as xs:anyAtomicType?,
-                          $rangeHaveLowerBoundM     as xs:boolean,
-                          $rangeHaveupperBoundM     as xs:boolean,
-                          $rangeLowerBoundIncludedM as xs:boolean,
-                          $rangeupperBoundIncludedM as xs:boolean) as node()*
+                          $lowerBoundM         as xs:anyAtomicType?,
+                          $upperBoundM         as xs:anyAtomicType?,
+                          $haveLowerBoundM     as xs:boolean,
+                          $haveUpperBoundM     as xs:boolean,
+                          $lowerBoundIncludedM as xs:boolean,
+                          $upperBoundIncludedM as xs:boolean) as node()*
 \endcode
 
 The probe-index-range-value function can be invoked on range indices only 
-(value or general) [<a href="#ERRZDDY0026">zerr:ZDDY0026</a>]. To describe the
-semantics of this function, we start by defining the i<sup>th</sup> <strong>key
-column</strong> of an index as the set of key items produced by evaluating the
-i<sup>th</sup> keyspec of the index for every domain node. Then, the search
-condition of a range probe can be defined as a number of
-<strong>rangespecs</strong>, where a rangespec describes a constraint on the
-values of a key column. The first rangespec applies to the first key column, the
-second rangespec to the second key column, etc. The number of rangespecs must be
-less or equal to the number of keyspecs found in the declaration of the given
-index [<a href="#ERRZDDY0025" title="zerr:ZDDY0025">zerr:ZDDY0025</a>]. Each
-rangespec consists of 6 values:
-  <ul>
-  <li>rangeLowerBound : The lower bound in a range of key values.</li>
-  <li>rangeUpperBound : The upper bound in a range of key values.</li>
-  <li>rangeHaveLowerBound : If false, then there is no lower bound, or
-equivalently, the lower bound is -INFINITY (the actual rangeLowerBound value is
-ignored). Otherwise, the lower bound is the one given by the rangeLowerBound
-value. The <strong>effective lower bound</strong> of the range is either the
-rangeLowerBound if rangeHaveLowerBound is true, or -INFINITY if
-rangeHaveLowerBound is false.</li>
-  <li>rangeHaveUpperBound : If false, then there is no upper bound, or
-equivalently, the upper bound is +INFINITY (the actual rangeUpperBound value is
-ignored). Otherwise, the upper bound is the one given by the rangeUpperBound
-value. The <strong>effective upper bound</strong> of the range is either the
-rangeUpperBound if rangeHaveUpperBound is true, or +INFINITY if
-rangeHaveUpperBound is false.</li>
-  <li>rangeLowerBoundIncluded : If false, then the range is open from below,
-i.e., the rangeLowerBound value is not considered part of the range. Otherwise,
-the range is closed from below, i.e., the rangeLowerBound value is part of the
-range.</li>
-  <li>rangeUpperBoundIncluded : If false, then the range is open from above,
-i.e., the rangeUpperBound value is not considered part of the range. Otherwise,
-the range is closed from above, i.e., the rangeUpperBound value is part of the
-range.</li>
-  </ul>
-
-If the number of rangespecs is less than the number of key columns, then the
-missing rangespecs are assumed to have the following value: [(), (), false,
-false, false, false].
-
-A key tuple K = [k<sub>1</sub>, ..., k<sub>M</sub>] satisfies a range search
-condition if for each i = 1, 2, ..., M the following is true:
-
-effectiveLowerBound<sub>i</sub>  lOp  k<sub>i</sub>  uOp 
-effectiveUpperBound<sub>i</sub>
-
-where lOp (uOp) is either the le operator if rangeLowerBoundIncluded<sub>i</sub>
-(rangeUpperBoundIncluded<sub>i</sub>) is true, or the lt operator if
-rangeLowerBoundIncluded<sub>i</sub> (rangeUpperBoundIncluded<sub>i</sub>) is
-false. The index-probe-range function finds all key tuples in the index that
-satisfy the given search condition, creates the union of the domain nodes
-associated with each such key tuple, puts the resulting sequence of nodes in
-document order, and finally returns this sequence to its caller.
-
+(value or general) [<a href="#ERRZDDY0026">zerr:ZDDY0026</a>]. The search 
+condition is specified as a number M of <strong>rangespecs</strong>, where
+each rangespec consists of six values. The number M must be greater than 
+0 and less than or equal to the number N of keyspecs found in the declaration 
+of the given index [<a href="#ERRZDDY0025">zerr:ZDDY0025</a>]. If M is less 
+than N, then the "missing" rangespecs are assumed to have the following 
+value: [(), (), false, false, false, false]. As a result, from now on, we
+can assume that M is equal to N (Remember that for general indexes, there 
+can be only one IndexKeySpec, and as a result, for general indexes, M = N = 1).
+
+The i<sup>th</sup> rangespec corresponds to the i<sup>th</sup> keyspec, and 
+specifies a condition on the key values that are produced by evaluating that
+keyspec for every domain node. Specifically, we define the i<sup>th</sup>
+<strong>rangespec result</strong> as the set of domain nodes for which the 
+following xquery condition returns true:
+
+\code
+if ($haveLowerBound-i and $haveUpperBound-i) then
+  $lowerBound-i lop $node/keyExpr-i and $node/keyExpr-i uop $upperBound-i
+else if ($haveLowerBound-i) then
+  $lowerBound-i lop $node/keyExpr-i
+else if ($haveUpperBound-i) then
+  $node/keyExpr-i uop $upperBound-i
+else
+  fn:true()
+\endcode
+
+where keyExpr-i is the expression specified by the i<sup>th</sup> keyspec 
+of the index, lop is either the le or the lt operator depending on whether 
+$lowerBoundsIncluded-i is true or false, and uop is either the le or the 
+lt operator depending on whether $upperBoundsIncluded-i is true or false.
+
+In computing the i<sup>th</sup> rangespec result, a type error [err:XPTY0004]
+is raised in the following cases: (a) $haveLowerBound-i is true and
+$lowerBound-i is an atomic item whose type does not match the atomic
+type specified by i<sup>th</sup> keyspec, or (b) $haveUpperBound-i is 
+true and $upperBound-i is an atomic item whose type does not match 
+the atomic type specified by i<sup>th</sup> keyspec, or (c) the index is general
+and its multi-key flag is true, or (d) the index is general, its untyped flag
+is true, $haveLowerBound-i is true, and $lowerBound-i is
+an atomic item whose type is something other than xs:untypedAtomic, xs:string, 
+or xs:anyURI (or subtype of these), or (e) the index is general, its untyped flag
+is true, $haveUpperBound-i is true, and $upperBound-i is
+an atomic item whose type is something other than xs:untypedAtomic, xs:string, 
+or xs:anyURI (or subtype of these).
+
+The result of the probe-index-range-value is either one of the errors described
+above, or the intersection of all the rangespec results.
+
+
+<strong>idml:probe-index-range-general</strong>
 
 <a name="probe_index_range_general" id="probe_index_range_general"></a>
 \code

=== modified file 'include/zorba/pregenerated/diagnostic_list.h'
--- include/zorba/pregenerated/diagnostic_list.h	2011-10-03 19:38:22 +0000
+++ include/zorba/pregenerated/diagnostic_list.h	2011-10-04 08:30:40 +0000
@@ -592,6 +592,8 @@
 
 extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDDY0030_INDEX_RANGE_GENERAL_PROBE_NOT_ALLOWED;
 
+extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDDY0034_INDEX_RANGE_VALUE_PROBE_BAD_KEY_TYPES;
+
 extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDDY0031_IC_NOT_DECLARED;
 
 extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZDDY0032_IC_NOT_ACTIVATED;

=== modified file 'modules/com/zorba-xquery/www/modules/pregenerated/errors.xq'
--- modules/com/zorba-xquery/www/modules/pregenerated/errors.xq	2011-08-17 23:04:48 +0000
+++ modules/com/zorba-xquery/www/modules/pregenerated/errors.xq	2011-10-04 08:30:40 +0000
@@ -485,6 +485,10 @@
 
 (:~
 :)
+declare variable $zerr:ZDDY0034 as xs:QName := fn:QName($zerr:NS, "zerr:ZDDY0034");
+
+(:~
+:)
 declare variable $zerr:ZDDY0031 as xs:QName := fn:QName($zerr:NS, "zerr:ZDDY0031");
 
 (:~

=== modified file 'src/diagnostics/diagnostic_en.xml'
--- src/diagnostics/diagnostic_en.xml	2011-10-03 19:38:22 +0000
+++ src/diagnostics/diagnostic_en.xml	2011-10-04 08:30:40 +0000
@@ -1981,6 +1981,10 @@
       <value>"$1": index range-general probe not allowed</value>
     </diagnostic>
 
+    <diagnostic code="ZDDY0034" name="INDEX_RANGE_VALUE_PROBE_BAD_KEY_TYPES">
+      <value>"$1": index range-value probe has search keys with incompatible types</value>
+    </diagnostic>
+
     <diagnostic code="ZDDY0031" name="IC_NOT_DECLARED">
       <value>"$1": integrity constraint is not declared</value>
     </diagnostic>

=== modified file 'src/diagnostics/pregenerated/diagnostic_list.cpp'
--- src/diagnostics/pregenerated/diagnostic_list.cpp	2011-10-03 19:38:22 +0000
+++ src/diagnostics/pregenerated/diagnostic_list.cpp	2011-10-04 08:30:40 +0000
@@ -867,6 +867,9 @@
 ZorbaErrorCode ZDDY0030_INDEX_RANGE_GENERAL_PROBE_NOT_ALLOWED( "ZDDY0030" );
 
 
+ZorbaErrorCode ZDDY0034_INDEX_RANGE_VALUE_PROBE_BAD_KEY_TYPES( "ZDDY0034" );
+
+
 ZorbaErrorCode ZDDY0031_IC_NOT_DECLARED( "ZDDY0031" );
 
 

=== modified file 'src/diagnostics/pregenerated/dict_en.cpp'
--- src/diagnostics/pregenerated/dict_en.cpp	2011-10-03 19:38:22 +0000
+++ src/diagnostics/pregenerated/dict_en.cpp	2011-10-04 08:30:40 +0000
@@ -293,6 +293,7 @@
   { "ZDDY0031", "\"$1\": integrity constraint is not declared" },
   { "ZDDY0032", "\"$1\": integrity constraint is not activated" },
   { "ZDDY0033", "\"$1\": integrity constraint not met for collection \"$2\"" },
+  { "ZDDY0034", "\"$1\": index range-value probe has search keys with incompatible types" },
   { "ZDST0001", "\"$1\": collection already declared" },
   { "ZDST0002", "\"$1\": collection already imported into module \"$2\"" },
   { "ZDST0003", "\"$1\": collection declaration not allowed in main module" },

=== modified file 'src/runtime/indexing/index_ddl.cpp'
--- src/runtime/indexing/index_ddl.cpp	2011-10-03 08:49:55 +0000
+++ src/runtime/indexing/index_ddl.cpp	2011-10-04 08:30:40 +0000
@@ -46,6 +46,40 @@
 namespace zorba {
 
 
+SERIALIZABLE_CLASS_VERSIONS(CreateInternalIndexIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(CreateInternalIndexIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(CreateIndexIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(CreateIndexIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(DeleteIndexIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(DeleteIndexIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(RefreshIndexIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(RefreshIndexIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(ValueIndexEntryBuilderIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(ValueIndexEntryBuilderIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(GeneralIndexEntryBuilderIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(GeneralIndexEntryBuilderIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(ProbeIndexPointValueIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(ProbeIndexPointValueIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(ProbeIndexPointGeneralIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(ProbeIndexPointGeneralIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(ProbeIndexRangeValueIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(ProbeIndexRangeValueIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(ProbeIndexRangeGeneralIterator)
+END_SERIALIZABLE_CLASS_VERSIONS(ProbeIndexRangeGeneralIterator)
+
+
+/*******************************************************************************
+
+********************************************************************************/
 static void checkKeyType(
     const QueryLoc& loc,
     TypeManager* tm,
@@ -92,41 +126,10 @@
 }
 
 
-SERIALIZABLE_CLASS_VERSIONS(CreateInternalIndexIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(CreateInternalIndexIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(CreateIndexIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(CreateIndexIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(DeleteIndexIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(DeleteIndexIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(RefreshIndexIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(RefreshIndexIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(ValueIndexEntryBuilderIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(ValueIndexEntryBuilderIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(GeneralIndexEntryBuilderIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(GeneralIndexEntryBuilderIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(ProbeIndexPointValueIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(ProbeIndexPointValueIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(ProbeIndexPointGeneralIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(ProbeIndexPointGeneralIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(ProbeIndexRangeValueIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(ProbeIndexRangeValueIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(ProbeIndexRangeGeneralIterator)
-END_SERIALIZABLE_CLASS_VERSIONS(ProbeIndexRangeGeneralIterator)
-
-
 /*******************************************************************************
 
 ********************************************************************************/
-void createIndexSpec(
+static void createIndexSpec(
     IndexDecl* indexDecl,
     store::IndexSpecification& spec)
 {
@@ -624,20 +627,14 @@
 
       if ((state->theIndexDecl = theSctx->lookup_index(qnameItem)) == NULL)
       {
-        throw XQUERY_EXCEPTION(
-          zerr::ZDDY0021_INDEX_NOT_DECLARED,
-          ERROR_PARAMS( qnameItem->getStringValue() ),
-          ERROR_LOC( loc )
-        );
+        RAISE_ERROR(zerr::ZDDY0021_INDEX_NOT_DECLARED, loc,
+        ERROR_PARAMS(qnameItem->getStringValue()));
       }
 
       if (state->theIndexDecl->getKeyExpressions().size() != numChildren-1)
       {
-        throw XQUERY_EXCEPTION(
-          zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS,
-          ERROR_PARAMS( qnameItem->getStringValue() ),
-          ERROR_LOC( loc )
-        );
+        RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
+        ERROR_PARAMS(qnameItem->getStringValue()));
       }
 
       state->theIndex = (state->theIndexDecl->isTemp() ?
@@ -646,11 +643,8 @@
       
       if (state->theIndex == NULL)
       {
-        throw XQUERY_EXCEPTION(
-          zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
-          ERROR_PARAMS( qnameItem->getStringValue() ),
-          ERROR_LOC( loc )
-        );
+        RAISE_ERROR(zerr::ZDDY0023_INDEX_DOES_NOT_EXIST, loc,
+        ERROR_PARAMS(qnameItem->getStringValue()));
       }
       
       state->theIterator = GENV_STORE.getIteratorFactory()->
@@ -951,6 +945,8 @@
   store::IndexCondition_t cond;
   ulong numChildren = (ulong)theChildren.size();
   bool status;
+  TypeManager* tm = theSctx->get_typemanager();
+  RootTypeManager& rtm = GENV_TYPESYSTEM;
  
   ProbeIndexRangeValueIteratorState* state;
   DEFAULT_STACK_INIT(ProbeIndexRangeValueIteratorState, state, planState);
@@ -1046,6 +1042,47 @@
       checkKeyType(loc, theSctx->get_typemanager(), indexDecl, keyNo, tempRight);
     }
 
+    if (indexDecl->isGeneral() &&
+        (indexDecl->getKeyTypes())[keyNo] == NULL)
+    {
+      xqtref_t leftType;
+      xqtref_t rightType;
+
+      if (tempLeft != NULL)
+      {
+        leftType = tm->create_value_type(tempLeft);
+        
+        if (TypeOps::is_equal(tm, *leftType, *rtm.UNTYPED_ATOMIC_TYPE_ONE))
+        {
+          zstring str = tempLeft->getStringValue();
+          GENV_ITEMFACTORY->createString(tempLeft, str);
+          leftType = rtm.STRING_TYPE_ONE;
+        }
+      }
+
+      if (tempRight != NULL)
+      {
+        rightType = tm->create_value_type(tempRight);
+        
+        if (TypeOps::is_equal(tm, *rightType, *rtm.UNTYPED_ATOMIC_TYPE_ONE))
+        {
+          zstring str = tempRight->getStringValue();
+          GENV_ITEMFACTORY->createString(tempRight, str);
+          rightType = rtm.STRING_TYPE_ONE;
+        }
+      }
+
+      if (leftType != NULL && rightType != NULL)
+      {
+        if (!TypeOps::is_subtype(tm, *leftType, *rightType) &&
+            !TypeOps::is_subtype(tm, *rightType, *leftType))
+        {
+          RAISE_ERROR(zerr::ZDDY0034_INDEX_RANGE_VALUE_PROBE_BAD_KEY_TYPES, loc,
+          ERROR_PARAMS(qname->getStringValue()));
+        }
+      }
+    }
+
     cond->pushRange(tempLeft, tempRight, haveLeft, haveRight, inclLeft, inclRight);
   }
 
@@ -1255,6 +1292,7 @@
     //
     // Build hashmap from the nodes satisfying the lower bound condition
     //
+
     if (!getSearchItems(planState, state, true, false, inclLower, false))
       goto done;
 
@@ -1291,6 +1329,7 @@
     // Compute the nodes satisfying the upper bound condition and probe the
     // node hashmap.
     //
+
     if (!getSearchItems(planState, state, false, true, false, inclUpper))
       goto done;
 

=== modified file 'src/store/api/index.h'
--- src/store/api/index.h	2011-07-06 19:19:49 +0000
+++ src/store/api/index.h	2011-10-04 08:30:40 +0000
@@ -177,8 +177,9 @@
 
   bound op? K, where 
 
-  (a) op? is one of <, <=, >, or >=, (b) K is a key value, and (c) bound is either
-  an atomic item or -INFINITY or +INFINITY.
+  (a) op? is one of <, <=, >, or >=, 
+  (b) K is a key value, and 
+  (c) bound is either an atomic item or -INFINITY or +INFINITY.
 
 ********************************************************************************/
 class IndexCondition : public SimpleRCObject

=== modified file 'src/store/api/item.h'
--- src/store/api/item.h	2011-08-23 23:18:43 +0000
+++ src/store/api/item.h	2011-10-04 08:30:40 +0000
@@ -241,7 +241,7 @@
   /**
    * @return If this is an atomic item with a user-defined data type UT, return
    *         the underlying atomic item that stores the actual value and whose
-   *         data type is a builtin atomic supertype of UT.
+   *         data type is a builtin atomic supertype of UT. Otherwise, return NULL.
    */
   virtual store::Item* getBaseItem() const;
 

=== modified file 'src/store/naive/atomic_items.cpp'
--- src/store/naive/atomic_items.cpp	2011-08-26 04:19:57 +0000
+++ src/store/naive/atomic_items.cpp	2011-10-04 08:30:40 +0000
@@ -88,17 +88,21 @@
 
   result = NULL;
 
-  switch (getTypeCode())
+  const AtomicItem* item1 = static_cast<AtomicItem*>(getBaseItem());
+  if (item1 == NULL)
+    item1 = this;
+
+  switch (item1->getTypeCode())
   {
   case XS_UNTYPED_ATOMIC:
   {
-    const UntypedAtomicItem* item = static_cast<const UntypedAtomicItem*>(this);
+    const UntypedAtomicItem* item = static_cast<const UntypedAtomicItem*>(item1);
     try
     {
       longValue = ztd::aton<xs_long>(item->theValue.c_str());
       GET_FACTORY().createLong(result, longValue);
     }
-    catch ( std::exception const& )
+    catch (std::exception const&)
     {
       // ignore
     }
@@ -108,7 +112,7 @@
   case XS_DOUBLE:
   case XS_FLOAT:
   {
-    double doubleValue = getDoubleValue().getNumber();
+    double doubleValue = item1->getDoubleValue().getNumber();
     longValue = static_cast<xs_long>(doubleValue);
 
     if (doubleValue == static_cast<double>(longValue))
@@ -119,13 +123,13 @@
 
   case XS_DECIMAL:
   {
-    const DecimalItem* item = static_cast<const DecimalItem*>(this);
+    const DecimalItem* item = static_cast<const DecimalItem*>(item1);
     try
     {
       longValue = to_xs_long(item->theValue);
       GET_FACTORY().createLong(result, longValue);
     }
-    catch ( std::range_error const& )
+    catch (std::range_error const&)
     {
       // ignore
     }
@@ -138,13 +142,13 @@
   case XS_NON_NEGATIVE_INTEGER:
   case XS_POSITIVE_INTEGER:
   {
-    const IntegerItem* item = static_cast<const IntegerItem*>(this);
+    const IntegerItem* item = static_cast<const IntegerItem*>(item1);
     try
     {
-      longValue = to_xs_long( item->theValue );
+      longValue = to_xs_long(item->theValue);
       GET_FACTORY().createLong(result, longValue);
     }
-    catch ( std::range_error const& )
+    catch (std::range_error const&)
     {
       // ignore
     }
@@ -153,7 +157,7 @@
 
   case XS_UNSIGNED_LONG:
   {
-    const UnsignedLongItem* item = static_cast<const UnsignedLongItem*>(this);
+    const UnsignedLongItem* item = static_cast<const UnsignedLongItem*>(item1);
     if ((item->theValue >> 63) == 0)
     {
       longValue = static_cast<xs_long>(item->theValue);
@@ -185,11 +189,15 @@
 
   result = NULL;
 
-  switch (getTypeCode())
+  const AtomicItem* item1 = static_cast<AtomicItem*>(getBaseItem());
+  if (item1 == NULL)
+    item1 = this;
+
+  switch (item1->getTypeCode())
   {
   case XS_DECIMAL:
   {
-    const DecimalItem* item = static_cast<const DecimalItem*>(this);
+    const DecimalItem* item = static_cast<const DecimalItem*>(item1);
 
     doubleValue = item->theValue;
 
@@ -205,7 +213,7 @@
   case XS_NON_NEGATIVE_INTEGER:
   case XS_POSITIVE_INTEGER:
   {
-    const IntegerItem* item = static_cast<const IntegerItem*>(this);
+    const IntegerItem* item = static_cast<const IntegerItem*>(item1);
 
     doubleValue = item->theValue;
 
@@ -217,7 +225,7 @@
 
   case XS_UNSIGNED_LONG:
   {
-    const UnsignedLongItem* item = static_cast<const UnsignedLongItem*>(this);
+    const UnsignedLongItem* item = static_cast<const UnsignedLongItem*>(item1);
 
     doubleValue = item->theValue;
 
@@ -238,7 +246,7 @@
 
   case XS_LONG:
   {
-    const LongItem* item = static_cast<const LongItem*>(this);
+    const LongItem* item = static_cast<const LongItem*>(item1);
 
     doubleValue = item->theValue;
 
@@ -252,7 +260,7 @@
   case XS_SHORT:
   case XS_BYTE:
   {
-    doubleValue = getIntValue();
+    doubleValue = item1->getIntValue();
     lossy = false;
     break;
   }
@@ -351,6 +359,22 @@
 
 
 /*******************************************************************************
+  class UserTypedAtomicItem
+********************************************************************************/
+store::Item* UserTypedAtomicItem::getBaseItem() const 
+{
+  store::Item* baseItem = theBaseItem.getp();
+
+  while (baseItem->getBaseItem() != NULL)
+  {
+    baseItem = baseItem->getBaseItem();
+  }
+
+  return baseItem;
+}
+
+
+/*******************************************************************************
   class UntypedAtomicItem
 ********************************************************************************/
 bool UntypedAtomicItem::castToUri(store::Item_t& result) const

=== modified file 'src/store/naive/atomic_items.h'
--- src/store/naive/atomic_items.h	2011-08-23 23:18:43 +0000
+++ src/store/naive/atomic_items.h	2011-10-04 08:30:40 +0000
@@ -110,7 +110,7 @@
   UserTypedAtomicItem() {}
 
 public:
-  store::Item* getBaseItem() const { return theBaseItem.getp(); }
+  store::Item* getBaseItem() const;
 
   SchemaTypeCode getTypeCode() const { return theBaseItem->getTypeCode(); }
 

=== modified file 'src/store/naive/simple_index.cpp'
--- src/store/naive/simple_index.cpp	2011-07-01 23:48:40 +0000
+++ src/store/naive/simple_index.cpp	2011-10-04 08:30:40 +0000
@@ -331,6 +331,30 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
+void IndexBoxCondition::pushRange(
+    store::Item_t& lower,
+    store::Item_t& upper,
+    bool haveLower,
+    bool haveUpper,
+    bool lowerIncl,
+    bool upperIncl)
+{
+  ZORBA_ASSERT(false);
+}
+
+
+void IndexBoxCondition::pushBound(
+    store::Item_t& bound, 
+    bool isLower,
+    bool boundIncl)
+{
+  ZORBA_ASSERT(false);
+}
+
+
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //
 //  IndexBoxValueCondition                                                     //
@@ -374,15 +398,6 @@
 }
 
 
-void IndexBoxValueCondition::pushBound(
-    store::Item_t& bound, 
-    bool isLower,
-    bool boundIncl)
-{
-  ZORBA_ASSERT(false);
-}
-
-
 /*******************************************************************************
 
 ********************************************************************************/
@@ -509,21 +524,6 @@
 /*******************************************************************************
 
 ********************************************************************************/
-void IndexBoxGeneralCondition::pushRange(
-    store::Item_t& lower,
-    store::Item_t& upper,
-    bool haveLower,
-    bool haveUpper,
-    bool lowerIncl,
-    bool upperIncl)
-{
-  ZORBA_ASSERT(false);
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
 void IndexBoxGeneralCondition::pushBound(
     store::Item_t& bound,
     bool isLower, 
@@ -545,6 +545,7 @@
 ********************************************************************************/
 bool IndexBoxGeneralCondition::test(const store::IndexKey& key) const
 {
+  ZORBA_ASSERT(false);
   return true;
 }
 

=== modified file 'src/store/naive/simple_index.h'
--- src/store/naive/simple_index.h	2011-06-29 16:38:22 +0000
+++ src/store/naive/simple_index.h	2011-10-04 08:30:40 +0000
@@ -241,16 +241,37 @@
   IndexBoxCondition(IndexImpl* idx) : theIndex(idx) { }
 
   void pushItem(store::Item_t& item);
+
+  virtual void pushRange(
+        store::Item_t& lower,
+        store::Item_t& upper,
+        bool haveLower,
+        bool haveUpper,
+        bool lowerIncl,
+        bool upperIncl);
+
+  virtual void pushBound(store::Item_t& bound, bool isLower, bool boundIncl);
 };
 
 
 /*******************************************************************************
-
+  It represents a condition that is satisfied by the index keys inside a
+  user-specified "box".
+
+  Let M be the number of key columns. Then, an M-dimensional box is defined as
+  a conjuction of M range conditions on columns 0 to M-1. Each range condition
+  specifies a range of acceptable values for some key column. Specifically, a
+  range is defined as the set of all key values K such that
+
+  lower_bound <? K <? upper_bound, where <? is either the lt or the le operator.
+
+  The lower bound may be -INFINITY and the upper bound may be +INFINTY.
 ********************************************************************************/
 class IndexBoxValueCondition : public IndexBoxCondition
 {
   friend class ValueTreeIndex;
   friend class ProbeValueTreeIndexIterator;
+  friend class ProbeGeneralTreeIndexIterator;
 
   friend std::ostream& operator<<(std::ostream& os, const IndexBoxValueCondition& c);
 
@@ -278,8 +299,6 @@
       bool lowerIncl,
       bool upperIncl);
 
-  void pushBound(store::Item_t& bound, bool isLower, bool boundIncl);
-
   bool test(const store::IndexKey& key) const;
 
   std::string toString() const;
@@ -290,7 +309,23 @@
 
 
 /*******************************************************************************
-
+  It represents the following condition:
+
+  bound op? K, where 
+
+  (a) op? is one of <, <=, >, or >=, 
+  (b) K is a key value, and 
+  (c) bound is either an atomic item or -INFINITY or +INFINITY.
+
+  theRangeFlags:
+  --------------
+  Specify the kind of operator and whether the bound is INFINITY or not
+
+  theBound:
+  ---------
+  The search key that serves as either a lower bound or an upper bound. If,
+  according to theRangeFlags, the bound is not INFINITY, theBound contains 
+  exactly one non-NULL atomic item; otherwise, it is empty.
 ********************************************************************************/
 class IndexBoxGeneralCondition : public IndexBoxCondition
 {
@@ -312,14 +347,6 @@
 
   void clear();
 
-  void pushRange(
-      store::Item_t& lower,
-      store::Item_t& upper,
-      bool haveLower,
-      bool haveUpper,
-      bool lowerIncl,
-      bool upperIncl);
-
   void pushBound(store::Item_t& bound, bool isLower, bool boundIncl);
 
   bool test(const store::IndexKey& key) const;

=== modified file 'src/store/naive/simple_index_general.cpp'
--- src/store/naive/simple_index_general.cpp	2011-07-29 06:13:28 +0000
+++ src/store/naive/simple_index_general.cpp	2011-10-04 08:30:40 +0000
@@ -1415,32 +1415,65 @@
   return true;
 }
 
+
+/******************************************************************************
+
+*******************************************************************************/
 ulong GeneralTreeIndex::size() const
 {
   return 0;
 }
 
+
+/******************************************************************************
+
+*******************************************************************************/
+store::Index::KeyIterator_t GeneralTreeIndex::keys() const
+{
+  return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//                                                                             //
+//  GeneralTreeIndex::KeyIterator                                              //
+//                                                                             //
+/////////////////////////////////////////////////////////////////////////////////
+
+
+/******************************************************************************
+
+*******************************************************************************/
+GeneralTreeIndex::KeyIterator::~KeyIterator()
+{
+}
+
+
+/******************************************************************************
+
+*******************************************************************************/
 void GeneralTreeIndex::KeyIterator::open()
 {
 }
 
+
+/******************************************************************************
+
+*******************************************************************************/
 bool GeneralTreeIndex::KeyIterator::next(store::IndexKey&)
 {
   return false;
 }
 
+
+/******************************************************************************
+
+*******************************************************************************/
 void GeneralTreeIndex::KeyIterator::close()
 {
 }
 
-GeneralTreeIndex::KeyIterator::~KeyIterator()
-{
-}
 
-store::Index::KeyIterator_t GeneralTreeIndex::keys() const
-{
-  return 0;
-}
 
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //
@@ -1452,8 +1485,26 @@
 /////////////////////////////////////////////////////////////////////////////////
 
 
+#define PROBE_TREE_MAP(MAP_ID)                                          \
+{                                                                       \
+  ite = theIndex->theMaps[MAP_ID]->find(key);                           \
+  if (ite != theIndex->theMaps[MAP_ID]->end())                          \
+    theResultSets[0] = ite->second;                                     \
+}
+
+
+#define PROBE_ALT_TREE_MAP(MAP_ID)                                      \
+{                                                                       \
+  altKey[0].transfer(castItem);                                         \
+  theResultSets.push_back(NULL);                                        \
+  ite = theIndex->theMaps[MAP_ID]->find(&altKey);                       \
+  if (ite != theIndex->theMaps[MAP_ID]->end())                          \
+    theResultSets[theResultSets.size() - 1] = ite->second;              \
+}
+
+
 /******************************************************************************
-  Create an 
+
 ********************************************************************************/
 ProbeGeneralTreeIndexIterator::ProbeGeneralTreeIndexIterator(
     const store::Index_t& index) 
@@ -1470,6 +1521,36 @@
 /******************************************************************************
   
 ********************************************************************************/
+void ProbeGeneralTreeIndexIterator::checkStringKeyType(AtomicItem* keyItem) const
+{
+  if (keyItem == NULL)
+    return;
+
+  SchemaTypeCode keyType = keyItem->getTypeCode();
+
+  if (keyType != XS_UNTYPED_ATOMIC &&
+      keyType != XS_ANY_URI &&
+      keyType != XS_STRING &&
+      keyType != XS_NORMALIZED_STRING &&
+      keyType != XS_TOKEN &&
+      keyType != XS_NMTOKEN &&
+      keyType != XS_LANGUAGE &&
+      keyType != XS_NAME &&
+      keyType != XS_NCNAME &&
+      keyType != XS_ID &&
+      keyType != XS_IDREF &&
+      keyType != XS_ENTITY)
+  {
+    RAISE_ERROR_NO_LOC(err::XPTY0004,
+    ERROR_PARAMS(ZED(NoUntypedKeyNodeValue_2),
+                 theIndex->getName()->getStringValue()));
+  }
+}
+
+
+/******************************************************************************
+  
+********************************************************************************/
 void ProbeGeneralTreeIndexIterator::init(const store::IndexCondition_t& cond)
 {
   theProbeKind = cond->getKind();
@@ -1490,24 +1571,6 @@
 }
 
 
-#define PROBE_TREE_MAP(MAP_ID)                                          \
-{                                                                       \
-  ite = theIndex->theMaps[MAP_ID]->find(key);                           \
-  if (ite != theIndex->theMaps[MAP_ID]->end())                          \
-    theResultSets[0] = ite->second;                                     \
-}
-
-
-#define PROBE_ALT_TREE_MAP(MAP_ID)                                      \
-{                                                                       \
-  altKey[0].transfer(castItem);                                         \
-  theResultSets.push_back(NULL);                                        \
-  ite = theIndex->theMaps[MAP_ID]->find(&altKey);                       \
-  if (ite != theIndex->theMaps[MAP_ID]->end())                          \
-    theResultSets[theResultSets.size() - 1] = ite->second;              \
-}
-
-
 /******************************************************************************
   
 ********************************************************************************/
@@ -1515,12 +1578,17 @@
 {
   thePointCondition = reinterpret_cast<IndexPointCondition*>(cond.getp());
 
+  // Note: the runtime (or compiler) makes sure that the search tuple consists
+  // of exactly one search item, which is not NULL and whose type is a subtype
+  // of the index key type. Furthermore, in the case of a point-value probe,
+  // the type of the search item cannot be untyped, because untyped search keys
+  // either don't match the index key type, or are cast to xs:string. 
+
   store::IndexKey* key = &(thePointCondition->theKey);
 
   if (key->size() != theIndex->getNumColumns())
   {
-    RAISE_ERROR_NO_LOC(zerr::ZSTR0005_INDEX_PARTIAL_KEY_PROBE,
-    ERROR_PARAMS(key->toString(), theIndex->getName()->getStringValue()));
+    ZORBA_ASSERT(false);
   }
 
   if (theProbeKind == store::IndexCondition::POINT_VALUE)
@@ -1535,29 +1603,7 @@
     if (theIndex->theUntypedFlag)
     {
       AtomicItem* keyItem = static_cast<AtomicItem*>((*key)[0].getp());
-
-      if (keyItem->getBaseItem() != NULL)
-        keyItem = static_cast<AtomicItem*>(keyItem->getBaseItem());
-      
-      SchemaTypeCode keyType = keyItem->getTypeCode();
-
-      if (keyType != XS_UNTYPED_ATOMIC &&
-          keyType != XS_ANY_URI &&
-          keyType != XS_STRING &&
-          keyType != XS_NORMALIZED_STRING &&
-          keyType != XS_TOKEN &&
-          keyType != XS_NMTOKEN &&
-          keyType != XS_LANGUAGE &&
-          keyType != XS_NAME &&
-          keyType != XS_NCNAME &&
-          keyType != XS_ID &&
-          keyType != XS_IDREF &&
-          keyType != XS_ENTITY)
-      {
-        RAISE_ERROR_NO_LOC(err::XPTY0004,
-        ERROR_PARAMS(ZED(NoUntypedKeyNodeValue_2),
-                     theIndex->getName()->getStringValue()));
-      }
+      checkStringKeyType(keyItem);
     }
   }
 
@@ -1568,9 +1614,6 @@
 
   if (theIndex->isTyped())
   {
-    // Note: the runtime (or compiler) makes sure that the search key is a
-    // subtype of the index key type.
-
     ite = theIndex->theSingleMap->find(key);
 
     if (ite != theIndex->theSingleMap->end())
@@ -1714,6 +1757,8 @@
 
     case XS_UNTYPED_ATOMIC:
     {
+      ZORBA_ASSERT(theProbeKind == store::IndexCondition::POINT_GENERAL);
+
       theIsUntypedProbe = true;
 
       store::ItemHandle<UntypedAtomicItem> untypedItem = 
@@ -1831,88 +1876,221 @@
 void ProbeGeneralTreeIndexIterator::initValueBox(
     const store::IndexCondition_t& cond)
 {
-#if 0
-  theBoxCondition = reinterpret_cast<IndexBoxCondition*>(cond.getp());
-
-  long timezone = theIndex->getTimezone();
-
-  bool haveLowerBound = true;
-  bool haveUpperBound = true;
-  bool lowIncl = true;
-  bool highIncl = true;
-
-  ulong numRanges = theBoxCond->numRanges();
+  theBoxValueCondition = static_cast<IndexBoxValueCondition*>(cond.getp());
+
+  ulong numRanges = theBoxValueCondition->numRanges();
+
+  if (numRanges > theIndex->getNumColumns())
+  {
+    RAISE_ERROR_NO_LOC(zerr::ZSTR0006_INDEX_INVALID_BOX_PROBE,
+    ERROR_PARAMS(theIndex->getName()->getStringValue(), ZED(BoxCondTooManyColumns)));
+  }
 
   if (numRanges == 0)
   {
-    haveLowerBound = false;
-    haveUpperBound = false;
-  }
-
-  if (numRanges > theIndex->getNumColumns())
-  {
-    ZORBA_ERROR_PARAM(ZSTR0006_INDEX_INVALID_BOX_PROBE, 
-                      theIndex->getName()->getStringValue().c_str(),
-                      "The box condition has more columns than the index");
-  }
-
-  store::IndexKey& lowerBounds = theBoxCondition->theLowerBounds;
-  store::IndexKey& upperBounds = theBoxCondition->theUpperBounds;
-
-  RangeFlags& rangeFlags = theBoxCondition->theRangeFlags[0];
-#endif
+    ZORBA_ASSERT(false);
+  }
+
+  if (theIndex->theMultiKeyFlag)
+  {
+    RAISE_ERROR_NO_LOC(err::XPTY0004,
+    ERROR_PARAMS(ZED(NoMultiKeyNodeValues_2),
+                 theIndex->getName()->getStringValue()));
+  }
+
+  store::IndexKey* lowerKey = &theBoxValueCondition->theLowerBounds;
+  store::IndexKey* upperKey = &theBoxValueCondition->theUpperBounds;
+
+  AtomicItem* lowerKeyItem = static_cast<AtomicItem*>((*lowerKey)[0].getp());
+  AtomicItem* upperKeyItem = static_cast<AtomicItem*>((*upperKey)[0].getp());
+
+  bool haveLower = theBoxValueCondition->theRangeFlags[0].theHaveLowerBound;
+  bool haveUpper = theBoxValueCondition->theRangeFlags[0].theHaveUpperBound;
+
+  if (theIndex->theUntypedFlag)
+  {
+    checkStringKeyType(lowerKeyItem);
+    checkStringKeyType(upperKeyItem);
+  }
+
+  theMapBegins.clear();
+  theMapEnds.clear();
+
+  if (theIndex->isTyped())
+  {
+    // Note: the runtime (or compiler) makes sure that each search key is a
+    // subtype of the index key type.
+    probeMap(theIndex->theSingleMap, lowerKey, upperKey);
+  }
+  else if (haveLower || haveUpper)
+  {
+    store::Item_t castItem;
+
+    SchemaTypeCode lowerKeyType = (haveLower ? lowerKeyItem->getTypeCode() : XS_LAST);
+    SchemaTypeCode upperKeyType = (haveUpper ? upperKeyItem->getTypeCode() : XS_LAST);
+
+    SchemaTypeCode keyType = (lowerKeyType < upperKeyType ?
+                              lowerKeyType :
+                              upperKeyType);
+
+    switch (keyType)
+    {
+    case XS_BOOLEAN:
+    case XS_DATETIME:
+    case XS_DATE:
+    case XS_TIME:
+    {
+      probeMap(theIndex->theMaps[keyType], lowerKey, upperKey);
+      break;
+    }
+
+    case XS_DURATION:
+    case XS_YM_DURATION:
+    case XS_DT_DURATION:
+    {
+      probeMap(theIndex->theMaps[XS_DURATION], lowerKey, upperKey);
+      break;
+    }
+
+    case XS_ANY_URI:
+    {
+      probeMap(theIndex->theMaps[XS_ANY_URI], lowerKey, upperKey);
+
+      if (theIndex->theMaps[XS_STRING])
+      {
+        zstring tmp;
+        store::IndexKey lowerAltKey(1);
+        store::IndexKey upperAltKey(1);
+
+        if (haveLower)
+        {
+          lowerKeyItem->getStringValue2(tmp);
+          GET_FACTORY().createString(castItem, tmp);
+          lowerAltKey[0].transfer(castItem);
+        }
+
+        if (haveUpper)
+        {
+          upperKeyItem->getStringValue2(tmp);
+          GET_FACTORY().createString(castItem, tmp);
+          upperAltKey[0].transfer(castItem);
+        }
+        
+        probeMap(theIndex->theMaps[XS_STRING], &lowerAltKey, &aupperAltKey);
+      }
+
+      break;
+    }
+
+    case XS_STRING:
+    case XS_NORMALIZED_STRING:
+    case XS_TOKEN:
+    case XS_NMTOKEN:
+    case XS_LANGUAGE:
+    case XS_NAME:
+    case XS_NCNAME:
+    case XS_ID:
+    case XS_IDREF:
+    case XS_ENTITY:
+    {
+      probeMap(theIndex->theMaps[XS_STRING], lowerKey, upperKey);
+
+      if (theIndex->theMaps[XS_ANY_URI])
+      {
+        zstring tmp;
+        store::IndexKey lowerAltKey(1);
+        store::IndexKey upperAltKey(1);
+
+        if (haveLower)
+        {
+          lowerKeyItem->getStringValue2(tmp);
+          GET_FACTORY().createAnyURI(castItem, tmp);
+          lowerAltKey[0].transfer(castItem);
+        }
+
+        if (haveUpper)
+        {
+          upperKeyItem->getStringValue2(tmp);
+          GET_FACTORY().createAnyURI(castItem, tmp);
+          upperAltKey[0].transfer(castItem);
+        }
+
+        probeMap(theIndex->theMaps[XS_ANY_URI], &lowerAltKey, &upperAltKey);
+      }
+
+      break;
+    }
+
+    case XS_DOUBLE:
+    case XS_FLOAT:
+    {
+      probeMap(theIndex->theMaps[XS_DOUBLE], lowerKey, upperKey);
+
+      
+    }
+
+    default:
+      ZORBA_ASSERT(false);
+    }
+  }
+  else
+  {
+    for (ulong i = 0; i < XS_LAST; ++i)
+    {
+      if (theIndex->theMaps[i] == NULL)
+        continue;
+
+      theMapBegins.push_back(theIndex->theMaps[i]->begin());
+      theMapEnds.push_back(theIndex->theMaps[i]->end());
+  }
 }
 
 
-
 /******************************************************************************
   
 ********************************************************************************/
 void ProbeGeneralTreeIndexIterator::probeMap(
     GeneralTreeIndex::IndexMap* map,
-    const store::IndexKey* key)
+    const store::IndexKey* lowerKey,
+    const store::IndexKey* upperKey)
 {
   if (map == NULL)
     return;
 
-  bool haveLower = theBoxGeneralCondition->theRangeFlags.theHaveLowerBound;
-  bool haveUpper = theBoxGeneralCondition->theRangeFlags.theHaveUpperBound;
-  bool lowerIncl = theBoxGeneralCondition->theRangeFlags.theLowerBoundIncl;
-  bool upperIncl = theBoxGeneralCondition->theRangeFlags.theUpperBoundIncl;
-
-  if (haveLower && haveUpper)
-  {
-    if (lowerIncl)
-      theMapBegins.push_back(map->lower_bound(key));
-    else
-      theMapBegins.push_back(map->upper_bound(key));
-
-    if (upperIncl)
-      theMapEnds.push_back(map->upper_bound(key));
-    else
-      theMapEnds.push_back(map->lower_bound(key));
-  }
-  else if (haveLower)
-  {
-    theMapEnds.push_back(map->end());
-
-    if (lowerIncl)
-      theMapBegins.push_back(map->lower_bound(key));
-    else
-      theMapBegins.push_back(map->upper_bound(key));
-  }
-  else if (haveUpper)
-  {
-    theMapBegins.push_back(map->begin());
-    
-    if (upperIncl)
-      theMapEnds.push_back(map->upper_bound(key));
-    else
-      theMapEnds.push_back(map->lower_bound(key));
-  }
-  else
-  {
-    theMapBegins.push_back(map->begin());
+  IndexBoxCondition::RangeFlags& flags = 
+  (theProbeKind == store::IndexCondition::BOX_VALUE ?
+   theBoxValueCondition->theRangeFlags[0] :
+   theBoxGeneralCondition->theRangeFlags);
+
+  bool haveLower = flags.theHaveLowerBound;
+  bool haveUpper = flags.theHaveUpperBound;
+  bool lowerIncl = flags.theLowerBoundIncl;
+  bool upperIncl = flags.theUpperBoundIncl;
+
+  assert(theProbeKind != store::IndexCondition::BOX_GENERAL ||
+         !(haveLower && haveUpper));
+
+  if (haveLower)
+  {
+    if (lowerIncl)
+      theMapBegins.push_back(map->lower_bound(lowerKey));
+    else
+      theMapBegins.push_back(map->upper_bound(lowerKey));    
+  }
+  else
+  {
+    theMapBegins.push_back(map->begin());
+  }
+ 
+  if (haveUpper)
+  {
+    if (upperIncl)
+      theMapEnds.push_back(map->upper_bound(upperKey));
+    else
+      theMapEnds.push_back(map->lower_bound(upperKey));
+  }
+  else
+  {
     theMapEnds.push_back(map->end());
   }
 }
@@ -1998,8 +2176,6 @@
 
   bool haveLower = theBoxGeneralCondition->theRangeFlags.theHaveLowerBound;
   bool haveUpper = theBoxGeneralCondition->theRangeFlags.theHaveUpperBound;
-  //bool lowerIncl = theBoxGeneralCondition->theRangeFlags.theLowerBoundIncl;
-  //bool upperIncl = theBoxGeneralCondition->theRangeFlags.theUpperBoundIncl;
 
   theMapBegins.clear();
   theMapEnds.clear();
@@ -2010,12 +2186,10 @@
   {
     // Note: the runtime (or compiler) makes sure that the search key is a
     // subtype of the index key type.
-
-    probeMap(theIndex->theSingleMap, key);
+    probeMap(theIndex->theSingleMap, key, key);
   }
   else if (haveLower || haveUpper)
   {
-    //bool lossy;
     store::Item_t castItem;
     store::IndexKey altKey(1);
 
@@ -2036,7 +2210,7 @@
     case XS_DATE:
     case XS_TIME:
     {
-      probeMap(theIndex->theMaps[keyType], key);
+      probeMap(theIndex->theMaps[keyType], key, key);
       break;
     }
 
@@ -2044,23 +2218,23 @@
     case XS_YM_DURATION:
     case XS_DT_DURATION:
     {
-      probeMap(theIndex->theMaps[XS_DURATION], key);
+      probeMap(theIndex->theMaps[XS_DURATION], key, key);
       break;
     }
 
     case XS_ANY_URI:
     {
-      probeMap(theIndex->theMaps[XS_ANY_URI], key);
+      probeMap(theIndex->theMaps[XS_ANY_URI], key, key);
 
       if (theIndex->theMaps[XS_STRING])
       {
         zstring tmp;
         keyItem->getStringValue2(tmp);
-        GET_FACTORY().createAnyURI(castItem, tmp);
+        GET_FACTORY().createString(castItem, tmp);
 
         altKey[0].transfer(castItem);
         
-        probeMap(theIndex->theMaps[XS_STRING], &altKey);
+        probeMap(theIndex->theMaps[XS_STRING], &altKey, &altKey);
       }
 
       break;
@@ -2077,7 +2251,7 @@
     case XS_IDREF:
     case XS_ENTITY:
     {
-      probeMap(theIndex->theMaps[XS_STRING], key);
+      probeMap(theIndex->theMaps[XS_STRING], key, key);
 
       if (theIndex->theMaps[XS_ANY_URI])
       {
@@ -2087,7 +2261,7 @@
 
         altKey[0].transfer(castItem);
         
-        probeMap(theIndex->theMaps[XS_ANY_URI], &altKey);
+        probeMap(theIndex->theMaps[XS_ANY_URI], &altKey, &altKey);
       }
 
       break;
@@ -2096,7 +2270,7 @@
     case XS_DOUBLE:
     case XS_FLOAT:
     {
-      probeMap(theIndex->theMaps[XS_DOUBLE], key);
+      probeMap(theIndex->theMaps[XS_DOUBLE], key, key);
 
       if (theIndex->theMaps[XS_LONG])
       {
@@ -2105,7 +2279,7 @@
         if (castItem)
         {
           altKey[0].transfer(castItem);
-          probeMap(theIndex->theMaps[XS_LONG], &altKey);
+          probeMap(theIndex->theMaps[XS_LONG], &altKey, &altKey);
         }
       }
 
@@ -2120,12 +2294,12 @@
     case XS_POSITIVE_INTEGER:
     case XS_UNSIGNED_LONG:
     {
-      probeMap(theIndex->theMaps[XS_DECIMAL], key);
+      probeMap(theIndex->theMaps[XS_DECIMAL], key, key);
 
       if (theIndex->theMaps[XS_LONG])
       {
         altKey[0] = keyItem;
-        probeMap(theIndex->theMaps[XS_LONG], &altKey);
+        probeMap(theIndex->theMaps[XS_LONG], &altKey, &altKey);
       }
 
       if (theIndex->theMaps[XS_DOUBLE])
@@ -2133,7 +2307,7 @@
         xs_double doubleValue = keyItem->getDecimalValue();
         GET_FACTORY().createDouble(castItem, doubleValue);
         altKey[0].transfer(castItem);
-        probeMap(theIndex->theMaps[XS_DOUBLE], &altKey);
+        probeMap(theIndex->theMaps[XS_DOUBLE], &altKey, &altKey);
       }
 
       break;
@@ -2147,14 +2321,14 @@
     case XS_UNSIGNED_SHORT:
     case XS_UNSIGNED_BYTE:
     {
-      probeMap(theIndex->theMaps[XS_LONG], key);
+      probeMap(theIndex->theMaps[XS_LONG], key, key);
 
       if (theIndex->theMaps[XS_DECIMAL])
       {
         xs_decimal decimalValue = keyItem->getLongValue();
         GET_FACTORY().createDecimal(castItem, decimalValue);
         altKey[0].transfer(castItem);
-        probeMap(theIndex->theMaps[XS_DECIMAL], &altKey);
+        probeMap(theIndex->theMaps[XS_DECIMAL], &altKey, &altKey);
       }
 
       if (theIndex->theMaps[XS_DOUBLE])
@@ -2162,7 +2336,7 @@
         xs_double doubleValue = keyItem->getLongValue();
         GET_FACTORY().createDouble(castItem, doubleValue);
         altKey[0].transfer(castItem);
-        probeMap(theIndex->theMaps[XS_DOUBLE], &altKey);
+        probeMap(theIndex->theMaps[XS_DOUBLE], &altKey, &altKey);
       }
 
       break;
@@ -2180,14 +2354,14 @@
       {
         untypedItem->castToString(castItem);
         altKey[0].transfer(castItem);
-        probeMap(theIndex->theMaps[XS_STRING], &altKey);
+        probeMap(theIndex->theMaps[XS_STRING], &altKey, &altKey);
       }
 
       // cast to xs:anyURI
       if (theIndex->theMaps[XS_ANY_URI] && untypedItem->castToUri(castItem))
       {
         altKey[0].transfer(castItem);
-        probeMap(theIndex->theMaps[XS_ANY_URI], &altKey);
+        probeMap(theIndex->theMaps[XS_ANY_URI], &altKey, &altKey);
       }
 
       // try casting to xs:long
@@ -2202,7 +2376,7 @@
         if (theIndex->theMaps[XS_LONG])
         {
           altKey[0].transfer(castItem);
-          probeMap(theIndex->theMaps[XS_LONG], &altKey);
+          probeMap(theIndex->theMaps[XS_LONG], &altKey, &altKey);
         }
 
         if (theIndex->theMaps[XS_DOUBLE])
@@ -2210,7 +2384,7 @@
           xs_double doubleValue = longItem->getLongValue();
           GET_FACTORY().createDouble(castItem, doubleValue);
           altKey[0].transfer(castItem);
-          probeMap(theIndex->theMaps[XS_DOUBLE], &altKey);
+          probeMap(theIndex->theMaps[XS_DOUBLE], &altKey, &altKey);
         }
 
         if (theIndex->theMaps[XS_DECIMAL])
@@ -2218,7 +2392,7 @@
           xs_decimal decimalValue = longItem->getLongValue();
           GET_FACTORY().createDecimal(castItem, decimalValue);
           altKey[0].transfer(castItem);
-          probeMap(theIndex->theMaps[XS_DECIMAL], &altKey);
+          probeMap(theIndex->theMaps[XS_DECIMAL], &altKey, &altKey);
         }
       }
 
@@ -2234,12 +2408,12 @@
         if (theIndex->theMaps[XS_DECIMAL])
         {
           altKey[0].transfer(castItem);
-          probeMap(theIndex->theMaps[XS_DECIMAL], &altKey);
+          probeMap(theIndex->theMaps[XS_DECIMAL], &altKey, &altKey);
 
           if (theIndex->theMaps[XS_LONG])
           {
             altKey[0] = decimalItem;
-            probeMap(theIndex->theMaps[XS_LONG], &altKey);
+            probeMap(theIndex->theMaps[XS_LONG], &altKey, &altKey);
           }
 
           if (theIndex->theMaps[XS_DOUBLE])
@@ -2247,7 +2421,7 @@
             xs_double doubleValue = decimalItem->getDecimalValue();
             GET_FACTORY().createDouble(castItem, doubleValue);
             altKey[0].transfer(castItem);
-            probeMap(theIndex->theMaps[XS_DOUBLE], &altKey);
+            probeMap(theIndex->theMaps[XS_DOUBLE], &altKey, &altKey);
           }
         }
       }
@@ -2263,7 +2437,7 @@
         if (theIndex->theMaps[XS_DOUBLE])
         {
           altKey[0].transfer(castItem);
-          probeMap(theIndex->theMaps[XS_DOUBLE], &altKey);
+          probeMap(theIndex->theMaps[XS_DOUBLE], &altKey, &altKey);
         }
 
         if (theIndex->theMaps[XS_LONG])
@@ -2273,7 +2447,7 @@
           if (castItem)
           {
             altKey[0].transfer(castItem);
-            probeMap(theIndex->theMaps[XS_LONG], &altKey);
+            probeMap(theIndex->theMaps[XS_LONG], &altKey, &altKey);
           }
         }
       }
@@ -2282,28 +2456,28 @@
       else if (theIndex->theMaps[XS_DATETIME] && untypedItem->castToDateTime(castItem))
       {
         altKey[0].transfer(castItem);
-        probeMap(theIndex->theMaps[XS_DATETIME], &altKey);
+        probeMap(theIndex->theMaps[XS_DATETIME], &altKey, &altKey);
       }
 
       // try casting to xs:date
       else if (theIndex->theMaps[XS_DATE] && untypedItem->castToDate(castItem))
       {
         altKey[0].transfer(castItem);
-        probeMap(theIndex->theMaps[XS_DATE], &altKey);
+        probeMap(theIndex->theMaps[XS_DATE], &altKey, &altKey);
       }
 
       // try casting to xs:time
       else if (theIndex->theMaps[XS_TIME] && untypedItem->castToTime(castItem))
       {
         altKey[0].transfer(castItem);
-        probeMap(theIndex->theMaps[XS_TIME], &altKey);
+        probeMap(theIndex->theMaps[XS_TIME], &altKey, &altKey);
       }
 
       // try casting to xs:duration
       else if (theIndex->theMaps[XS_DURATION] && untypedItem->castToDuration(castItem))
       {
         altKey[0].transfer(castItem);
-        probeMap(theIndex->theMaps[XS_DURATION], &altKey);
+        probeMap(theIndex->theMaps[XS_DURATION], &altKey, &altKey);
       }
 
       break;
@@ -2403,6 +2577,12 @@
       {
         if (theIsUntypedProbe && (*theIte).theUntyped)
         {
+          assert(theProbeKind == store::IndexCondition::POINT_GENERAL);
+          // Note: in case of a point value probe, (*theIte).theUntyped implies
+          // that the search key is of type xs:string, or xs:anyURI (otherwise,
+          // an error would have been raised in the initPoint method). As a 
+          // result, we should not skip this node.
+
           ++theIte;
           continue;
         }

=== modified file 'src/store/naive/simple_index_general.h'
--- src/store/naive/simple_index_general.h	2011-07-06 19:19:49 +0000
+++ src/store/naive/simple_index_general.h	2011-10-04 08:30:40 +0000
@@ -285,6 +285,7 @@
 
   store::IndexCondition::Kind                 theProbeKind;
   rchandle<IndexPointCondition>               thePointCondition;
+  rchandle<IndexBoxValueCondition>            theBoxValueCondition;
   rchandle<IndexBoxGeneralCondition>          theBoxGeneralCondition;
   bool                                        theIsUntypedProbe;
 
@@ -321,11 +322,16 @@
 
   void initGeneralBox(const store::IndexCondition_t& cond);
 
-  void probeMap(GeneralTreeIndex::IndexMap* map, const store::IndexKey* key);
+  void probeMap(
+      GeneralTreeIndex::IndexMap* map,
+      const store::IndexKey* lowerKey,
+      const store::IndexKey* upperKey);
 
   void doubleToLongProbe(
       const AtomicItem* doubleItem,
       store::Item_t& result) const;
+
+  void checkStringKeyType(AtomicItem* keyItem) const;
 };
 
 

=== modified file 'src/store/naive/store_defs.h'
--- src/store/naive/store_defs.h	2011-09-15 07:18:45 +0000
+++ src/store/naive/store_defs.h	2011-10-04 08:30:40 +0000
@@ -106,6 +106,7 @@
 
   XS_FLOAT,
   XS_DOUBLE,
+
   XS_DECIMAL,
   XS_INTEGER,
   XS_NON_POSITIVE_INTEGER,
@@ -133,34 +134,6 @@
 };
 
 
-enum IndexKeyTypeCode
-{
-  IDX_XS_STRING,
-
-  IDX_XS_DOUBLE,
-
-  IDX_XS_DECIMAL,
-
-  IDX_XS_INTEGER,
-
-  IDX_XS_LONG,
-
-  IDX_XS_BASE64BINARY,
-
-  IDX_XS_HEXBINARY,
-
-  IDX_XS_BOOLEAN,
-
-  IDX_XS_DATETIME,
-
-  IDX_XS_DURATION,
-
-  IDX_XS_QNAME,
-
-  IDX_XS_LAST
-};
-
-
 }
 }
 #endif

=== modified file 'src/zorbaserialization/zorba_class_serializer.cpp'
--- src/zorbaserialization/zorba_class_serializer.cpp	2011-07-29 23:27:03 +0000
+++ src/zorbaserialization/zorba_class_serializer.cpp	2011-10-04 08:30:40 +0000
@@ -404,12 +404,15 @@
       {
         ar.dont_allow_delay();
         ar & type;//save qname of type
+
+        ar.set_is_temp_field(false);
+        ar.dont_allow_delay();
+
         ///check for User Typed Atomic Item
-        store::Item*    baseItem;
-        if(ar.is_serializing_out())         
+        store::Item* baseItem;
+        if(ar.is_serializing_out())       
           baseItem = (store::Item*)obj->getBaseItem();            
-        ar.set_is_temp_field(false);
-        ar.dont_allow_delay();
+
         ar & baseItem;
         ar.set_is_temp_field(true);
         if(baseItem)

=== modified file 'test/rbkt/ExpQueryResults/zorba/index/auctions1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/index/auctions1.xml.res	2011-07-01 05:22:12 +0000
+++ test/rbkt/ExpQueryResults/zorba/index/auctions1.xml.res	2011-10-04 08:30:40 +0000
@@ -110,20 +110,31 @@
 Probing the typed AuctionDates sorted general index
 ---------------------------------------------------
 
+probe 1:
 <exception>err:XPTY0004 : node with more than one key value found during probe on index "auctions:AuctionDates"</exception>
 
+probe 2:
 <exception>err:XPTY0004 : "xs:integer": search key type for index "auctions:AuctionDates" does not match expected type "xs:date"</exception>
 
+probe 3:
 <open_auction id="open_auction2"/><open_auction id="open_auction3"/>
 
+probe 4:
 <exception>err:XPTY0004 : "xs:string": search key type for index "auctions:AuctionDates" does not match expected type "xs:date"</exception>
 
+probe 5:
+<exception>err:XPTY0004 : node with more than one key value found during probe on index "auctions:AuctionDates"</exception>
+
+probe 6:
 <open_auction id="open_auction0"/><open_auction id="open_auction1"/><open_auction id="open_auction3"/><open_auction id="open_auction4"/><open_auction id="open_auction9"/><open_auction id="open_auction10"/><open_auction id="open_auction11"/>
 
+probe 7:
 <open_auction id="open_auction1"/><open_auction id="open_auction4"/><open_auction id="open_auction9"/>
 
+probe 8:
 <open_auction id="open_auction1"/><open_auction id="open_auction9"/>
 
+probe 9:
 <open_auction id="open_auction9"/>
 
 Empty Probe

=== modified file 'test/rbkt/Queries/zorba/index/auctions1.xq'
--- test/rbkt/Queries/zorba/index/auctions1.xq	2011-08-02 17:52:47 +0000
+++ test/rbkt/Queries/zorba/index/auctions1.xq	2011-10-04 08:30:40 +0000
@@ -72,6 +72,7 @@
 Probing the typed AuctionDates sorted general index
 ---------------------------------------------------
 
+probe 1:
 ",
 
 try
@@ -85,6 +86,7 @@
 
 "
 
+probe 2:
 ",
 
 try
@@ -98,6 +100,7 @@
 
 "
 
+probe 3:
 ",
 
 for $id in index_dml:probe-index-point-general($auctions:AuctionDates, 
@@ -108,20 +111,39 @@
 
 "
 
+probe 4:
 ",
 
 try
 {
   index_dml:probe-index-point-general($auctions:AuctionDates, 
-                                  (xs:date("2000-12-04"), "2000-12-04"))
-}
-catch * 
-{
-  <exception>{$err:code} : {$err:description}</exception>
-},
-
-"
-
+                                      (xs:date("2000-12-04"), "2000-12-04"))
+}
+catch * 
+{
+  <exception>{$err:code} : {$err:description}</exception>
+},
+
+"
+
+probe 5:
+",
+
+try
+{
+  index_dml:probe-index-range-value($auctions:AuctionDates, 
+                                    xs:date("1998-12-11"),
+                                    xs:date("1999-12-11"),
+                                    fn:true(), fn:true(), fn:true(), fn:true())
+}
+catch * 
+{
+  <exception>{$err:code} : {$err:description}</exception>
+},
+
+"
+
+probe 6:
 ",
 
 for $id in index_dml:probe-index-range-general($auctions:AuctionDates,
@@ -136,34 +158,37 @@
 
 "
 
-",
-
-for $id in index_dml:probe-index-range-general($auctions:AuctionDates, 
-                                               (xs:date("2001-11-11"),
-                                                xs:date("2001-12-13")),
-                                               (),
-                                               fn:true(),
-                                               fn:false(),
-                                               fn:true(),
-                                               fn:true())/@id
-return <open_auction>{$id}</open_auction>,
-
-"
-
-",
-
-for $id in index_dml:probe-index-range-general($auctions:AuctionDates, 
-                                               (xs:date("2001-11-11"),
-                                                xs:date("2001-12-13")),
-                                               (),
-                                               fn:true(),
-                                               fn:false(),
-                                               fn:false(),
-                                               fn:true())/@id
-return <open_auction>{$id}</open_auction>,
-
-"
-
+probe 7:
+",
+
+for $id in index_dml:probe-index-range-general($auctions:AuctionDates, 
+                                               (xs:date("2001-11-11"),
+                                                xs:date("2001-12-13")),
+                                               (),
+                                               fn:true(),
+                                               fn:false(),
+                                               fn:true(),
+                                               fn:true())/@id
+return <open_auction>{$id}</open_auction>,
+
+"
+
+probe 8:
+",
+
+for $id in index_dml:probe-index-range-general($auctions:AuctionDates, 
+                                               (xs:date("2001-11-11"),
+                                                xs:date("2001-12-13")),
+                                               (),
+                                               fn:true(),
+                                               fn:false(),
+                                               fn:false(),
+                                               fn:true())/@id
+return <open_auction>{$id}</open_auction>,
+
+"
+
+probe 9:
 ",
 
 for $id in index_dml:probe-index-range-general($auctions:AuctionDates, 
@@ -352,6 +377,47 @@
 return <open_auction>{$id}</open_auction>,
 
 "
+
+-----------------------------------------------------------
+Probing the untyped PersonIncome2 sorted general 1-1 index
+-----------------------------------------------------------
+
+probe 1:
+
+",
+
+try
+{
+for $person in index_dml:probe-index-range-value($auctions:PersonIncome2, 
+                                                 10000,
+                                                 50000,
+                                                 fn:false(),
+                                                 fn:false(),
+                                                 fn:true(),
+                                                 fn:true())
+return <person>{$person/@id, $person//@income}</person>
+}
+catch *
+{
+  <exception>{$err:code} : {$err:description}</exception>
+},
+
+"
+
+probe 2:
+
+",
+
+for $person in index_dml:probe-index-range-value($auctions:PersonIncome2, 
+                                                 "10000",
+                                                 "50000",
+                                                 fn:true(),
+                                                 fn:true(),
+                                                 fn:true(),
+                                                 fn:true())
+return <person>{$person/@id, $person//@income}</person>,
+
+"
 "
 
 )

=== modified file 'test/rbkt/Queries/zorba/index/auctions_module1.xqlib'
--- test/rbkt/Queries/zorba/index/auctions_module1.xqlib	2011-08-12 16:07:57 +0000
+++ test/rbkt/Queries/zorba/index/auctions_module1.xqlib	2011-10-04 08:30:40 +0000
@@ -15,6 +15,7 @@
 declare variable $auctions:PersonWatches2 := xs:QName("auctions:PersonWatches2");
 declare variable $auctions:AuctionDates := xs:QName("auctions:AuctionDates");
 declare variable $auctions:AuctionDates2 := xs:QName("auctions:AuctionDates2");
+declare variable $auctions:PersonIncome2 := xs:QName("auctions:PersonIncome2");
 
 declare collection auctions:auctions as node()*;
 
@@ -39,7 +40,8 @@
 
 
 (:
-  The PersonWatches index maps each open auction to the persons who watch that auction.
+  The PersonWatches index maps each open auction to the persons who watch that 
+  auction. A person may watch multiple open auctions.
 :)
 
 declare %ann:general-equality %ann:manual index auctions:PersonWatches
@@ -58,7 +60,7 @@
 
 (:
   The AuctionDates index maps dates to the open auctions that had a biding on the
-  associated date.
+  associated date. An open auction may have biddings on it on multiple dates.
 :)
 
 declare %ann:general-range %ann:manual index auctions:AuctionDates
@@ -77,6 +79,16 @@
 
 
 (:
+  The PersonIncome2 maps each income to the persons who have that income.
+  Each person has at most one income.
+:)
+
+declare %ann:general-range %ann:manual index auctions:PersonIncome2
+on nodes dml:collection(xs:QName("auctions:auctions"))//person
+by .//@income;
+
+
+(:
   Create and populate the collection, and then create the indexes
 :)
 
@@ -97,6 +109,8 @@
   index_ddl:create($auctions:AuctionDates);
 
   index_ddl:create($auctions:AuctionDates2);
+
+  index_ddl:create($auctions:PersonIncome2);
 };
 
 


Follow ups