← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~paul-lucas/zorba/bug-1147518 into lp:zorba

 

Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/bug-1147518 into lp:zorba.

Commit message:
Fixed all FOTS test failures.

Requested reviews:
  Paul J. Lucas (paul-lucas)
Related bugs:
  Bug #1147518 in Zorba: "fn:round-half-to-even (at least 11 failures)"
  https://bugs.launchpad.net/zorba/+bug/1147518

For more details, see:
https://code.launchpad.net/~paul-lucas/zorba/bug-1147518/+merge/158449

Fixed all FOTS test failures.
-- 
https://code.launchpad.net/~paul-lucas/zorba/bug-1147518/+merge/158449
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2013-04-11 16:59:33 +0000
+++ ChangeLog	2013-04-11 18:16:24 +0000
@@ -40,6 +40,7 @@
 Bug Fixes/Other Changes:
   * Fixed bug #1123836 (overflows in date/time casts now return FODT0001 and
     in durations return FODT0002)
+  * Fixed bug #1147518 (fn:round-half-to-even (at least 11 failures))
   * Fixed bug #1114228 (unrecognized options in the XQuery namespace now raise an error)
   * Fixed bug #1124273 (xqdoc crash because of annotation literals)
   * Fixed bug #867027 (XQST0059 error messages inconsistent)

=== modified file 'src/runtime/numerics/numerics_impl.cpp'
--- src/runtime/numerics/numerics_impl.cpp	2013-04-04 04:06:57 +0000
+++ src/runtime/numerics/numerics_impl.cpp	2013-04-11 18:16:24 +0000
@@ -258,7 +258,6 @@
 RoundIterator::nextImpl(store::Item_t& result, PlanState& planState) const
 {
   store::Item_t item;
-  store::Item_t res;
   xqtref_t type;
   store::Item_t precision;
   Integer precision_integer(0);
@@ -327,72 +326,77 @@
 }
 
 //6.4.5 fn:round-half-to-even
-bool
-RoundHalfToEvenIterator::nextImpl(store::Item_t& result, PlanState& planState) const
-{
+bool RoundHalfToEvenIterator::nextImpl( store::Item_t &result,
+                                        PlanState& planState ) const {
   store::Item_t item;
-  store::Item_t itemPrec;
-  store::Item_t res;
+  xs_integer precision;
+  RootTypeManager const &rtm = GENV_TYPESYSTEM;
+  TypeManager const *const tm = theSctx->get_typemanager();
   xqtref_t type;
-  Integer precision(0);
-
-  const TypeManager* tm = theSctx->get_typemanager();
-  const RootTypeManager& rtm = GENV_TYPESYSTEM;
-
-  PlanIteratorState* state;
-  DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
-
-  if (consumeNext(result, theChildren [0].getp(), planState ))
-  {
-    if (theChildren.size() == 2)
-    {
-      consumeNext(itemPrec, theChildren[1].getp(), planState);
-      assert(itemPrec->isAtomic());
-
-      precision = itemPrec->getIntegerValue();
-    }
-
-    //get the value and the type of the item
-    assert(result->isAtomic());
-
-    type = tm->create_value_type(result);
-
-    //Parameters of type xs:untypedAtomic are always promoted to xs:double
-    if ( TypeOps::is_subtype(tm, *type, *rtm.UNTYPED_ATOMIC_TYPE_ONE))
-    {
-      GenericCast::castToAtomic(result, result, &*rtm.DOUBLE_TYPE_ONE, tm, NULL, loc);
-      type = tm->create_value_type (result);
-    }
-
-    //item type is subtype of DOUBLE
-    if ( TypeOps::is_subtype(tm, *type, *rtm.DOUBLE_TYPE_ONE))
-      GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().roundHalfToEven(precision));
-
-    //item type is subtype of FLOAT
-    else if ( TypeOps::is_subtype(tm, *type, *rtm.FLOAT_TYPE_ONE))
-      GENV_ITEMFACTORY->createFloat(result, result->getFloatValue().roundHalfToEven(precision));
-
-    //item type is subtype of INTEGER
-    else if(TypeOps::is_subtype(tm, *type, *rtm.INTEGER_TYPE_ONE))
-    { /* do nothing */ }
-    //item type is subtype of DECIMAL
-    else if (TypeOps::is_subtype (tm, *type, *rtm.DECIMAL_TYPE_ONE))
-      GENV_ITEMFACTORY->createDecimal(result, result->getDecimalValue().roundHalfToEven(precision));
+
+  PlanIteratorState *state;
+  DEFAULT_STACK_INIT( PlanIteratorState, state, planState );
+
+  if ( consumeNext( result, theChildren [0].getp(), planState ) ) {
+    assert( result->isAtomic() );
+    type = tm->create_value_type( result );
+
+    if ( theChildren.size() == 2 ) {
+      consumeNext( item, theChildren[1].getp(), planState );
+      assert( item->isAtomic() );
+      precision = item->getIntegerValue();
+    }
+
+    if ( TypeOps::is_subtype( tm, *type, *rtm.UNTYPED_ATOMIC_TYPE_ONE ) ) {
+      //
+      // XQuery 3.0 3.1.5.2: Each item in the atomic sequence that is of type
+      // xs:untypedAtomic is cast to the expected generalized atomic type. For
+      // built-in functions where the expected type is specified as numeric,
+      // arguments of type xs:untypedAtomic are cast to xs:double.
+      //
+      GenericCast::castToAtomic(
+        result, result, &*rtm.DOUBLE_TYPE_ONE, tm, NULL, loc
+      );
+      type = tm->create_value_type( result );
+    }
+
+    if ( TypeOps::is_subtype( tm, *type, *rtm.DOUBLE_TYPE_ONE ) )
+      GENV_ITEMFACTORY->createDouble(
+        result, result->getDoubleValue().roundHalfToEven( precision )
+      );
+
+    else if ( TypeOps::is_subtype( tm, *type, *rtm.FLOAT_TYPE_ONE ) )
+      GENV_ITEMFACTORY->createFloat(
+        result, result->getFloatValue().roundHalfToEven( precision )
+      );
+
+    else if ( TypeOps::is_subtype( tm, *type, *rtm.INTEGER_TYPE_ONE ) )
+      GENV_ITEMFACTORY->createInteger(
+        result, result->getIntegerValue().roundHalfToEven( precision )
+      );
+
+    else if ( TypeOps::is_subtype( tm, *type, *rtm.DECIMAL_TYPE_ONE ) )
+      GENV_ITEMFACTORY->createDecimal(
+        result, result->getDecimalValue().roundHalfToEven( precision )
+      );
 
     else
-    {
-      RAISE_ERROR(err::XPTY0004, loc,
-      ERROR_PARAMS(ZED(BadTypeFor_23), type, "fn:round-half-to-even"));
-    }
+      throw XQUERY_EXCEPTION(
+        err::XPTY0004,
+        ERROR_PARAMS( ZED( BadTypeFor_23 ), type, "fn:round-half-to-even" ),
+        ERROR_LOC( loc )
+      );
 
-    if ( consumeNext(item, theChildren [0].getp(), planState ))
-    {
-      RAISE_ERROR(err::XPTY0004, loc,
-      ERROR_PARAMS(ZED(NoSeqForFnOp_2), "fn:round-half-to-even"));
+    if ( consumeNext( item, theChildren [0].getp(), planState ) ) {
+      throw XQUERY_EXCEPTION(
+        err::XPTY0004,
+        ERROR_PARAMS( ZED( NoSeqForFnOp_2 ), "fn:round-half-to-even" ),
+        ERROR_LOC( loc )
+      );
     }
-    STACK_PUSH ( true, state );
+    STACK_PUSH( true, state );
   }
-  STACK_END (state);
+  STACK_END( state );
 }
 
 } // namespace zorba

=== modified file 'src/zorbatypes/decimal.cpp'
--- src/zorbatypes/decimal.cpp	2013-04-09 22:38:19 +0000
+++ src/zorbatypes/decimal.cpp	2013-04-11 18:16:24 +0000
@@ -38,9 +38,10 @@
 
 namespace zorba {
 
-
 ///////////////////////////////////////////////////////////////////////////////
 
+Decimal::value_type const Decimal::round_precision_limit( 64 );
+
 void Decimal::parse( char const *s, value_type *result, int parse_options ) {
   if ( !*s )
     throw std::invalid_argument( "empty string" );
@@ -338,6 +339,11 @@
 
 Decimal::value_type Decimal::round2( value_type const &v,
                                      value_type const &precision ) {
+  if ( precision < -round_precision_limit )
+    return round2( v, -round_precision_limit );
+  if ( precision > round_precision_limit )
+    return round2( v, round_precision_limit );
+
   value_type const exp( value_type(10).pow( precision ) );
   value_type result( v * exp );
   result += MAPM::get0_5();
@@ -357,6 +363,11 @@
 
 Decimal::value_type Decimal::roundHalfToEven2( value_type const &v,
                                                value_type const &precision ) {
+  if ( precision < -round_precision_limit )
+    return roundHalfToEven2( v, -round_precision_limit );
+  if ( precision > round_precision_limit )
+    return roundHalfToEven2( v, round_precision_limit );
+
   value_type const exp( value_type(10).pow( precision ) );
   value_type result( v * exp );
   bool const aHalfVal = (result - MAPM::get0_5()) == result.floor();

=== modified file 'src/zorbatypes/decimal.h'
--- src/zorbatypes/decimal.h	2013-04-09 22:38:19 +0000
+++ src/zorbatypes/decimal.h	2013-04-11 18:16:24 +0000
@@ -233,6 +233,7 @@
   typedef long int_cast_type;
 
   value_type value_;
+  static value_type const round_precision_limit;
 
   Decimal( value_type const &v ) : value_( v ) { }
 

=== modified file 'test/fots/CMakeLists.txt'
--- test/fots/CMakeLists.txt	2013-04-11 02:29:22 +0000
+++ test/fots/CMakeLists.txt	2013-04-11 18:16:24 +0000
@@ -213,17 +213,6 @@
 EXPECTED_FOTS_FAILURE (fn-replace fn-replace-42 0)
 EXPECTED_FOTS_FAILURE (fn-resolve-uri fn-resolve-uri-26 0)
 EXPECTED_FOTS_FAILURE (fn-resolve-uri fn-resolve-uri-28 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even fn-round-half-to-even-9 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even fn-round-half-to-even-30 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even fn-round-half-to-even-31 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even fn-round-half-to-even-32 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even fn-round-half-to-even-33 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even fn-round-half-to-even-34 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even fn-round-half-to-even-35 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even cbcl-round-half-to-even-001 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even cbcl-round-half-to-even-003 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even cbcl-round-half-to-even-005 0)
-EXPECTED_FOTS_FAILURE (fn-round-half-to-even cbcl-round-half-to-even-012 0)
 EXPECTED_FOTS_FAILURE (fn-serialize serialize-xml-007a 0)
 EXPECTED_FOTS_FAILURE (fn-serialize serialize-xml-008 0)
 EXPECTED_FOTS_FAILURE (fn-string-length fn-string-length-22 0)

=== renamed file 'test/rbkt/ExpQueryResults/zorba/math/round-half-to-even8.xml.res' => 'test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-INF-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/math/round-half-to-even8.xml.res	2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-INF-1.xml.res	2013-04-11 18:16:24 +0000
@@ -1,2 +1,1 @@
-<?xml version="1.0" encoding="UTF-8"?>
-INF
\ No newline at end of file
+INF

=== renamed file 'test/rbkt/ExpQueryResults/zorba/math/round-half-to-even9.xml.res' => 'test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-INF-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/math/round-half-to-even9.xml.res	2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-INF-2.xml.res	2013-04-11 18:16:24 +0000
@@ -1,2 +1,1 @@
-<?xml version="1.0" encoding="UTF-8"?>
--INF
\ No newline at end of file
+-INF

=== renamed file 'test/rbkt/ExpQueryResults/zorba/math/round-half-to-even7.xml.res' => 'test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-NaN.xml.res'
--- test/rbkt/ExpQueryResults/zorba/math/round-half-to-even7.xml.res	2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-NaN.xml.res	2013-04-11 18:16:24 +0000
@@ -1,2 +1,1 @@
-<?xml version="1.0" encoding="UTF-8"?>
-NaN
\ No newline at end of file
+NaN

=== renamed file 'test/rbkt/ExpQueryResults/zorba/math/round-half-to-even1.xml.res' => 'test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-xs_decimal-01.xml.res'
=== renamed file 'test/rbkt/ExpQueryResults/zorba/math/round-half-to-even2.xml.res' => 'test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-xs_decimal-02.xml.res'
=== renamed file 'test/rbkt/ExpQueryResults/zorba/math/round-half-to-even3.xml.res' => 'test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-xs_decimal-03.xml.res'
=== renamed file 'test/rbkt/ExpQueryResults/zorba/math/round-half-to-even4.xml.res' => 'test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-xs_double-01.xml.res'
=== renamed file 'test/rbkt/ExpQueryResults/zorba/math/round-half-to-even5.xml.res' => 'test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-xs_double-02.xml.res'
=== renamed file 'test/rbkt/ExpQueryResults/zorba/math/round-half-to-even6.xml.res' => 'test/rbkt/ExpQueryResults/zorba/numerics/round-half-to-even-xs_double-03.xml.res'
=== renamed file 'test/rbkt/Queries/zorba/math/round-half-to-even8.xq' => 'test/rbkt/Queries/zorba/numerics/round-half-to-even-INF-1.xq'
--- test/rbkt/Queries/zorba/math/round-half-to-even8.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/numerics/round-half-to-even-INF-1.xq	2013-04-11 18:16:24 +0000
@@ -1,1 +1,1 @@
-fn:round-half-to-even(xs:double("INF"))
\ No newline at end of file
+fn:round-half-to-even( xs:double("INF") )

=== renamed file 'test/rbkt/Queries/zorba/math/round-half-to-even9.xq' => 'test/rbkt/Queries/zorba/numerics/round-half-to-even-INF-2.xq'
--- test/rbkt/Queries/zorba/math/round-half-to-even9.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/numerics/round-half-to-even-INF-2.xq	2013-04-11 18:16:24 +0000
@@ -1,1 +1,1 @@
-fn:round-half-to-even(xs:double("-INF"))
\ No newline at end of file
+fn:round-half-to-even( xs:double("-INF") )

=== renamed file 'test/rbkt/Queries/zorba/math/round-half-to-even7.xq' => 'test/rbkt/Queries/zorba/numerics/round-half-to-even-NaN.xq'
--- test/rbkt/Queries/zorba/math/round-half-to-even7.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/numerics/round-half-to-even-NaN.xq	2013-04-11 18:16:24 +0000
@@ -1,1 +1,1 @@
-fn:round-half-to-even(xs:double("NaN"))
\ No newline at end of file
+fn:round-half-to-even( xs:double("NaN") )

=== renamed file 'test/rbkt/Queries/zorba/math/round-half-to-even1.xq' => 'test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_decimal-01.xq'
--- test/rbkt/Queries/zorba/math/round-half-to-even1.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_decimal-01.xq	2013-04-11 18:16:24 +0000
@@ -1,1 +1,1 @@
-fn:round-half-to-even(0.5)
\ No newline at end of file
+fn:round-half-to-even( 0.5 )

=== renamed file 'test/rbkt/Queries/zorba/math/round-half-to-even2.xq' => 'test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_decimal-02.xq'
--- test/rbkt/Queries/zorba/math/round-half-to-even2.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_decimal-02.xq	2013-04-11 18:16:24 +0000
@@ -1,1 +1,1 @@
-fn:round-half-to-even(1.5)
\ No newline at end of file
+fn:round-half-to-even( 1.5 )

=== renamed file 'test/rbkt/Queries/zorba/math/round-half-to-even3.xq' => 'test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_decimal-03.xq'
--- test/rbkt/Queries/zorba/math/round-half-to-even3.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_decimal-03.xq	2013-04-11 18:16:24 +0000
@@ -1,1 +1,1 @@
-fn:round-half-to-even(2.5)
\ No newline at end of file
+fn:round-half-to-even( 2.5 )

=== renamed file 'test/rbkt/Queries/zorba/math/round-half-to-even4.xq' => 'test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_double-01.xq'
--- test/rbkt/Queries/zorba/math/round-half-to-even4.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_double-01.xq	2013-04-11 18:16:24 +0000
@@ -1,1 +1,1 @@
-fn:round-half-to-even(3.567812E+3, 2)
\ No newline at end of file
+fn:round-half-to-even( 3.567812E+3, 2 )

=== renamed file 'test/rbkt/Queries/zorba/math/round-half-to-even5.xq' => 'test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_double-02.xq'
--- test/rbkt/Queries/zorba/math/round-half-to-even5.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_double-02.xq	2013-04-11 18:16:24 +0000
@@ -1,1 +1,1 @@
-fn:round-half-to-even(4.7564E-3, 2)
\ No newline at end of file
+fn:round-half-to-even( 4.7564E-3, 2 )

=== renamed file 'test/rbkt/Queries/zorba/math/round-half-to-even6.xq' => 'test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_double-03.xq'
--- test/rbkt/Queries/zorba/math/round-half-to-even6.xq	2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/numerics/round-half-to-even-xs_double-03.xq	2013-04-11 18:16:24 +0000
@@ -1,1 +1,1 @@
-fn:round-half-to-even(35612.25, -2)
\ No newline at end of file
+fn:round-half-to-even( 35612.25, -2 )


Follow ups