1 /* 2 * Copyright 2006-2008 The FLWOR Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 #ifndef ZORBA_TYPEOPS_H 18 #define ZORBA_TYPEOPS_H 19 20 #include <string> 21 #include <zorba/config.h> 22 #include "common/shared_types.h" 23 #include "types/typeconstants.h" 24 #include "zorba/typeident.h" 25 26 #include "compiler/parser/query_loc.h" 27 28 #include <zorba/store_consts.h> 29 #include "store/api/item.h" 30 31 namespace zorba 32 { 33 34 // exported for unit testing only 35 class ZORBA_DLL_PUBLIC TypeOps 36 { 37 public: 38 /** 39 * Return true is q1 is a sub-quantifier of q2 (see QUANT_SUBTYPE_MATRIX 40 * in root_typemanger.h). 41 */ 42 static bool is_sub_quant( 43 TypeConstants::quantifier_t q1, 44 TypeConstants::quantifier_t q2); 45 46 /** 47 * Return the "intersection" of the 2 given quantifiers (see QUANT_INTERS_MATRIX 48 * in root_typemanger.h). 49 */ 50 static TypeConstants::quantifier_t intersect_quant( 51 TypeConstants::quantifier_t, 52 TypeConstants::quantifier_t); 53 54 /** 55 * Return the "union" of the 2 given quantifiers (see QUANT_UNION_MATRIX 56 * in root_typemanger.h). 57 */ 58 static TypeConstants::quantifier_t union_quant( 59 TypeConstants::quantifier_t, 60 TypeConstants::quantifier_t); 61 62 /* 63 * Returns the atomic_type_code_t for a given type, which is assumed to be 64 * a quantified builtin atomic type. 65 */ 66 static store::SchemaTypeCode get_atomic_type_code(const XQType& type); 67 68 /** 69 * Return true is the given type is among the known types of the given type mgr 70 */ 71 static bool is_in_scope(const TypeManager* tm, const XQType& type); 72 73 /** 74 * Returns true if the quantifier of the given sequence type is QUANT_ONE and 75 * its ItemType is an atomic type. 76 */ 77 static bool is_atomic(const TypeManager* tm, const XQType& type); 78 79 /** 80 * Returns true if the quantifier of the given sequence type is QUANT_ONE and 81 * its ItemType is a builtin atomic type. 82 */ 83 static bool is_builtin_atomic(const TypeManager* tm, const XQType& type); 84 85 /** 86 * Returns true if the ItemType of the given sequence type is a builtin 87 * atomic type. 88 */ 89 static bool is_builtin_simple(const TypeManager* tm, const XQType& type); 90 91 /** 92 * Returns true is the given sequence type is a subtype of an atomic builtin 93 * numeric type (xs:decimal, xs:double, or xs:float) 94 */ 95 static bool is_numeric(const TypeManager* tm, const XQType& type); 96 97 /** 98 * Returns true is the given sequence type is a subtype of an atomic builtin 99 * numeric type (xs:decimal, xs:double, or xs:float) 100 */ 101 static bool is_numeric(store::SchemaTypeCode type); 102 103 /** 104 * Returns true is the given sequence type is a subtype of an atomic builtin 105 * numeric type (xs:decimal?, xs:double?, or xs:float?) or of xs:untypedAtomic? 106 */ 107 static bool is_numeric_or_untyped(const TypeManager* tm, const XQType& type); 108 109 /** 110 * Returns true is the given type could be a date / time type. 111 */ 112 static bool maybe_date_time(const TypeManager* tm, const XQType& type); 113 114 /* 115 * Returns the prime type (ItemType) of the given type. 116 */ 117 static xqtref_t prime_type(const TypeManager* tm, const XQType& type); 118 119 /* 120 * Returns true iff type1 is equal to type2 including the quantifier, 121 * false otherwise. 122 */ 123 static bool is_equal( 124 const TypeManager* tm, 125 const XQType& type1, 126 const XQType& type2, 127 const QueryLoc& loc = QueryLoc::null); 128 129 /* 130 * Returns true if _subtype_ is a subtype of _supertype_, false otherwise. 131 */ 132 static bool is_subtype( 133 store::SchemaTypeCode subtype, 134 store::SchemaTypeCode supertype); 135 136 /* 137 * Returns true if _subtype_ is a subtype of _supertype_, false otherwise. 138 */ 139 static bool is_subtype( 140 const TypeManager* tm, 141 const XQType& subtype, 142 const XQType& supertype, 143 const QueryLoc& loc = QueryLoc::null); 144 145 /* 146 * Returns true if the data type of the given item is a subtype of the 147 * given supertype; otherwise, returns false. 148 */ 149 static bool is_subtype( 150 const TypeManager* tm, 151 const store::Item* subitem, 152 const XQType& supertype, 153 const QueryLoc& loc); 154 155 /* 156 * Returns true if _item_ is treatable as _type_, false otherwise. 157 */ 158 static bool is_treatable( 159 const TypeManager* tm, 160 const store::Item_t& item, 161 const XQType& type, 162 const QueryLoc& loc); 163 164 /** 165 * Returns the castability fron the source ItemType to the target ItemType. It 166 * works only if both source and target types are builtin atomic types. 167 * Otherwise, it returns NOT_CASTABLE. 168 */ 169 static TypeConstants::castable_t castability( 170 const XQType& src, 171 const XQType& target); 172 173 /* 174 * Computes the union type (type1 | type2), of the two types. The output _u_ 175 * of this call satisfies the following invariant: 176 * 177 * is_subtype(_type1_, _u_) == true && is_subtype(_type2_, _u_) == true 178 */ 179 static xqtref_t union_type( 180 const XQType& type1, 181 const XQType& type2, 182 const TypeManager* manager); 183 184 /* 185 * Computes the intersection of the two types. The output _u_ of this call 186 * satisfies the following invariant: 187 * 188 * there exists some type(not necessarily representable in this TypeSystem), 189 * _t_ such that: 190 * is_subtype(_t_, _type1_) == true && 191 * is_subtype(_t_, _type2_) == true && 192 * is_subtype(_t_, _u_) == true. 193 * 194 * Informally, the returned type is a supertype (not necessarily a perfect 195 * supertype) of the actual intersection type. 196 */ 197 static xqtref_t intersect_type( 198 const XQType& type1, 199 const XQType& type2, 200 const TypeManager* manager); 201 202 /* 203 * Returns the type to be used for numeric arithmetic ops. 204 */ 205 static xqtref_t arithmetic_type( 206 const TypeManager* tm, 207 const XQType& type1, 208 const XQType& type2, 209 bool division); 210 211 /* 212 * Returns a type identifier that represents the given type. 213 * The invariant that is guaranteed is: 214 * is_subtype(_t_, create_type(*get_type_identifier(_t_))) == true 215 */ 216 static TypeIdentifier_t get_type_identifier( 217 const TypeManager* tm, 218 const XQType& type, 219 bool nested = false); 220 221 /* 222 * Writes a textual representation of the given type to the output stream. 223 */ 224 static std::ostream& serialize(std::ostream& os, const XQType& type); 225 226 /* 227 * Returns a string with a textual representation of the given type. 228 */ 229 static std::string toString(const XQType& type); 230 231 /* 232 * Returns a string with a textual representation of the given quantifier. 233 */ 234 static const char* decode_quantifier(TypeConstants::quantifier_t quant); 235 }; 236 237 } 238 239 #endif /* ZORBA_TYPEOPS_H */ 240 /* 241 * Local variables: 242 * mode: c++ 243 * End: 244 */ 245 /* vim:set et sw=2 ts=2: */ 246