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