zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #03496
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/markos-scratch into lp:zorba.
Requested reviews:
Markos Zaharioudakis (markos-za)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/88172
types-related optimization for the general comparison operator
--
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/88172
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/runtime/booleans/BooleanImpl.cpp'
--- src/runtime/booleans/BooleanImpl.cpp 2012-01-10 10:52:15 +0000
+++ src/runtime/booleans/BooleanImpl.cpp 2012-01-11 10:33:29 +0000
@@ -750,65 +750,63 @@
void CompareIterator::generalCasting(
const QueryLoc& loc,
const TypeManager* tm,
- store::Item_t& aItem0,
- store::Item_t& aItem1,
+ store::Item_t& item0,
+ store::Item_t& item1,
store::Item_t& castItem0,
store::Item_t& castItem1)
{
- RootTypeManager& rtm = GENV_TYPESYSTEM;
-
- xqtref_t type0 = tm->create_value_type(aItem0);
- xqtref_t type1 = tm->create_value_type(aItem1);
-
- if (TypeOps::is_subtype(tm, *type0, *rtm.UNTYPED_ATOMIC_TYPE_ONE))
+ store::SchemaTypeCode type0 = item0->getTypeCode();
+ store::SchemaTypeCode type1 = item1->getTypeCode();
+
+ if (TypeOps::is_subtype(type0, store::XS_UNTYPED_ATOMIC))
{
- if (TypeOps::is_numeric(tm, *type1))
+ if (TypeOps::is_numeric(type1))
{
- GenericCast::castToAtomic(castItem0, aItem0, &*rtm.DOUBLE_TYPE_ONE, tm, NULL, loc);
+ GenericCast::castToAtomic(castItem0, item0, store::XS_DOUBLE, tm, NULL, loc);
- GenericCast::promote(castItem1, aItem1, &*rtm.DOUBLE_TYPE_ONE, tm, loc);
- }
- else if (TypeOps::is_subtype(tm, *type1, *rtm.UNTYPED_ATOMIC_TYPE_ONE))
- {
- GenericCast::castToAtomic(castItem0, aItem0, &*rtm.STRING_TYPE_ONE, tm, NULL, loc);
- GenericCast::castToAtomic(castItem1, aItem1, &*rtm.STRING_TYPE_ONE, tm, NULL, loc);
- }
- else if (TypeOps::is_subtype(tm, *type1, *rtm.STRING_TYPE_ONE))
- {
- GenericCast::castToAtomic(castItem0, aItem0, &*rtm.STRING_TYPE_ONE, tm, NULL, loc);
- castItem1.transfer(aItem1);
+ GenericCast::promote(castItem1, item1, store::XS_DOUBLE, tm, loc);
+ }
+ else if (TypeOps::is_subtype(type1, store::XS_UNTYPED_ATOMIC))
+ {
+ GenericCast::castToAtomic(castItem0, item0, store::XS_STRING, tm, NULL, loc);
+ GenericCast::castToAtomic(castItem1, item1, store::XS_STRING, tm, NULL, loc);
+ }
+ else if (TypeOps::is_subtype(type1, store::XS_STRING))
+ {
+ GenericCast::castToAtomic(castItem0, item0, store::XS_STRING, tm, NULL, loc);
+ castItem1.transfer(item1);
}
else
{
- GenericCast::castToAtomic(castItem0, aItem0, &*type1, tm, NULL, loc);
- castItem1.transfer(aItem1);
+ GenericCast::castToAtomic(castItem0, item0, type1, tm, NULL, loc);
+ castItem1.transfer(item1);
}
}
- else if (TypeOps::is_subtype(tm, *type1, *rtm.UNTYPED_ATOMIC_TYPE_ONE))
+ else if (TypeOps::is_subtype(type1, store::XS_UNTYPED_ATOMIC))
{
- if (TypeOps::is_numeric(tm, *type0))
+ if (TypeOps::is_numeric(type0))
{
- GenericCast::castToAtomic(castItem1, aItem1, &*rtm.DOUBLE_TYPE_ONE, tm, NULL, loc);
- GenericCast::promote(castItem0, aItem0, &*rtm.DOUBLE_TYPE_ONE, tm, loc);
+ GenericCast::castToAtomic(castItem1, item1, store::XS_DOUBLE, tm, NULL, loc);
+ GenericCast::promote(castItem0, item0, store::XS_DOUBLE, tm, loc);
}
- else if (TypeOps::is_subtype(tm, *type0, *rtm.STRING_TYPE_ONE))
+ else if (TypeOps::is_subtype(type0, store::XS_STRING))
{
- GenericCast::castToAtomic(castItem1, aItem1, &*rtm.STRING_TYPE_ONE, tm, NULL, loc);
- castItem0.transfer(aItem0);
+ GenericCast::castToAtomic(castItem1, item1, store::XS_STRING, tm, NULL, loc);
+ castItem0.transfer(item0);
}
else
{
- GenericCast::castToAtomic(castItem1, aItem1, &*type0, tm, NULL, loc);
- castItem0.transfer(aItem0);
+ GenericCast::castToAtomic(castItem1, item1, type0, tm, NULL, loc);
+ castItem0.transfer(item0);
}
}
else
{
- if (!GenericCast::promote(castItem0, aItem0, &*type1, tm, loc))
- castItem0.transfer(aItem0);
+ if (!GenericCast::promote(castItem0, item0, type1, tm, loc))
+ castItem0.transfer(item0);
- if (!GenericCast::promote(castItem1, aItem1, &*type0, tm, loc))
- castItem1.transfer(aItem1);
+ if (!GenericCast::promote(castItem1, item1, type0, tm, loc))
+ castItem1.transfer(item1);
}
}
=== modified file 'src/types/casting.cpp'
--- src/types/casting.cpp 2012-01-10 10:52:15 +0000
+++ src/types/casting.cpp 2012-01-11 10:33:29 +0000
@@ -34,6 +34,7 @@
#include "store/api/item_factory.h"
#include "store/api/item.h"
#include "store/api/store.h"
+#include "store/api/xs_type_codes.h"
#include "types/typeops.h"
#include "types/typemanagerimpl.h"
@@ -65,18 +66,64 @@
struct ErrorInfo
{
- const XQType * theSourceType;
- const XQType * theTargetType;
- const QueryLoc & theLoc;
+ const XQType * theSourceType;
+ const XQType * theTargetType;
+ store::SchemaTypeCode theSourceTypeCode;
+ store::SchemaTypeCode theTargetTypeCode;
+ const QueryLoc & theLoc;
+
+ ErrorInfo(
+ const XQType* source,
+ const XQType* target,
+ const QueryLoc& loc)
+ :
+ theSourceType(source),
+ theTargetType(target),
+ theLoc(loc)
+ {
+ assert(source != NULL && target != NULL);
+ }
+
+ ErrorInfo(
+ store::SchemaTypeCode source,
+ store::SchemaTypeCode target,
+ const QueryLoc& loc)
+ :
+ theSourceType(NULL),
+ theTargetType(NULL),
+ theSourceTypeCode(source),
+ theTargetTypeCode(target),
+ theLoc(loc)
+ {
+ }
};
-#define TYPE_EXCEPTION( ERROR_CODE, ERROR_INFO ) \
- XQUERY_EXCEPTION(ERROR_CODE, \
- ERROR_PARAMS(*(ERROR_INFO).theSourceType, \
- ZED( NoCastTo_34o ), \
- *(ERROR_INFO).theTargetType ), \
- ERROR_LOC(ERROR_INFO.theLoc) )
+void throwTypeException(const Diagnostic& errcode, const ErrorInfo& info)
+{
+ if (info.theSourceType)
+ {
+ throw XQUERY_EXCEPTION_VAR(errcode,
+ ERROR_PARAMS(*info.theSourceType, ZED(NoCastTo_34o), *info.theTargetType),
+ ERROR_LOC(info.theLoc));
+ }
+ else
+ {
+ TypeManager& tm = GENV_TYPESYSTEM;
+
+ xqtref_t sourceType =
+ tm.create_builtin_atomic_type(info.theSourceTypeCode,
+ TypeConstants::QUANT_ONE);
+
+ xqtref_t targetType =
+ tm.create_builtin_atomic_type(info.theTargetTypeCode,
+ TypeConstants::QUANT_ONE);
+
+ throw XQUERY_EXCEPTION_VAR(errcode,
+ ERROR_PARAMS(*sourceType, ZED(NoCastTo_34o), *targetType),
+ ERROR_LOC(info.theLoc));
+ }
+}
/*******************************************************************************
@@ -149,7 +196,8 @@
}
catch (std::invalid_argument const&)
{
- throw TYPE_EXCEPTION(err::FORG0001, aErrorInfo);
+ throwTypeException(err::FORG0001, aErrorInfo);
+ return NULL;
}
catch ( std::range_error const& )
{
@@ -167,7 +215,8 @@
}
catch (std::invalid_argument const& )
{
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException(err::FORG0001, aErrorInfo);
+ return NULL;
}
catch (std::range_error const& )
{
@@ -185,7 +234,8 @@
}
catch ( std::exception const& )
{
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
}
@@ -199,11 +249,13 @@
}
catch ( std::invalid_argument const& )
{
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
catch ( std::range_error const& )
{
- throw TYPE_EXCEPTION( err::FOAR0002, aErrorInfo );
+ throwTypeException( err::FOAR0002, aErrorInfo );
+ return NULL;
}
}
@@ -216,7 +268,8 @@
if (0 == (err = Duration::parseDuration(strval.c_str(), strval.size(), d)))
return aFactory->createDuration(result, &d);
- throw TYPE_EXCEPTION(err::FORG0001, aErrorInfo);
+ throwTypeException(err::FORG0001, aErrorInfo);
+ return NULL;
}
@@ -228,7 +281,8 @@
if (0 == (err = Duration::parseYearMonthDuration(strval.c_str(), strval.size(), d)))
return aFactory->createYearMonthDuration(result, &d);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -240,7 +294,8 @@
if (0 == (err = Duration::parseDayTimeDuration(strval.c_str(), strval.size(), d)))
return aFactory->createDayTimeDuration(result, &d);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -250,7 +305,8 @@
if (0 == DateTime::parseDateTime(strval.c_str(), strval.size(), dt))
return aFactory->createDateTime(result, &dt);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -260,7 +316,8 @@
if (0 == DateTime::parseTime(strval.c_str(), strval.size(), t))
return aFactory->createTime(result, &t);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -270,7 +327,8 @@
if (0 == DateTime::parseDate(strval.c_str(), strval.size(), d))
return aFactory->createDate(result, &d);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -280,7 +338,8 @@
if (0 == DateTime::parseGYearMonth(strval.c_str(), strval.size(), ym))
return aFactory->createGYearMonth(result, &ym);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -290,7 +349,8 @@
if (0 == DateTime::parseGYear(strval.c_str(), strval.size(), y))
return aFactory->createGYear(result, &y);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -300,7 +360,8 @@
if (0 == DateTime::parseGMonthDay(strval.c_str(), strval.size(), md))
return aFactory->createGMonthDay(result, &md);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -310,7 +371,8 @@
if (0 == DateTime::parseGDay(strval.c_str(), strval.size(), d))
return aFactory->createGDay(result, &d);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -320,7 +382,8 @@
if (0 == DateTime::parseGMonth(strval.c_str(), strval.size(), m))
return aFactory->createGMonth(result, &m);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -357,14 +420,15 @@
}
else
{
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
pos = str - strval.c_str();
ascii::skip_whitespace(strval.c_str(), len, &pos);
if (pos != len)
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
return aFactory->createBoolean(result, lRetValue);
}
@@ -376,7 +440,8 @@
if (xs_base64Binary::parseString(strval, n))
return aFactory->createBase64Binary(result, n);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -386,7 +451,8 @@
if (xs_hexBinary::parseString(strval, n))
return aFactory->createHexBinary(result, n);
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -414,7 +480,7 @@
zstring::size_type lidx = strval.rfind(":", strval.size(), 1);
if (idx != lidx)
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
zstring nsuri;
zstring prefix;
@@ -434,7 +500,7 @@
prefix = strval.substr(0, idx);
if (!GenericCast::instance()->castableToNCName(prefix))
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
if (nsCtx)
{
@@ -446,7 +512,7 @@
}
if (!GenericCast::instance()->castableToNCName(local))
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
return aFactory->createQName(result, nsuri, prefix, local);
}
@@ -667,7 +733,8 @@
}
catch ( std::exception const& /*e*/ )
{
- throw TYPE_EXCEPTION( err::FOCA0002, aErrorInfo );
+ throwTypeException( err::FOCA0002, aErrorInfo );
+ return NULL;
}
}
@@ -680,7 +747,8 @@
}
catch ( std::exception const& )
{
- throw TYPE_EXCEPTION( err::FOCA0002, aErrorInfo );
+ throwTypeException( err::FOCA0002, aErrorInfo );
+ return NULL;
}
}
@@ -721,7 +789,8 @@
}
catch ( std::exception const& )
{
- throw TYPE_EXCEPTION( err::FOCA0002, aErrorInfo );
+ throwTypeException(err::FOCA0002, aErrorInfo);
+ return NULL;
}
}
@@ -734,7 +803,8 @@
}
catch ( std::exception const& )
{
- throw TYPE_EXCEPTION( err::FOCA0002, aErrorInfo );
+ throwTypeException( err::FOCA0002, aErrorInfo );
+ return NULL;
}
}
@@ -1351,7 +1421,8 @@
ZORBA_ASSERT(false);
}
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -1503,7 +1574,8 @@
default:
ZORBA_ASSERT (false);
}
- throw TYPE_EXCEPTION( err::FORG0001, aErrorInfo );
+ throwTypeException( err::FORG0001, aErrorInfo );
+ return NULL;
}
@@ -1676,7 +1748,7 @@
bool GenericCast::castToAtomic(
store::Item_t& result,
zstring& str,
- const XQType* aTargetType,
+ const XQType* targetType,
const TypeManager* tm,
namespace_context* aNsCtx,
const QueryLoc& loc)
@@ -1686,24 +1758,24 @@
const XQType* sourceType = rtm.STRING_TYPE_ONE.getp();
- ErrorInfo lErrorInfo = {&*sourceType, aTargetType, loc};
+ ErrorInfo lErrorInfo(sourceType, targetType, loc);
- if (!TypeOps::is_atomic(tm, *aTargetType))
- RAISE_ERROR(err::XPST0051, loc, ERROR_PARAMS(aTargetType));
+ if (!TypeOps::is_atomic(tm, *targetType))
+ RAISE_ERROR(err::XPST0051, loc, ERROR_PARAMS(targetType));
#ifndef ZORBA_NO_XMLSCHEMA
- if (aTargetType->type_kind() == XQType::USER_DEFINED_KIND)
+ if (targetType->type_kind() == XQType::USER_DEFINED_KIND)
{
store::Item_t baseItem;
bool success = tm->getSchema()->parseUserAtomicTypes(str,
- aTargetType,
+ targetType,
baseItem,
aNsCtx,
loc);
if (success)
{
- const UserDefinedXQType* udt = static_cast<const UserDefinedXQType*>(aTargetType);
+ const UserDefinedXQType* udt = static_cast<const UserDefinedXQType*>(targetType);
store::Item_t typeName = udt->get_qname();
GENV_ITEMFACTORY->createUserTypedAtomicItem(result, baseItem, typeName);
@@ -1716,7 +1788,7 @@
store::Item_t lItem;
ATOMIC_CODE_T sourceTypeCode = store::XS_STRING;
- ATOMIC_CODE_T targetTypeCode = TypeOps::get_atomic_type_code(*aTargetType);
+ ATOMIC_CODE_T targetTypeCode = TypeOps::get_atomic_type_code(*targetType);
bool valid = true;
if (theMapping[sourceTypeCode] == theMapping[targetTypeCode])
@@ -1728,7 +1800,7 @@
CastFunc lCastFunc = theCastMatrix[theMapping[sourceTypeCode]]
[theMapping[targetTypeCode]];
if (lCastFunc == 0)
- throw TYPE_EXCEPTION(err::XPTY0004, lErrorInfo);
+ throwTypeException(err::XPTY0004, lErrorInfo);
valid = (*lCastFunc)(result,
lItem,
@@ -1788,7 +1860,7 @@
// std::cout << "\t\t tgtType: " << aTargetType->get_qname()->getLocalName()->c_str()
// << " @ " << aTargetType->get_qname()->getNamespace()->c_str() << "\n";
- ErrorInfo errorInfo = {&*sourceType, targetType, loc};
+ ErrorInfo errorInfo(sourceType.getp(), targetType, loc);
if (!TypeOps::is_atomic(tm, *targetType))
RAISE_ERROR(err::XPST0051, loc, ERROR_PARAMS(targetType));
@@ -1820,18 +1892,18 @@
}
if (sourceTypeCode == store::XS_ANY_ATOMIC)
- throw TYPE_EXCEPTION(err::XPTY0004, errorInfo);
+ throwTypeException(err::XPTY0004, errorInfo);
if (targetTypeCode == store::XS_NCNAME &&
sourceTypeCode != store::XS_STRING &&
sourceTypeCode != store::XS_NCNAME &&
sourceTypeCode != store::XS_UNTYPED_ATOMIC)
- throw TYPE_EXCEPTION(err::XPTY0004, errorInfo);
+ throwTypeException(err::XPTY0004, errorInfo);
CastFunc castFunc = theCastMatrix[theMapping[sourceTypeCode]]
[theMapping[targetTypeCode]];
if (castFunc == 0)
- throw TYPE_EXCEPTION(err::XPTY0004, errorInfo);
+ throwTypeException(err::XPTY0004, errorInfo);
if (theMapping[sourceTypeCode] == theMapping[store::XS_STRING])
{
@@ -1865,6 +1937,87 @@
/*******************************************************************************
+ Cast, if possible, a given atomic item SI to an atomic item TI of a given
+ type TT. If the cast is not allowed, the method raises an error. If the cast
+ is not possible, the method may raise an error or return false (TODO fix
+ this!). Otherwise, it returns true.
+********************************************************************************/
+bool GenericCast::castToAtomic(
+ store::Item_t& result,
+ store::Item_t& item,
+ store::SchemaTypeCode targetType,
+ const TypeManager* tm,
+ namespace_context* nsCtx,
+ const QueryLoc& loc)
+{
+ RootTypeManager& rtm = GENV_TYPESYSTEM;
+ store::ItemFactory* factory = GENV_ITEMFACTORY;
+ zstring sourceString;
+
+ ZORBA_ASSERT(item->isAtomic());
+
+ store::SchemaTypeCode sourceType = item->getTypeCode();
+
+ ErrorInfo errorInfo(sourceType, targetType, loc);
+
+ if (sourceType == targetType)
+ {
+ result.transfer(item);
+ return true;
+ }
+
+ if (targetType == store::XS_NOTATION ||
+ targetType == store::XS_ANY_ATOMIC)
+ {
+ RAISE_ERROR(err::XPST0080, loc, ERROR_PARAMS(*errorInfo.theTargetType));
+ }
+
+ if (sourceType == store::XS_ANY_ATOMIC)
+ throwTypeException(err::XPTY0004, errorInfo);
+
+ if (targetType == store::XS_NCNAME &&
+ sourceType != store::XS_STRING &&
+ sourceType != store::XS_NCNAME &&
+ sourceType != store::XS_UNTYPED_ATOMIC)
+ throwTypeException(err::XPTY0004, errorInfo);
+
+ CastFunc castFunc = theCastMatrix[theMapping[sourceType]]
+ [theMapping[targetType]];
+ if (castFunc == 0)
+ throwTypeException(err::XPTY0004, errorInfo);
+
+ if (theMapping[sourceType] == theMapping[store::XS_STRING])
+ {
+ item->getStringValue2(sourceString);
+ }
+
+ bool valid = (*castFunc)(result,
+ item,
+ sourceString,
+ factory,
+ nsCtx,
+ errorInfo);
+
+ DownCastFunc downCastFunc = theDownCastMatrix[theMapping[targetType]];
+
+ if (downCastFunc != 0 &&
+ targetType != store::XS_STRING &&
+ targetType != store::XS_INTEGER)
+ {
+ valid = (*downCastFunc)(result,
+ &*result,
+ rtm,
+ targetType,
+ factory,
+ errorInfo);
+ }
+
+ assert(valid);
+ return valid;
+}
+
+
+/*******************************************************************************
********************************************************************************/
void castToUserDefinedType(
@@ -1874,7 +2027,7 @@
const XQType* aTargetType,
const QueryLoc& loc)
{
- ErrorInfo lErrorInfo = {aSourceType, aTargetType, loc};
+ ErrorInfo lErrorInfo(aSourceType, aTargetType, loc);
// std::cout << "-castToUserDefinedType: " << aItem.getp()->getStringValue()->c_str()
// << " srcType: " << aSourceType->get_qname()->getLocalName()->c_str()
@@ -1889,7 +2042,7 @@
if (aSourceType->type_kind() != XQType::ATOMIC_TYPE_KIND ||
(TypeOps::get_atomic_type_code(*aSourceType) != store::XS_STRING))
{
- throw TYPE_EXCEPTION(err::FORG0001, lErrorInfo);
+ throwTypeException(err::FORG0001, lErrorInfo);
}
const UserDefinedXQType* udt = static_cast<const UserDefinedXQType*>(aTargetType);
@@ -1973,17 +2126,11 @@
else if (!TypeOps::is_subtype(tm, *sourceType, *rtm.STRING_TYPE_ONE) &&
!TypeOps::is_equal(tm, *sourceType, *rtm.UNTYPED_ATOMIC_TYPE_ONE))
{
- throw XQUERY_EXCEPTION(
- err::XPTY0004,
- ERROR_PARAMS(
- ZED( BadType_23o ), *sourceType,
- ZED( NoCastTo_45o ), "QName"
- ),
- ERROR_LOC( loc )
- );
+ RAISE_ERROR(err::XPTY0004, loc,
+ ERROR_PARAMS(ZED(BadType_23o), *sourceType, ZED(NoCastTo_45o), "QName"));
}
- ErrorInfo errorInfo = { sourceType.getp(), rtm.QNAME_TYPE_ONE.getp(), loc };
+ ErrorInfo errorInfo(sourceType.getp(), rtm.QNAME_TYPE_ONE.getp(), loc);
zstring strval;
item->getStringValue2(strval);
@@ -1992,7 +2139,7 @@
zstring::size_type idx = strval.find(":");
zstring::size_type lidx = strval.rfind(":", strval.size(), 1);
if (idx != lidx)
- throw TYPE_EXCEPTION( err::FORG0001, errorInfo );
+ throwTypeException(err::FORG0001, errorInfo);
zstring prefix;
zstring nsuri;
@@ -2012,19 +2159,19 @@
prefix = strval.substr(0, idx);
if (!GenericCast::instance()->castableToNCName(prefix))
- throw TYPE_EXCEPTION( err::FORG0001, errorInfo );
+ throwTypeException(err::FORG0001, errorInfo);
if (nsCtx)
{
if (!nsCtx->findBinding(prefix, nsuri))
- throw XQUERY_EXCEPTION( err::FONS0004, ERROR_PARAMS( prefix ) );
+ throw XQUERY_EXCEPTION(err::FONS0004, ERROR_PARAMS(prefix));
}
local = strval.substr(idx + 1);
}
if (!GenericCast::instance()->castableToNCName(local.c_str()))
- throw TYPE_EXCEPTION( err::FORG0001, errorInfo );
+ throwTypeException(err::FORG0001, errorInfo );
return GENV_ITEMFACTORY->createQName(result, nsuri, prefix, local);
}
@@ -2450,6 +2597,62 @@
}
+/*******************************************************************************
+
+********************************************************************************/
+bool GenericCast::promote(
+ store::Item_t& result,
+ store::Item_t& item,
+ store::SchemaTypeCode targetType,
+ const TypeManager* tm,
+ const QueryLoc& loc)
+{
+ assert(item->isAtomic());
+
+ store::SchemaTypeCode itemType = item->getTypeCode();
+
+ if (TypeOps::is_subtype(itemType, targetType))
+ {
+ result.transfer(item);
+ return result != NULL;
+ }
+
+ if (TypeOps::is_subtype(itemType, store::XS_UNTYPED_ATOMIC) &&
+ ! TypeOps::is_subtype(targetType, store::XS_QNAME))
+ {
+ // untyped --> target type
+ return castToAtomic(result, item, targetType, tm, NULL, loc);
+ }
+ else if (TypeOps::is_subtype(targetType, store::XS_FLOAT))
+ {
+ // decimal --> xs:float
+ if (TypeOps::is_subtype(itemType, store::XS_DECIMAL))
+ {
+ return castToAtomic(result, item, targetType, tm, NULL, loc);
+ }
+ }
+ else if (TypeOps::is_subtype(targetType, store::XS_DOUBLE))
+ {
+ // Decimal/Float --> xs:double
+ if (TypeOps::is_subtype(itemType, store::XS_DECIMAL) ||
+ TypeOps::is_subtype(itemType, store::XS_FLOAT))
+ {
+ return castToAtomic(result, item, targetType, tm, NULL, loc);
+ }
+ }
+ else if (TypeOps::is_subtype(targetType, store::XS_STRING))
+ {
+ // URI --> xs:String Promotion
+ if (TypeOps::is_subtype(itemType, store::XS_ANY_URI))
+ {
+ return castToAtomic(result, item, store::XS_STRING, tm, NULL, loc);
+ }
+ }
+
+ return false;
+}
+
+
#undef ATOMIC_TYPE
=== modified file 'src/types/casting.h'
--- src/types/casting.h 2012-01-10 10:52:15 +0000
+++ src/types/casting.h 2012-01-11 10:33:29 +0000
@@ -66,16 +66,23 @@
/**
* Promotes the passed item to the passed target type.
- * @param aItem
- * @param aTargetType
+ * @param item
+ * @param targetType
* @return 0 if promotion is not possible else promoted item
* if the item type is a subtype of the target type, then
* the passed item is returned
*/
static bool promote(
store::Item_t& result,
- store::Item_t& aItem,
- const XQType* aTargetType,
+ store::Item_t& item,
+ const XQType* targetType,
+ const TypeManager* tm,
+ const QueryLoc& loc);
+
+ static bool promote(
+ store::Item_t& result,
+ store::Item_t& item,
+ store::SchemaTypeCode targetType,
const TypeManager* tm,
const QueryLoc& loc);
@@ -97,10 +104,23 @@
*/
static bool castToAtomic(
store::Item_t& result,
- store::Item_t& aItem,
- const XQType* aTargetType,
- const TypeManager* tm,
- namespace_context* aNCtx,
+ store::Item_t& item,
+ const XQType* targetType,
+ const TypeManager* tm,
+ namespace_context* nameCtx,
+ const QueryLoc& loc);
+
+ /**
+ * Executes the casting of the passed item. If the passed item has the same
+ * type or a subtype of the passed targetType, the passed item is directly
+ * returned.
+ */
+ static bool castToAtomic(
+ store::Item_t& result,
+ store::Item_t& item,
+ store::SchemaTypeCode targetType,
+ const TypeManager* tm,
+ namespace_context* nameCtx,
const QueryLoc& loc);
static bool castToSimple(
=== modified file 'src/types/typeops.cpp'
--- src/types/typeops.cpp 2012-01-10 13:54:05 +0000
+++ src/types/typeops.cpp 2012-01-11 10:33:29 +0000
@@ -288,6 +288,15 @@
/*******************************************************************************
********************************************************************************/
+bool TypeOps::is_numeric(store::SchemaTypeCode type)
+{
+ return store::XS_FLOAT <= type && type <= store::XS_POSITIVE_INTEGER;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
bool TypeOps::is_numeric(const TypeManager* tm, const XQType& type)
{
CHECK_IN_SCOPE(tm, type, QueryLoc::null);
=== modified file 'src/types/typeops.h'
--- src/types/typeops.h 2012-01-10 13:54:05 +0000
+++ src/types/typeops.h 2012-01-11 10:33:29 +0000
@@ -134,6 +134,12 @@
* numeric type (xs:decimal, xs:double, or xs:float)
*/
static bool is_numeric(const TypeManager* tm, const XQType& type);
+
+ /**
+ * Returns true is the given sequence type is a subtype of an atomic builtin
+ * numeric type (xs:decimal, xs:double, or xs:float)
+ */
+ static bool is_numeric(store::SchemaTypeCode type);
/**
* Returns true is the given sequence type is a subtype of an atomic builtin
@@ -164,7 +170,7 @@
/*
* Returns true if _subtype_ is a subtype of _supertype_, false otherwise.
*/
- bool is_subtype(
+ static bool is_subtype(
store::SchemaTypeCode subtype,
store::SchemaTypeCode supertype);
Follow ups
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: noreply, 2012-01-11
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Zorba Build Bot, 2012-01-11
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Zorba Build Bot, 2012-01-11
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Markos Zaharioudakis, 2012-01-11
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Zorba Build Bot, 2012-01-11
-
Re: [Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Zorba Build Bot, 2012-01-11
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Markos Zaharioudakis, 2012-01-11
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Zorba Build Bot, 2012-01-11
-
Re: [Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Zorba Build Bot, 2012-01-11
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Markos Zaharioudakis, 2012-01-11
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Zorba Build Bot, 2012-01-11
-
Re: [Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Zorba Build Bot, 2012-01-11
-
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Markos Zaharioudakis, 2012-01-11
-
Re: [Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
From: Markos Zaharioudakis, 2012-01-11