PyObject* check_compatible(PyObject* self, PyObject* args) { PyObject *tmcap; int from, to; if (!PyArg_ParseTuple(args, "Oii", &tmcap, &from, &to)) { return NULL; } TypeManager *tm = unwrap_TypeManager(tmcap); if(!tm) { BAD_TM_ARGUMENT; return NULL; } switch(tm->isCompatible(Type(from), Type(to))){ case TCC_EXACT: return PyString_FromString("exact"); case TCC_PROMOTE: return PyString_FromString("promote"); case TCC_CONVERT_SAFE: return PyString_FromString("safe"); case TCC_CONVERT_UNSAFE: return PyString_FromString("unsafe"); default: Py_RETURN_NONE; } }
xqtref_t fn_remove::getReturnType(const fo_expr* caller) const { TypeManager* tm = caller->get_type_manager(); return tm->create_type_x_quant(*caller->get_arg(0)->get_return_type(), SequenceType::QUANT_QUESTION); }
SequenceType SequenceType::createSchemaAttributeType( const StaticContext_t& sctx, const String& uri, const String& localName, Quantifier quant) { ZORBA_ASSERT(sctx != NULL); static_context* sctx2 = Unmarshaller::getInternalStaticContext(sctx); TypeManager* tm = sctx2->get_typemanager(); zstring& ns = Unmarshaller::getInternalString(uri); zstring& local = Unmarshaller::getInternalString(localName); store::Item_t qname; ZORBA_ASSERT(!local.empty()); GENV_ITEMFACTORY->createQName(qname, ns, "", local); try { xqtref_t res = tm->create_schema_attribute_type(qname, quant, QueryLoc::null); return Unmarshaller::createSequenceType(res.getp()); } catch (...) { return Unmarshaller::createSequenceType(NULL); } }
std::string Serializer::serialize(const TypeManager &typeManager) { rapidjson::Document document; { rapidjson::Value moduleTypesValue; moduleTypesValue.SetArray(); for(unsigned int i=0; i<typeManager.numUserTypes(); ++i){ rapidjson::Value moduleTypeValue; jsonifyModuleType(*typeManager.getUserType(i), moduleTypeValue, document); moduleTypesValue.PushBack(moduleTypeValue, document.GetAllocator()); } document.SetObject(); document.AddMember("moduleTypes", moduleTypesValue, document.GetAllocator()); } //TODO remove this line when rapidjson have fixed their bug (radix separator is decided by locale, instead of set to .) setlocale(LC_NUMERIC, "POSIX"); //make an std::string from the document StdStringStreamWrapper streamWrapper; rapidjson::PrettyWriter<StdStringStreamWrapper> writer(streamWrapper); document.Accept(writer); return streamWrapper.stream.str(); }
SequenceType SequenceType::createAtomicOrUnionType( const StaticContext_t& sctx, const String& uri, const String& localName, Quantifier quant) { TypeManager* tm; if (sctx == NULL) { tm = &GENV_TYPESYSTEM; } else { static_context* sctx2 = Unmarshaller::getInternalStaticContext(sctx); tm = sctx2->get_typemanager(); } zstring& ns = Unmarshaller::getInternalString(uri); zstring& local = Unmarshaller::getInternalString(localName); store::Item_t qname; GENV_ITEMFACTORY->createQName(qname, ns, "", local); xqtref_t type = tm->create_named_type(qname, quant, QueryLoc::null, false); if (type->isGenAtomicAny()) return Unmarshaller::createSequenceType(type.getp()); return Unmarshaller::createSequenceType(NULL); }
PyObject* set_compatible(PyObject* self, PyObject* args) { PyObject *tmcap; int from, to, by; if (!PyArg_ParseTuple(args, "Oiii", &tmcap, &from, &to, &by)) { return NULL; } TypeManager *tm = unwrap_TypeManager(tmcap); if (!tm) { BAD_TM_ARGUMENT; return NULL; } TypeCompatibleCode tcc; switch (by) { case 'p': // promote tcc = TCC_PROMOTE; break; case 's': // safe convert tcc = TCC_CONVERT_SAFE; break; case 'u': // unsafe convert tcc = TCC_CONVERT_UNSAFE; break; default: PyErr_SetString(PyExc_ValueError, "Unknown TCC"); return NULL; } tm->addCompatibility(Type(from), Type(to), tcc); Py_RETURN_NONE; }
xqtref_t op_concatenate::getReturnType(const fo_expr* caller) const { TypeManager* tm = caller->get_type_manager(); csize sz = caller->num_args(); if (sz == 0) { return GENV_TYPESYSTEM.EMPTY_TYPE; } else { xqtref_t t = caller->get_arg(0)->get_return_type(); SequenceType::Quantifier q = SequenceType::QUANT_STAR; for (csize i = 1; i < sz; i++) { t = TypeOps::union_type(*t, *caller->get_arg(i)->get_return_type(), tm); SequenceType::Quantifier pq = t->get_quantifier(); if (pq == SequenceType::QUANT_ONE || pq == SequenceType::QUANT_PLUS) q = SequenceType::QUANT_PLUS; } return tm->create_type_x_quant(*t, q); } }
xqtref_t op_zorba_sequence_point_access::getReturnType( const fo_expr* caller) const { TypeManager* tm = caller->get_type_manager(); return tm->create_type(*caller->get_arg(0)->get_return_type(), SequenceType::QUANT_QUESTION); }
SequenceType SequenceType::createJSONArrayType(Quantifier q) { TypeManager* tm = &GENV_TYPESYSTEM; xqtref_t res = tm->create_json_type(store::StoreConsts::jsonArray, q); return Unmarshaller::createSequenceType(res.getp()); }
xqtref_t fn_one_or_more::getReturnType(const fo_expr* caller) const { TypeManager* tm = caller->get_type_manager(); return tm->create_type( *TypeOps::prime_type(tm, *(caller->get_arg(0)->get_return_type())), SequenceType::QUANT_PLUS); }
xqtref_t fn_zero_or_one::getReturnType(const fo_expr* caller) const { TypeManager* tm = caller->get_type_manager(); xqtref_t srcType = caller->get_arg(0)->get_return_type(); return tm->create_type(*TypeOps::prime_type(tm, *srcType), SequenceType::QUANT_QUESTION); }
PyObject* select_overload(PyObject* self, PyObject* args) { PyObject *tmcap, *sigtup, *ovsigstup; int allow_unsafe; if (!PyArg_ParseTuple(args, "OOOi", &tmcap, &sigtup, &ovsigstup, &allow_unsafe)) { return NULL; } TypeManager *tm = unwrap_TypeManager(tmcap); if (!tm) { BAD_TM_ARGUMENT; } Py_ssize_t sigsz = PySequence_Size(sigtup); Py_ssize_t ovsz = PySequence_Size(ovsigstup); Type *sig = new Type[sigsz]; Type *ovsigs = new Type[ovsz * sigsz]; for (int i = 0; i < sigsz; ++i) { sig[i] = Type(PyNumber_AsSsize_t(PySequence_Fast_GET_ITEM(sigtup, i), NULL)); } for (int i = 0; i < ovsz; ++i) { PyObject *cursig = PySequence_Fast_GET_ITEM(ovsigstup, i); for (int j = 0; j < sigsz; ++j) { long tid = PyNumber_AsSsize_t(PySequence_Fast_GET_ITEM(cursig, j), NULL); ovsigs[i * sigsz + j] = Type(tid); } } int selected = -42; int matches = tm->selectOverload(sig, ovsigs, selected, sigsz, ovsz, (bool) allow_unsafe); delete [] sig; delete [] ovsigs; if (matches > 1) { PyErr_SetString(PyExc_TypeError, "Ambigous overloading"); return NULL; } else if (matches == 0) { PyErr_SetString(PyExc_TypeError, "No compatible overload"); return NULL; } return PyLong_FromLong(selected); }
SequenceType SequenceType::createElementType( const StaticContext_t& sctx, const String& nodeUri, const String& nodeLocalName, const String& typeUri, const String& typeLocalName, bool nillable, Quantifier quant) { TypeManager* tm; if (sctx == NULL) { tm = &GENV_TYPESYSTEM; } else { static_context* sctx2 = Unmarshaller::getInternalStaticContext(sctx); tm = sctx2->get_typemanager(); } zstring& nodeNS = Unmarshaller::getInternalString(nodeUri); zstring& nodeLocal = Unmarshaller::getInternalString(nodeLocalName); store::Item_t nodeQName; if (!nodeLocal.empty()) GENV_ITEMFACTORY->createQName(nodeQName, nodeNS, "", nodeLocal); zstring& typeNS = Unmarshaller::getInternalString(typeUri); zstring& typeLocal = Unmarshaller::getInternalString(typeLocalName); store::Item_t typeQName; xqtref_t contentType; if (!typeLocal.empty()) { GENV_ITEMFACTORY->createQName(typeQName, typeNS, "", typeLocal); contentType = tm->create_named_type(typeQName, QUANT_ONE, QueryLoc::null, false); if (contentType == NULL) return Unmarshaller::createSequenceType(NULL); } xqtref_t res = tm->create_node_type(store::StoreConsts::elementNode, nodeQName, contentType, quant, nillable, false); return Unmarshaller::createSequenceType(res.getp()); }
SequenceType SequenceType::createNamespaceType(Quantifier quant) { TypeManager* tm = &GENV_TYPESYSTEM; xqtref_t res = tm->create_node_type(store::StoreConsts::namespaceNode, NULL, NULL, quant, false, false); return Unmarshaller::createSequenceType(res.getp()); }
void SchemaValidatorImpl::validateSimpleContent( store::Item *typeQName, zstring newValue, std::vector<store::Item_t>& resultList) { TypeManager* typeManager = theSctx->get_typemanager(); Schema* schema = typeManager->getSchema(); ZORBA_ASSERT( schema ); const xqtref_t& targetType = schema->createXQTypeFromTypeName(typeManager, typeQName); schema->parseUserSimpleTypes(newValue, targetType, resultList, QueryLoc::null, false); }
xqtref_t op_zorba_subsequence_int::getReturnType(const fo_expr* caller) const { TypeManager* tm = caller->get_type_manager(); xqtref_t argType = caller->get_arg(0)->get_return_type(); //When there is a length argument and it's 1 then we know we will return //a value type T? where the input sequence was type T* or T+ if (caller->num_args() > 2 && caller->get_arg(2)->get_expr_kind() == const_expr_kind) { store::Item* len = static_cast<const_expr*>(caller->get_arg(2))->get_val(); if (len->getIntegerValue() == Integer(1)) return tm->create_type(*argType, SequenceType::QUANT_QUESTION); } return tm->create_type_x_quant(*argType, SequenceType::QUANT_QUESTION); }
xqtref_t fn_data::getReturnType(const fo_expr* caller) const { const QueryLoc& loc = caller->get_loc(); TypeManager* tm = caller->get_type_manager(); RootTypeManager& RTM = GENV_TYPESYSTEM; xqtref_t argType = caller->get_arg(0)->get_return_type(); if (TypeOps::is_subtype(tm, *argType, *RTM.ANY_ATOMIC_TYPE_STAR, loc)) return argType; // includes () case SequenceType::Quantifier q = argType->get_quantifier(); if (argType->type_kind() == XQType::NODE_TYPE_KIND) { const NodeXQType& nType = static_cast<const NodeXQType&>(*argType); store::StoreConsts::NodeKind nodeKind = nType.get_node_kind(); if (nodeKind == store::StoreConsts::piNode || nodeKind == store::StoreConsts::commentNode) { return tm->create_builtin_atomic_type(store::XS_STRING, q); } if (nodeKind == store::StoreConsts::documentNode || nodeKind == store::StoreConsts::textNode) { return tm->create_builtin_atomic_type(store::XS_UNTYPED_ATOMIC, q); } xqtref_t cType = nType.get_content_type(); if (cType != NULL) { if (cType->isList()) { const XQType* itemType = static_cast<const UserDefinedXQType*>(cType.getp())-> getListItemType(); return tm->create_type(*itemType, SequenceType::QUANT_STAR); } else if (TypeOps::is_equal(tm, *cType, *RTM.UNTYPED_ATOMIC_TYPE_ONE)) { return tm->create_builtin_atomic_type(store::XS_UNTYPED_ATOMIC, q); } else if (TypeOps::is_equal(tm, *cType, *RTM.UNTYPED_TYPE)) { return tm->create_builtin_atomic_type(store::XS_UNTYPED_ATOMIC, q); } else if (TypeOps::is_subtype(tm, *cType, *RTM.ANY_ATOMIC_TYPE_STAR, loc)) { return tm->create_type(*cType, q); } } } return RTM.ANY_ATOMIC_TYPE_STAR; }
bool SchemaValidatorImpl::isPossibleSimpleContentRevalidation( store::Item* typeQName) { TypeManager* typeManager = theSctx->get_typemanager(); //StaticContextConsts::validation_mode_t mode = theSctx->validation_mode(); Schema* schema = typeManager->getSchema(); if ( !schema ) { // no schema available no change to pul return false; } xqtref_t schemaType = schema->createXQTypeFromTypeName(typeManager, typeQName); if ( schemaType.getp() ) return isPossibleSimpleContentRevalImpl(schemaType); else return false; }
SequenceType SequenceType::createDocumentType( const SequenceType& contentType, Quantifier quant) { const XQType* contentType2 = Unmarshaller::getInternalType(contentType); TypeManager* tm = (contentType2 == NULL ? &GENV_TYPESYSTEM : contentType2->get_manager()); store::Item_t qname; xqtref_t res = tm->create_node_type(store::StoreConsts::documentNode, qname, contentType2, quant, false, false); return Unmarshaller::createSequenceType(res.getp()); }
int main() { TypeManager tm; Type t_int32 = tm.get("int32"); Type t_float = tm.get("float"); Type t_int64 = tm.get("int64"); tm.addConversion(t_int32, t_float); tm.addConversion(t_float, t_int32); tm.addConversion(t_float, t_int64); tm.addPromotion(t_int32, t_int64); cout << "int32 -> float " << TCCString(tm.isCompatible(tm.get("int32"), tm.get("float"))) << EOL; cout << "int32 -> int64 " << TCCString(tm.isCompatible(tm.get("int32"), tm.get("int64"))) << EOL; Type sig[] = {t_int32, t_float}; Type ovsigs[] = { t_float, t_float, t_int64, t_int64, t_int32, t_float, }; int sel = tm.selectOverload(sig, ovsigs, 2, 3); cout << "Selected " << sel << '\n'; return 0; }
void SchemaValidatorImpl::validateAfterUpdate( store::Item* item, zorba::store::PUL* pul, const QueryLoc& loc) { ZORBA_ASSERT(item->isNode()); TypeManager* typeManager = theSctx->get_typemanager(); StaticContextConsts::validation_mode_t mode = theSctx->validation_mode(); if (mode == StaticContextConsts::skip_validation) return; bool isLax = (mode == StaticContextConsts::lax_validation); Schema* schema = typeManager->getSchema(); if ( !schema ) { // no schema available no change to pul return; } EventSchemaValidator schemaValidator = EventSchemaValidator(typeManager, schema->getGrammarPool(), isLax, theLoc); switch ( item->getNodeKind() ) { case store::StoreConsts::documentNode: { //cout << "Validate after update document" << "\n"; cout.flush(); schemaValidator.startDoc(); store::NsBindings bindings; namespace_context nsCtx = namespace_context(theSctx, bindings); std::vector<store::Item_t> typedValues; processChildren(pul, nsCtx, typeManager, schemaValidator, item->getChildren(), typedValues, loc); schemaValidator.endDoc(); //cout << "End Validate after update doc" << "\n"; cout.flush(); return; } case store::StoreConsts::elementNode: { //cout << "Validate after update element" << "\n"; cout.flush(); schemaValidator.startDoc(); processElement(pul, typeManager, schemaValidator, item, loc); schemaValidator.endDoc(); //cout << "End Validate after update elem" << "\n"; cout.flush(); return; } default: throw XQUERY_EXCEPTION( err::XQDY0061, ERROR_PARAMS( ZED( NotDocOrElementNode ) ), ERROR_LOC( theLoc ) ); } }
forlet_clause::forlet_clause( static_context* sctx, CompilerCB* ccb, const QueryLoc& loc, flwor_clause::ClauseKind kind, var_expr* varExpr, expr* domainExpr, var_expr* posVarExpr, var_expr* scoreVarExpr, bool isAllowingEmpty, bool lazy) : forletwin_clause(sctx, ccb, loc, kind, varExpr, domainExpr), thePosVarExpr(posVarExpr), theScoreVarExpr(scoreVarExpr), theAllowingEmpty(isAllowingEmpty), theLazyEval(lazy) { if (thePosVarExpr != NULL) thePosVarExpr->set_flwor_clause(this); if (theScoreVarExpr != NULL) theScoreVarExpr->set_flwor_clause(this); if (varExpr != NULL && sctx != NULL) { RootTypeManager& rtm = GENV_TYPESYSTEM; TypeManager* tm = sctx->get_typemanager(); xqtref_t declaredType = varExpr->get_type(); if (declaredType != NULL) { if (kind == flwor_clause::for_clause && declaredType->is_empty()) { RAISE_ERROR(err::XPTY0004, loc, ERROR_PARAMS(ZED(BadType_23o), "empty-sequence")); } xqtref_t domainType = domainExpr->get_return_type(); if (!TypeOps::is_equal(tm, *rtm.ITEM_TYPE_STAR, *declaredType, loc)) { if (kind == flwor_clause::for_clause) { SequenceType::Quantifier domQuant = domainType->get_quantifier(); SequenceType::Quantifier declQuant = declaredType->get_quantifier(); if (theAllowingEmpty && (declQuant == SequenceType::QUANT_ONE || declQuant == SequenceType::QUANT_PLUS)) { declaredType = tm->create_type(*declaredType, SequenceType::QUANT_PLUS); } else { declaredType = tm->create_type(*declaredType, domQuant); } } if (!TypeOps::is_subtype(tm, *domainType, *declaredType, loc)) { xqtref_t varType = TypeOps::intersect_type(*domainType, *declaredType, tm); if (TypeOps::is_equal(tm, *varType, *rtm.NONE_TYPE, loc)) { RAISE_ERROR(err::XPTY0004, loc, ERROR_PARAMS(ZED(BadType_23o), *domainType, ZED(NoTreatAs_4), *declaredType)); } domainExpr = theCCB->theEM-> create_treat_expr(sctx, domainExpr->get_udf(), loc, domainExpr, declaredType, TREAT_TYPE_MATCH); set_expr(domainExpr); } } } } }
bool deepEqualNodes( const QueryLoc& loc, static_context* sctx, const store::Item* item1, const store::Item* item2, XQPCollator* collator, int timezone, bool raiseError) { if (item1->getNodeKind() != item2->getNodeKind()) return false; switch (item1->getNodeKind()) { case store::StoreConsts::documentNode: { return deepEqualChildren(loc, sctx, item1->getChildren(), item2->getChildren(), collator, timezone, raiseError); break; } case store::StoreConsts::elementNode: { if (! item1->getNodeName()->equals(item2->getNodeName())) return false; if (!deepEqualAttributes(loc, sctx, item1->getAttributes(), item2->getAttributes(), collator, timezone, raiseError)) return false; if (item1->haveSimpleContent()) { if (!item2->haveSimpleContent()) return false; store::Item_t value1, value2; store::Iterator_t ite1, ite2; item1->getTypedValue(value1, ite1); item2->getTypedValue(value2, ite2); if (ite1 == NULL && ite2 == NULL) { return deepEqual(loc, sctx, value1, value2, collator, timezone, raiseError); } else if (ite1 != NULL && ite2 != NULL) { ite1->open(); ite2->open(); while (1) { bool c1Valid = ite1->next(value1); bool c2Valid = ite2->next(value2); if (!c1Valid && !c2Valid) return true; else if (!c1Valid || !c2Valid) return false; else if (!deepEqual(loc, sctx, value1, value2, collator, timezone, raiseError)) return false; } } else { return false; } } else if (item2->haveSimpleContent()) { return false; } else { store::Item* typename1 = item1->getType(); store::Item* typename2 = item2->getType(); if (typename1->equals(typename2)) { return deepEqualChildren(loc, sctx, item1->getChildren(), item2->getChildren(), collator, timezone, raiseError); } else { TypeManager* tm = sctx->get_typemanager(); xqtref_t type1 = tm->create_named_type(typename1, SequenceType::QUANT_ONE, loc, raiseError); xqtref_t type2 = tm->create_named_type(typename2, SequenceType::QUANT_ONE, loc, raiseError); ZORBA_ASSERT(type1->isComplex() && type2->isComplex()); if (type1->contentKind() != type2->contentKind()) return false; return deepEqualChildren(loc, sctx, item1->getChildren(), item2->getChildren(), collator, timezone, raiseError); } } break; } case store::StoreConsts::attributeNode: { if (! item1->getNodeName()->equals(item2->getNodeName())) return false; store::Item_t value1, value2; store::Iterator_t ite1, ite2; item1->getTypedValue(value1, ite1); item2->getTypedValue(value2, ite2); if (ite1 == NULL && ite2 == NULL) { return deepEqual(loc, sctx, value1, value2, collator, timezone, raiseError); } else if (ite1 != NULL && ite2 != NULL) { ite1->open(); ite2->open(); while (1) { bool c1Valid = ite1->next(value1); bool c2Valid = ite2->next(value2); if (!c1Valid && !c2Valid) return true; else if (!c1Valid || !c2Valid) return false; else if (!deepEqual(loc, sctx, value1, value2, collator, timezone, raiseError)) return false; } } else { return false; } break; } case store::StoreConsts::textNode: case store::StoreConsts::commentNode: { return (0 == utf8::compare(item1->getStringValue(), item2->getStringValue(), collator)); } case store::StoreConsts::piNode: { if (utf8::compare(item1->getNodeName()->getStringValue(), item2->getNodeName()->getStringValue(), collator)) return false; return (0 == utf8::compare(item1->getStringValue(), item2->getStringValue(), collator)); } case store::StoreConsts::namespaceNode: { if (utf8::compare(item1->getNamespacePrefix(), item2->getNamespacePrefix(), collator)) return false; return (0 == utf8::compare(item1->getStringValue(), item2->getStringValue(), collator)); } default: ZORBA_ASSERT(false); } return true; }