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 #include "stdafx.h"
17 
18 #include <zorba/identtypes.h>
19 #include <zorba/typeident.h>
20 
21 #include "api/unmarshaller.h"
22 
23 #include "system/globalenv.h"
24 
25 #include "store/api/item.h"
26 
27 #include "types/typeops.h"
28 #include "types/typeimpl.h"
29 #include "types/node_test.h"
30 #include "types/root_typemanager.h"
31 #include "types/schema/schema.h"
32 
33 #include "diagnostics/assert.h"
34 
35 #include "diagnostics/xquery_diagnostics.h"
36 #include "diagnostics/util_macros.h"
37 
38 
39 namespace zorba {
40 
41 
42 
43 #define CHECK_IN_SCOPE(tm, type, loc)                                         \
44 {                                                                             \
45   const TypeManager* ttm = type.get_manager();                                \
46   if (ttm != tm && ttm != &GENV_TYPESYSTEM && !TypeOps::is_in_scope(tm,type)) \
47     RAISE_ERROR(err::XPTY0004, loc,                                           \
48     ERROR_PARAMS(ZED(BadType_23o), type, ZED(NotAmongInScopeSchemaTypes)));   \
49 }
50 
51 
52 /*******************************************************************************
53 
54 ********************************************************************************/
is_sub_quant(TypeConstants::quantifier_t q1,TypeConstants::quantifier_t q2)55 bool TypeOps::is_sub_quant(
56     TypeConstants::quantifier_t q1,
57     TypeConstants::quantifier_t q2)
58 {
59   return RootTypeManager::QUANT_SUBTYPE_MATRIX[q1][q2];
60 }
61 
62 
63 /*******************************************************************************
64 
65 ********************************************************************************/
intersect_quant(TypeConstants::quantifier_t q1,TypeConstants::quantifier_t q2)66 TypeConstants::quantifier_t TypeOps::intersect_quant(
67     TypeConstants::quantifier_t q1,
68     TypeConstants::quantifier_t q2)
69 {
70   return RootTypeManager::QUANT_INTERS_MATRIX [q1] [q2];
71 }
72 
73 
74 /*******************************************************************************
75 
76 ********************************************************************************/
union_quant(TypeConstants::quantifier_t q1,TypeConstants::quantifier_t q2)77 TypeConstants::quantifier_t TypeOps::union_quant(
78     TypeConstants::quantifier_t q1,
79     TypeConstants::quantifier_t q2)
80 {
81   return RootTypeManager::QUANT_UNION_MATRIX [q1] [q2];
82 }
83 
84 
85 /*******************************************************************************
86 
87 ********************************************************************************/
get_atomic_type_code(const XQType & type)88 store::SchemaTypeCode TypeOps::get_atomic_type_code(const XQType& type)
89 {
90   assert(type.type_kind() == XQType::ATOMIC_TYPE_KIND);
91   return (static_cast<const AtomicXQType&>(type)).get_type_code();
92 }
93 
94 
95 /*******************************************************************************
96 
97 ********************************************************************************/
is_in_scope(const TypeManager * tm,const XQType & type)98 bool TypeOps::is_in_scope(const TypeManager* tm, const XQType& type)
99 {
100   if (type.type_kind() == XQType::USER_DEFINED_KIND)
101   {
102     return (tm->create_named_type(type.get_qname(),
103                                   TypeConstants::QUANT_ONE,
104                                   QueryLoc::null) != NULL);
105   }
106   else if (type.type_kind() == XQType::NODE_TYPE_KIND)
107   {
108     const NodeXQType& ntype = static_cast<const NodeXQType&>(type);
109     xqtref_t ctype = ntype.get_content_type();
110 
111     if (ctype != NULL)
112     {
113       if (ntype.get_node_kind() == store::StoreConsts::documentNode)
114       {
115         assert(!ntype.is_schema_test());
116         return is_in_scope(tm, *ctype);
117       }
118       else if (tm->create_named_type(ctype->get_qname(),
119                                      TypeConstants::QUANT_ONE,
120                                      QueryLoc::null) == NULL)
121       {
122         return false;
123       }
124     }
125 
126     if (ntype.is_schema_test())
127     {
128       Schema* schema = tm->getSchema();
129 
130       if (schema == NULL)
131         return false;
132 
133 #ifndef ZORBA_NO_XMLSCHEMA
134       if (ntype.get_node_kind() == store::StoreConsts::elementNode)
135       {
136         return (schema->createXQTypeFromElementName(tm,
137                                                     ntype.get_node_name(),
138                                                     false,
139                                                     QueryLoc::null) != NULL);
140       }
141       else
142       {
143         return (schema->createXQTypeFromAttributeName(tm,
144                                                       ntype.get_node_name(),
145                                                       false,
146                                                       QueryLoc::null) != NULL);
147       }
148 #else
149       throw ZORBA_EXCEPTION(err::XQST0009);
150 #endif
151     }
152 
153     return true;
154   }
155   else if (type.type_kind() == XQType::FUNCTION_TYPE_KIND)
156   {
157     throw ZORBA_EXCEPTION(zerr::ZXQP0004_NOT_IMPLEMENTED,
158     ERROR_PARAMS(ZED(ZXQP0004_TypeOps_is_in_scope_ForFunctionItemTypes)));
159   }
160   else
161   {
162     return true;
163   }
164 }
165 
166 
167 /*******************************************************************************
168 
169 ********************************************************************************/
is_atomic(const TypeManager * tm,const XQType & type)170 bool TypeOps::is_atomic(const TypeManager* tm, const XQType& type)
171 {
172   CHECK_IN_SCOPE(tm, type, QueryLoc::null);
173 
174   if (type.get_quantifier() == TypeConstants::QUANT_ONE)
175   {
176     if (type.type_kind() == XQType::ATOMIC_TYPE_KIND)
177     {
178       return true;
179     }
180     else if (type.type_kind() == XQType::USER_DEFINED_KIND)
181     {
182       return reinterpret_cast<const UserDefinedXQType&>(type).isAtomic();
183     }
184   }
185 
186   return false;
187 }
188 
189 
190 /*******************************************************************************
191 
192 ********************************************************************************/
is_builtin_atomic(const TypeManager * tm,const XQType & type)193 bool TypeOps::is_builtin_atomic(const TypeManager* tm, const XQType& type)
194 {
195   CHECK_IN_SCOPE(tm, type, QueryLoc::null);
196 
197   return type.get_quantifier() == TypeConstants::QUANT_ONE &&
198          type.type_kind() == XQType::ATOMIC_TYPE_KIND;
199 }
200 
201 
202 /*******************************************************************************
203 
204 ********************************************************************************/
is_builtin_simple(const TypeManager * tm,const XQType & type)205 bool TypeOps::is_builtin_simple(const TypeManager* tm, const XQType& type)
206 {
207   CHECK_IN_SCOPE(tm, type, QueryLoc::null);
208 
209   return type.type_kind() == XQType::ATOMIC_TYPE_KIND;
210 }
211 
212 
213 /*******************************************************************************
214 
215 ********************************************************************************/
is_numeric(store::SchemaTypeCode type)216 bool TypeOps::is_numeric(store::SchemaTypeCode type)
217 {
218   return store::XS_FLOAT <= type && type <= store::XS_POSITIVE_INTEGER;
219 }
220 
221 
222 /*******************************************************************************
223 
224 ********************************************************************************/
is_numeric(const TypeManager * tm,const XQType & type)225 bool TypeOps::is_numeric(const TypeManager* tm, const XQType& type)
226 {
227   CHECK_IN_SCOPE(tm, type, QueryLoc::null);
228 
229   RootTypeManager& rtm = GENV_TYPESYSTEM;
230 
231   return (is_subtype(tm, type, *rtm.DOUBLE_TYPE_QUESTION) ||
232           is_subtype(tm, type, *rtm.FLOAT_TYPE_QUESTION) ||
233           is_subtype(tm, type, *rtm.DECIMAL_TYPE_QUESTION));
234 }
235 
236 
237 /*******************************************************************************
238 
239 ********************************************************************************/
is_numeric_or_untyped(const TypeManager * tm,const XQType & type)240 bool TypeOps::is_numeric_or_untyped(const TypeManager* tm, const XQType& type)
241 {
242   CHECK_IN_SCOPE(tm, type, QueryLoc::null);
243 
244   RootTypeManager& rtm = GENV_TYPESYSTEM;
245 
246   return (is_subtype(tm, type, *rtm.DOUBLE_TYPE_QUESTION) ||
247           is_subtype(tm, type, *rtm.FLOAT_TYPE_QUESTION) ||
248           is_subtype(tm, type, *rtm.DECIMAL_TYPE_QUESTION) ||
249           is_subtype(tm, type, *rtm.UNTYPED_ATOMIC_TYPE_QUESTION));
250 }
251 
252 
253 /*******************************************************************************
254 
255 ********************************************************************************/
maybe_date_time(const TypeManager * tm,const XQType & type)256 bool TypeOps::maybe_date_time(const TypeManager* tm, const XQType& type)
257 {
258   CHECK_IN_SCOPE(tm, type, QueryLoc::null);
259 
260   switch (type.type_kind())
261   {
262   case XQType::ATOMIC_TYPE_KIND:
263     switch (static_cast<const AtomicXQType &>(type).get_type_code())
264     {
265     case store::XS_ANY_ATOMIC:
266     case store::XS_DATE:
267     case store::XS_TIME:
268     case store::XS_DATETIME:
269     case store::XS_GYEAR_MONTH:
270     case store::XS_GYEAR:
271     case store::XS_GMONTH_DAY:
272     case store::XS_GDAY:
273     case store::XS_GMONTH:
274       return true;
275     default:
276       return false;
277     }
278     break;
279 
280   case XQType::ANY_TYPE_KIND:
281   case XQType::ANY_SIMPLE_TYPE_KIND:
282   case XQType::ITEM_KIND:
283     return true;
284 
285   case XQType::USER_DEFINED_KIND:
286     return true;  // TODO: finer analysis
287 
288   default:
289     // NODE, EMPTY, NONE, JSON, STRUCTURED_ITEM
290     return false;
291   }
292 }
293 
294 
295 /*******************************************************************************
296   For atomic, node, json, function and item types --> just set the quant to ONE
297 
298   none --> none
299 
300   empty -->  none
301 
302   xs:any --> item
303 
304   xs:untyped --> item
305 
306   xs:anySimple --> xs:anyAtomic
307 ********************************************************************************/
prime_type(const TypeManager * tm,const XQType & type)308 xqtref_t TypeOps::prime_type(const TypeManager* tm, const XQType& type)
309 {
310   CHECK_IN_SCOPE(tm, type, QueryLoc::null);
311 
312   switch (type.type_kind())
313   {
314   case XQType::EMPTY_KIND:
315     return GENV_TYPESYSTEM.NONE_TYPE;
316 
317   case XQType::ATOMIC_TYPE_KIND:
318   {
319     if (type.get_quantifier() == TypeConstants::QUANT_ONE)
320       return &type;
321 
322     const AtomicXQType& atype = static_cast<const AtomicXQType&>(type);
323     return tm->create_builtin_atomic_type(atype.get_type_code(),
324                                           TypeConstants::QUANT_ONE);
325   }
326 
327   case XQType::NONE_KIND:
328     return &type;
329 
330   case XQType::ITEM_KIND:
331     return GENV_TYPESYSTEM.ITEM_TYPE_ONE;
332 
333   case XQType::ANY_TYPE_KIND:
334   case XQType::UNTYPED_KIND:
335     return GENV_TYPESYSTEM.ITEM_TYPE_ONE;
336 
337   case XQType::ANY_SIMPLE_TYPE_KIND:
338     return GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_ONE;
339 
340   case XQType::ANY_FUNCTION_TYPE_KIND:
341     return GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_ONE;
342 
343   case XQType::FUNCTION_TYPE_KIND:
344   {
345     if (type.get_quantifier() == TypeConstants::QUANT_ONE)
346       return &type;
347 
348     const FunctionXQType& lType = static_cast<const FunctionXQType&>(type);
349     return tm->create_function_type(lType.get_param_types(),
350                                     lType.get_return_type(),
351                                     TypeConstants::QUANT_ONE);
352   }
353 
354   case XQType::STRUCTURED_ITEM_KIND:
355     return GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_ONE;
356 
357 #ifdef ZORBA_WITH_JSON
358   case XQType::JSON_TYPE_KIND:
359 #endif
360   case XQType::NODE_TYPE_KIND:
361 
362   {
363     if (type.get_quantifier() == TypeConstants::QUANT_ONE)
364       return &type;
365 
366     return tm->create_type(type, TypeConstants::QUANT_ONE);
367   }
368 
369   case XQType::USER_DEFINED_KIND:
370   {
371     if (type.get_quantifier() == TypeConstants::QUANT_ONE)
372       return &type;
373 
374     const UserDefinedXQType& udType = static_cast<const UserDefinedXQType&>(type);
375 
376     return tm->create_named_type(udType.get_qname(),
377                                  TypeConstants::QUANT_ONE,
378                                  QueryLoc::null,
379                                  err::XPTY0004);
380   }
381 
382   default:
383     ZORBA_ASSERT(false);
384     return NULL;
385   }
386 }
387 
388 
389 /*******************************************************************************
390   Returns true iff type1 is equal to type2 including the quantifier.
391 ********************************************************************************/
is_equal(const TypeManager * tm,const XQType & type1,const XQType & type2,const QueryLoc & loc)392 bool TypeOps::is_equal(
393     const TypeManager* tm,
394     const XQType& type1,
395     const XQType& type2,
396     const QueryLoc& loc)
397 {
398   CHECK_IN_SCOPE(tm, type1, loc);
399   CHECK_IN_SCOPE(tm, type2, loc);
400 
401   if (&type1 == &type2)
402     return true;
403 
404   if (type1.get_quantifier() != type2.get_quantifier())
405   {
406     return false;
407   }
408 
409   if (type1.type_kind() != type2.type_kind())
410   {
411     return false;
412   }
413 
414   switch(type1.type_kind())
415   {
416     case XQType::ATOMIC_TYPE_KIND:
417     {
418       const AtomicXQType& a1 = static_cast<const AtomicXQType&>(type1);
419       const AtomicXQType& a2 = static_cast<const AtomicXQType&>(type2);
420 
421       return a1.get_type_code() == a2.get_type_code();
422     }
423     case XQType::NODE_TYPE_KIND:
424     {
425       const NodeXQType& n1 = static_cast<const NodeXQType&>(type1);
426       const NodeXQType& n2 = static_cast<const NodeXQType&>(type2);
427 
428       return n1.is_equal(tm, n2);
429     }
430 #ifdef ZORBA_WITH_JSON
431     case XQType::JSON_TYPE_KIND:
432     {
433       const JSONXQType& j1 = static_cast<const JSONXQType&>(type1);
434       const JSONXQType& j2 = static_cast<const JSONXQType&>(type2);
435 
436       return j1.get_json_kind() == j2.get_json_kind();
437     }
438 #endif
439     case XQType::USER_DEFINED_KIND:
440     {
441       const UserDefinedXQType& udt1 = static_cast<const UserDefinedXQType&>(type1);
442       const UserDefinedXQType& udt2 = static_cast<const UserDefinedXQType&>(type2);
443 
444       return (udt1.getTypeCategory() == udt2.getTypeCategory() &&
445               udt1.get_qname()->equals(udt2.get_qname()));
446     }
447     default:
448       break;
449   }
450 
451   return true;
452 }
453 
454 
455 /*******************************************************************************
456   Returns true iff "subtype" is a subtype of "supertype".
457 ********************************************************************************/
is_subtype(store::SchemaTypeCode subtype,store::SchemaTypeCode supertype)458 bool TypeOps::is_subtype(
459     store::SchemaTypeCode subtype,
460     store::SchemaTypeCode supertype)
461 {
462   return RootTypeManager::ATOMIC_SUBTYPE_MATRIX[subtype][supertype];
463 }
464 
465 
466 /*******************************************************************************
467   Returns true iff "subtype" is a subtype of "supertype".
468 ********************************************************************************/
is_subtype(const TypeManager * tm,const XQType & subtype,const XQType & supertype,const QueryLoc & loc)469 bool TypeOps::is_subtype(
470     const TypeManager* tm,
471     const XQType& subtype,
472     const XQType& supertype,
473     const QueryLoc& loc)
474 {
475   CHECK_IN_SCOPE(tm, subtype, loc);
476   CHECK_IN_SCOPE(tm, supertype, loc);
477 
478   if (subtype.type_kind() == XQType::NONE_KIND)
479     return true;
480 
481   if (!RootTypeManager::QUANT_SUBTYPE_MATRIX[subtype.get_quantifier()]
482                                             [supertype.get_quantifier()])
483     return false;
484 
485   switch(supertype.type_kind())
486   {
487   case XQType::EMPTY_KIND:
488   {
489     switch(subtype.type_kind())
490     {
491     case XQType::EMPTY_KIND:
492       return true;
493 
494     default:
495       return false;
496     }
497     break;
498   }
499 
500   case XQType::NONE_KIND:
501   {
502     return false;
503   }
504 
505   case XQType::ITEM_KIND:
506   {
507     switch(subtype.type_kind())
508     {
509     case XQType::ATOMIC_TYPE_KIND:
510     case XQType::NODE_TYPE_KIND:
511     case XQType::ITEM_KIND:
512     case XQType::FUNCTION_TYPE_KIND:
513     case XQType::ANY_FUNCTION_TYPE_KIND:
514     case XQType::EMPTY_KIND:
515     case XQType::STRUCTURED_ITEM_KIND:
516 #ifdef ZORBA_WITH_JSON
517     case XQType::JSON_TYPE_KIND:
518 #endif
519       return true;
520 
521     case XQType::USER_DEFINED_KIND:
522     {
523       const UserDefinedXQType& udSubType =
524       static_cast<const UserDefinedXQType&>(subtype);
525 
526       // What about union of atomic types ????
527       return udSubType.isAtomic();
528     }
529 
530     default:
531       // ANY, ANY_SIMPLE, UNTYPED
532       return false;
533     }
534     break;
535   }
536 
537   case XQType::FUNCTION_TYPE_KIND:
538   {
539     switch (subtype.type_kind())
540     {
541     case XQType::ANY_FUNCTION_TYPE_KIND:
542     {
543       return false;
544     }
545 
546     case XQType::FUNCTION_TYPE_KIND:
547     {
548       const FunctionXQType& f1 = static_cast<const FunctionXQType&>(subtype);
549       const FunctionXQType& f2 = static_cast<const FunctionXQType&>(supertype);
550       return f1.is_subtype(tm, f2);
551     }
552     default:
553       return false;
554     }
555   }
556 
557   case XQType::ANY_FUNCTION_TYPE_KIND:
558   {
559     switch (subtype.type_kind())
560     {
561     case XQType::FUNCTION_TYPE_KIND:
562     case XQType::ANY_FUNCTION_TYPE_KIND:
563       return true;
564     default:
565       // any, untyped, node, atomic
566       return false;
567     }
568   }
569 
570   case XQType::ATOMIC_TYPE_KIND:
571   {
572     switch(subtype.type_kind())
573     {
574     case XQType::ATOMIC_TYPE_KIND:
575     {
576       const AtomicXQType& a1 = static_cast<const AtomicXQType&>(subtype);
577       const AtomicXQType& a2 = static_cast<const AtomicXQType&>(supertype);
578 
579       return RootTypeManager::ATOMIC_SUBTYPE_MATRIX[a1.get_type_code()][a2.get_type_code()];
580     }
581     case XQType::EMPTY_KIND:
582     {
583       return true;
584     }
585     case XQType::USER_DEFINED_KIND:
586     {
587       const UserDefinedXQType& udSubtype =
588       static_cast<const UserDefinedXQType&>(subtype);
589 
590       return udSubtype.isSubTypeOf(tm, supertype);
591     }
592     default:
593     {
594       // NODE, ITEM, STRUCTURED_ITEM, ANY, ANY_SIMPLE, FUNCTION, UNTYPED, JSON
595       return false;
596     }
597     }
598     break;
599   }
600 
601   case XQType::STRUCTURED_ITEM_KIND:
602   {
603     switch(subtype.type_kind())
604     {
605     case XQType::NODE_TYPE_KIND:
606     case XQType::EMPTY_KIND:
607     case XQType::STRUCTURED_ITEM_KIND:
608 #ifdef ZORBA_WITH_JSON
609     case XQType::JSON_TYPE_KIND:
610 #endif
611       return true;
612 
613     default:
614       // ITEM, ANY_FUNCTION, FUNCTION, ATOMIC, USER_DEFINED, ANY, ANY_SIMPLE, UNTYPED
615       return false;
616     }
617 
618     break;
619   }
620 
621 #ifdef ZORBA_WITH_JSON
622   case XQType::JSON_TYPE_KIND:
623   {
624     if (subtype.type_kind() != XQType::JSON_TYPE_KIND)
625       return false;
626 
627     const JSONXQType& sub = static_cast<const JSONXQType&>(subtype);
628     const JSONXQType& sup = static_cast<const JSONXQType&>(supertype);
629 
630     store::StoreConsts::JSONItemKind subKind = sub.get_json_kind();
631     store::StoreConsts::JSONItemKind supKind = sup.get_json_kind();
632 
633     switch (supKind)
634     {
635     case store::StoreConsts::jsonItem:
636       return true;
637 
638     case store::StoreConsts::jsonObject:
639     case store::StoreConsts::jsonArray:
640       return (subKind == supKind);
641 
642     default:
643       ZORBA_ASSERT(false);
644     }
645   }
646 #endif
647 
648   case XQType::NODE_TYPE_KIND:
649   {
650     switch(subtype.type_kind())
651     {
652     case XQType::NODE_TYPE_KIND:
653     {
654       const NodeXQType& n1 = static_cast<const NodeXQType&>(subtype);
655       const NodeXQType& n2 = static_cast<const NodeXQType&>(supertype);
656 
657       return n1.is_subtype(tm, n2, loc);
658     }
659     case XQType::EMPTY_KIND:
660     {
661       return true;
662     }
663     default:
664     {
665       // ATOMIC, ITEM, STRUCTURED_ITEM, ANY, ANY_SIMPLE, UNTYPED, FUNCTION,
666       // JSON, USER_DEFINED (???)
667       return false;
668     }
669     }
670     break;
671   }
672 
673   case XQType::ANY_TYPE_KIND:
674   {
675     switch(subtype.type_kind())
676     {
677     case XQType::ATOMIC_TYPE_KIND:
678     case XQType::ANY_TYPE_KIND:
679     case XQType::ANY_SIMPLE_TYPE_KIND:
680     case XQType::UNTYPED_KIND:
681     case XQType::EMPTY_KIND:
682     case XQType::USER_DEFINED_KIND:
683       return true;
684 
685     case XQType::NODE_TYPE_KIND:
686     case XQType::ITEM_KIND:
687 #ifdef ZORBA_WITH_JSON
688     case XQType::JSON_TYPE_KIND:
689 #endif
690     case XQType::STRUCTURED_ITEM_KIND:
691       return false;
692 
693     default:
694       ZORBA_ASSERT(false);
695     }
696     break;
697   }
698 
699   case XQType::ANY_SIMPLE_TYPE_KIND:
700   {
701     switch(subtype.type_kind())
702     {
703     case XQType::ATOMIC_TYPE_KIND:
704     case XQType::ANY_SIMPLE_TYPE_KIND:
705     case XQType::EMPTY_KIND:
706       return true;
707 
708     case XQType::USER_DEFINED_KIND:
709     {
710       const UserDefinedXQType& udSubType =
711       static_cast<const UserDefinedXQType&>(subtype);
712 
713       return (udSubType.isAtomic() || udSubType.isList() || udSubType.isUnion());
714     }
715 
716     default:
717       // ANY, UNTYPED, ITEM, NODE, JSON
718       return false;
719     }
720     break;
721   }
722 
723   case XQType::UNTYPED_KIND:
724   {
725     switch(subtype.type_kind())
726     {
727     case XQType::UNTYPED_KIND:
728       return true;
729 
730     default:
731       return false;
732     }
733     break;
734   }
735 
736   case XQType::USER_DEFINED_KIND:
737   {
738     const UserDefinedXQType& udSuperType =
739     static_cast<const UserDefinedXQType&>(supertype);
740 
741     return udSuperType.isSuperTypeOf(tm, subtype);
742   }
743 
744   default:
745     ZORBA_ASSERT(false);
746   }
747 
748   return false;
749 }
750 
751 
752 /*******************************************************************************
753   Returns true iff the type of "subitem" is a subtype of "supertype".
754 ********************************************************************************/
is_subtype(const TypeManager * tm,const store::Item * subitem,const XQType & supertype,const QueryLoc & loc)755 bool TypeOps::is_subtype(
756     const TypeManager* tm,
757     const store::Item* subitem,
758     const XQType& supertype,
759     const QueryLoc& loc)
760 {
761   CHECK_IN_SCOPE(tm, supertype, loc);
762 
763   switch(supertype.type_kind())
764   {
765   case XQType::EMPTY_KIND:
766   case XQType::NONE_KIND:
767   {
768     return false;
769   }
770 
771   case XQType::ITEM_KIND:
772   {
773     return true;
774     break;
775   }
776 
777   case XQType::FUNCTION_TYPE_KIND:
778   {
779     if (!subitem->isFunction())
780       return false;
781 
782     xqtref_t subtype = tm->create_value_type(subitem, loc);
783 
784     switch (subtype->type_kind())
785     {
786     case XQType::ANY_FUNCTION_TYPE_KIND:
787     case XQType::FUNCTION_TYPE_KIND:
788     {
789       const FunctionXQType& f1 = static_cast<const FunctionXQType&>(*subtype);
790       const FunctionXQType& f2 = static_cast<const FunctionXQType&>(supertype);
791       return f1.is_subtype(tm, f2);
792     }
793     default:
794       return false;
795     }
796   }
797 
798   case XQType::ANY_FUNCTION_TYPE_KIND:
799   {
800     if (subitem->isFunction())
801       return true;
802 
803     return false;
804   }
805 
806   case XQType::ATOMIC_TYPE_KIND:
807   {
808     if (!subitem->isAtomic())
809       return false;
810 
811     const AtomicXQType& a2 = static_cast<const AtomicXQType&>(supertype);
812 
813     if (a2.get_type_code() == store::XS_ANY_ATOMIC)
814       return true;
815 
816     xqtref_t subtype = tm->create_named_atomic_type(subitem->getType(),
817                                                     TypeConstants::QUANT_ONE,
818                                                     loc,
819                                                     err::XPTY0004);
820     switch(subtype->type_kind())
821     {
822     case XQType::ATOMIC_TYPE_KIND:
823     {
824       const AtomicXQType& a1 = static_cast<const AtomicXQType&>(*subtype);
825 
826       return RootTypeManager::ATOMIC_SUBTYPE_MATRIX[a1.get_type_code()]
827                                                    [a2.get_type_code()];
828     }
829     case XQType::USER_DEFINED_KIND:
830     {
831       const UserDefinedXQType& udSubtype =
832       static_cast<const UserDefinedXQType&>(*subtype);
833 
834       return udSubtype.isSubTypeOf(tm, supertype);
835     }
836     case XQType::EMPTY_KIND:
837     {
838       assert(false);
839       return true;
840     }
841     default:
842     {
843       // NODE, ITEM, ANY, ANY_SIMPLE, FUNCTION, UNTYPED, JSON
844       return false;
845     }
846     }
847     break;
848   }
849 
850   case XQType::STRUCTURED_ITEM_KIND:
851   {
852 #ifdef ZORBA_WITH_JSON
853     if (subitem->isJSONItem() || subitem->isNode())
854 #else
855     if (subitem->isNode())
856 #endif
857       return true;
858 
859     return false;
860   }
861 
862 #ifdef ZORBA_WITH_JSON
863   case XQType::JSON_TYPE_KIND:
864   {
865     if (!subitem->isJSONItem())
866       return false;
867 
868     const JSONXQType& sup = static_cast<const JSONXQType&>(supertype);
869 
870     store::StoreConsts::JSONItemKind subKind = subitem->getJSONItemKind();
871     store::StoreConsts::JSONItemKind supKind = sup.get_json_kind();
872 
873     switch (supKind)
874     {
875     case store::StoreConsts::jsonItem:
876       return true;
877 
878     case store::StoreConsts::jsonObject:
879     case store::StoreConsts::jsonArray:
880       return (subKind == supKind);
881 
882     default:
883       ZORBA_ASSERT(false);
884     }
885   }
886 #endif
887 
888   case XQType::NODE_TYPE_KIND:
889   {
890     if (!subitem->isNode())
891       return false;
892 
893     const NodeXQType& n2 = static_cast<const NodeXQType&>(supertype);
894 
895     return n2.is_supertype(tm, subitem, loc);
896 
897     break;
898   }
899 
900   case XQType::ANY_SIMPLE_TYPE_KIND:
901   {
902     if (!subitem->isAtomic())
903       return false;
904 
905     xqtref_t subtype = tm->create_named_atomic_type(subitem->getType(),
906                                                     TypeConstants::QUANT_ONE,
907                                                     loc,
908                                                     err::XPTY0004);
909     switch (subtype->type_kind())
910     {
911     case XQType::ATOMIC_TYPE_KIND:
912     case XQType::ANY_SIMPLE_TYPE_KIND:
913     case XQType::EMPTY_KIND:
914       return true;
915 
916     case XQType::USER_DEFINED_KIND:
917     {
918       const UserDefinedXQType& udSubType =
919       static_cast<const UserDefinedXQType&>(*subtype);
920 
921       return (udSubType.isAtomic() || udSubType.isList() || udSubType.isUnion());
922     }
923 
924     default:
925       // ANY, UNTYPED, ITEM, NODE
926       return false;
927     }
928     break;
929   }
930 
931   case XQType::UNTYPED_KIND:
932   case XQType::ANY_TYPE_KIND:
933   {
934     // We shouldn't be here because these are not a sequence types
935     ZORBA_ASSERT(false);
936 
937     if (!subitem->getType()->equals(GENV_TYPESYSTEM.XS_UNTYPED_QNAME))
938       return false;
939 
940     return true;
941   }
942 
943   case XQType::USER_DEFINED_KIND:
944   {
945     // The supertype must be a sequence type, and the only way that a user-
946     // defined type may be a sequence type, is if it is an atomic type.
947     if (!subitem->isAtomic())
948       return false;
949 
950     xqtref_t subtype = tm->create_named_atomic_type(subitem->getType(),
951                                                     TypeConstants::QUANT_ONE,
952                                                     loc,
953                                                     err::XPTY0004);
954     const UserDefinedXQType& udSuperType =
955     static_cast<const UserDefinedXQType&>(supertype);
956 
957     return udSuperType.isSuperTypeOf(tm, *subtype);
958   }
959 
960   default:
961     ZORBA_ASSERT(false);
962   }
963 
964   return false;
965 }
966 
967 
968 /*******************************************************************************
969 
970 ********************************************************************************/
is_treatable(const TypeManager * tm,const store::Item_t & item,const XQType & targetType,const QueryLoc & loc)971 bool TypeOps::is_treatable(
972     const TypeManager* tm,
973     const store::Item_t& item,
974     const XQType& targetType,
975     const QueryLoc& loc)
976 {
977   return is_subtype(tm, item.getp(), targetType, loc);
978 }
979 
980 
981 /*******************************************************************************
982   Returns the castability fron the source ItemType to the target ItemType. It
983   works only if both source and target types are builtin atomic types.
984   Otherwise, it returns NOT_CASTABLE.
985 ********************************************************************************/
castability(const XQType & src,const XQType & target)986 TypeConstants::castable_t TypeOps::castability(const XQType& src, const XQType& target)
987 {
988   if (src.type_kind() == XQType::ATOMIC_TYPE_KIND &&
989       target.type_kind() == XQType::ATOMIC_TYPE_KIND)
990   {
991     const AtomicXQType& aSrc = static_cast<const AtomicXQType&>(src);
992     const AtomicXQType& aTarget = static_cast<const AtomicXQType&>(target);
993 
994     return RootTypeManager::ATOMIC_CAST_MATRIX[aSrc.get_type_code()]
995                                               [aTarget.get_type_code()];
996   }
997 
998   // incorect should work for other than built-in types or at least rename it.
999   return TypeConstants::MAYBE_CASTABLE;
1000 }
1001 
1002 
1003 /*******************************************************************************
1004 
1005 ********************************************************************************/
union_type(const XQType & type1,const XQType & type2,const TypeManager * tm)1006 xqtref_t TypeOps::union_type(
1007     const XQType& type1,
1008     const XQType& type2,
1009     const TypeManager* tm)
1010 {
1011   RootTypeManager& rtm = GENV_TYPESYSTEM;
1012 
1013   XQType::TypeKind kind1 = type1.type_kind();
1014   XQType::TypeKind kind2 = type2.type_kind();
1015 
1016   ZORBA_ASSERT(kind1 != XQType::ANY_TYPE_KIND &&
1017                kind1 != XQType::ANY_SIMPLE_TYPE_KIND &&
1018                kind1 != XQType::UNTYPED_KIND);
1019 
1020   ZORBA_ASSERT(kind2 != XQType::ANY_TYPE_KIND &&
1021                kind2 != XQType::ANY_SIMPLE_TYPE_KIND &&
1022                kind2 != XQType::UNTYPED_KIND);
1023 
1024   if (is_subtype(tm, type1, type2))
1025     return &type2;
1026 
1027   else if (is_subtype(tm, type2, type1))
1028     return &type1;
1029 
1030   else if (type1.is_empty())
1031     return tm->create_type_x_quant(type2, TypeConstants::QUANT_QUESTION);
1032 
1033   else if (type2.is_empty())
1034     return tm->create_type_x_quant(type1, TypeConstants::QUANT_QUESTION);
1035 
1036   else if (type1.get_quantifier() == TypeConstants::QUANT_ONE &&
1037            type2.get_quantifier() == TypeConstants::QUANT_ONE)
1038   {
1039     if (kind1 == kind2)
1040     {
1041       switch (kind1)
1042       {
1043       case XQType::ATOMIC_TYPE_KIND:
1044         return rtm.ANY_ATOMIC_TYPE_ONE;
1045 
1046       case XQType::NODE_TYPE_KIND:
1047           return rtm.ANY_NODE_TYPE_ONE;
1048 
1049       case XQType::STRUCTURED_ITEM_KIND:
1050         return rtm.STRUCTURED_ITEM_TYPE_ONE;
1051 
1052 #ifdef ZORBA_WITH_JSON
1053       case XQType::JSON_TYPE_KIND:
1054         return rtm.JSON_ITEM_TYPE_ONE;
1055 #endif
1056       default:
1057         break;
1058       }
1059     }
1060     else if ((kind1 == XQType::NODE_TYPE_KIND ||
1061 #ifdef ZORBA_WITH_JSON
1062               kind1 == XQType::JSON_TYPE_KIND ||
1063 #endif
1064               kind1 == XQType::STRUCTURED_ITEM_KIND) &&
1065              (kind2 == XQType::NODE_TYPE_KIND ||
1066 #ifdef ZORBA_WITH_JSON
1067               kind2 == XQType::JSON_TYPE_KIND ||
1068 #endif
1069               kind2 == XQType::STRUCTURED_ITEM_KIND))
1070     {
1071       return rtm.STRUCTURED_ITEM_TYPE_ONE;
1072     }
1073 
1074     return GENV_TYPESYSTEM.ITEM_TYPE_ONE;
1075   }
1076   else
1077   {
1078     xqtref_t pt1 = prime_type(tm, type1);
1079     xqtref_t pt2 = prime_type(tm, type2);
1080 
1081     if (! is_equal(tm, type1, *pt1) || ! is_equal(tm, type2, *pt2))
1082     {
1083       TypeConstants::quantifier_t q1 = type1.get_quantifier();
1084       TypeConstants::quantifier_t q2 = type2.get_quantifier();
1085 
1086       TypeConstants::quantifier_t q12 = RootTypeManager::QUANT_UNION_MATRIX[q1][q2];
1087 
1088       // to be on the safe side
1089       q12 = RootTypeManager::QUANT_UNION_MATRIX[TypeConstants::QUANT_QUESTION][q12];
1090 
1091       return tm->create_type_x_quant(*union_type(*pt1, *pt2, tm), q12);
1092     }
1093     else
1094     {
1095       ZORBA_ASSERT(false);
1096       return GENV_TYPESYSTEM.ITEM_TYPE_STAR;
1097     }
1098   }
1099 }
1100 
1101 
1102 /*******************************************************************************
1103 
1104 ********************************************************************************/
intersect_type(const XQType & type1,const XQType & type2,const TypeManager * tm)1105 xqtref_t TypeOps::intersect_type(
1106     const XQType& type1,
1107     const XQType& type2,
1108     const TypeManager* tm)
1109 {
1110   RootTypeManager& rtm = GENV_TYPESYSTEM;
1111 
1112   XQType::TypeKind tk1 = type1.type_kind();
1113   XQType::TypeKind tk2 = type2.type_kind();
1114 
1115   ZORBA_ASSERT(tk1 != XQType::ANY_TYPE_KIND &&
1116                tk1 != XQType::ANY_SIMPLE_TYPE_KIND &&
1117                tk1 != XQType::UNTYPED_KIND);
1118 
1119   ZORBA_ASSERT(tk2 != XQType::ANY_TYPE_KIND &&
1120                tk2 != XQType::ANY_SIMPLE_TYPE_KIND &&
1121                tk2 != XQType::UNTYPED_KIND);
1122 
1123   if (is_subtype(tm, type1, type2))
1124     return &type1;
1125 
1126   if (is_subtype(tm, type2, type1))
1127     return &type2;
1128 
1129   TypeConstants::quantifier_t q1 = type1.get_quantifier();
1130   TypeConstants::quantifier_t q2 = type2.get_quantifier();
1131 
1132   if (tk1 == XQType::EMPTY_KIND)
1133     return (q2 == TypeConstants::QUANT_QUESTION || q2 == TypeConstants::QUANT_STAR ?
1134             rtm.EMPTY_TYPE :
1135             rtm.NONE_TYPE);
1136 
1137   if (tk2 == XQType::EMPTY_KIND)
1138     return (q1 == TypeConstants::QUANT_QUESTION || q1 == TypeConstants::QUANT_STAR ?
1139             rtm.EMPTY_TYPE :
1140             rtm.NONE_TYPE);
1141 
1142   if (q1 == TypeConstants::QUANT_ONE && q2 == TypeConstants::QUANT_ONE)
1143   {
1144     assert(tk1 != XQType::EMPTY_KIND &&
1145            tk1 != XQType::NONE_KIND &&
1146            tk1 != XQType::ITEM_KIND);
1147 
1148     assert(tk2 != XQType::EMPTY_KIND &&
1149            tk2 != XQType::NONE_KIND &&
1150            tk2 != XQType::ITEM_KIND);
1151 
1152     switch (tk1)
1153     {
1154     case XQType::ANY_FUNCTION_TYPE_KIND:
1155     {
1156       return rtm.NONE_TYPE;
1157     }
1158 
1159     case XQType::FUNCTION_TYPE_KIND:
1160     {
1161       return rtm.ANY_FUNCTION_TYPE_ONE;
1162     }
1163 
1164     case XQType::ATOMIC_TYPE_KIND:
1165     {
1166       return rtm.NONE_TYPE;
1167     }
1168 
1169     case XQType::NODE_TYPE_KIND:
1170     {
1171       return (tk2 != XQType::NODE_TYPE_KIND ?
1172               rtm.NONE_TYPE :
1173               rtm.ANY_NODE_TYPE_ONE); // ????
1174     }
1175 
1176     case XQType::STRUCTURED_ITEM_KIND:
1177     {
1178       return rtm.NONE_TYPE;
1179     }
1180 
1181 #ifdef ZORBA_WITH_JSON
1182     case XQType::JSON_TYPE_KIND:
1183     {
1184       return rtm.NONE_TYPE;
1185     }
1186 #endif
1187 
1188     default:
1189       break;
1190     }
1191 
1192     return rtm.ITEM_TYPE_ONE;
1193   }
1194   else
1195   {
1196     xqtref_t pt1 = prime_type(tm, type1);
1197     xqtref_t pt2 = prime_type(tm, type2);
1198 
1199     if (! is_equal(tm, type1, *pt1) || ! is_equal(tm, type2, *pt2))
1200     {
1201       xqtref_t pti = intersect_type(*pt1, *pt2, tm);
1202       return tm->create_type_x_quant(*pti,
1203                                      RootTypeManager::QUANT_INTERS_MATRIX[q1][q2]);
1204     }
1205     else
1206     {
1207       ZORBA_ASSERT(false);
1208       return rtm.ITEM_TYPE_STAR;
1209     }
1210   }
1211 }
1212 
1213 
1214 /*******************************************************************************
1215 
1216 ********************************************************************************/
arithmetic_type(const TypeManager * tm,const XQType & type1,const XQType & type2,bool division)1217 xqtref_t TypeOps::arithmetic_type(
1218     const TypeManager* tm,
1219     const XQType& type1,
1220     const XQType& type2,
1221     bool division)
1222 {
1223   if (type1.is_empty())
1224     return &type1;
1225 
1226   if (type2.is_empty())
1227     return &type2;
1228 
1229   RootTypeManager& rtm = GENV_TYPESYSTEM;
1230 
1231   xqtref_t resultType;
1232   TypeConstants::quantifier_t resultQuant = TypeConstants::QUANT_ONE;
1233 
1234   TypeConstants::quantifier_t quant1 = type1.get_quantifier();
1235   TypeConstants::quantifier_t quant2 = type2.get_quantifier();
1236 
1237   if (quant1 == TypeConstants::QUANT_QUESTION ||
1238       quant1 == TypeConstants::QUANT_STAR ||
1239       quant2 == TypeConstants::QUANT_QUESTION ||
1240       quant2 == TypeConstants::QUANT_STAR)
1241   {
1242     resultQuant = TypeConstants::QUANT_QUESTION;
1243   }
1244 
1245   if (division &&
1246       TypeOps::is_subtype(tm, type1, *rtm.INTEGER_TYPE_STAR) &&
1247       TypeOps::is_subtype(tm, type2, *rtm.INTEGER_TYPE_STAR))
1248   {
1249     return (resultQuant == TypeConstants::QUANT_ONE ?
1250             rtm.DECIMAL_TYPE_ONE : rtm.DECIMAL_TYPE_QUESTION);
1251   }
1252 
1253   if (TypeOps::is_subtype(tm, type1, *rtm.UNTYPED_ATOMIC_TYPE_STAR) ||
1254       TypeOps::is_subtype(tm, type2, *rtm.UNTYPED_ATOMIC_TYPE_STAR))
1255   {
1256     return (resultQuant == TypeConstants::QUANT_ONE ?
1257             rtm.DOUBLE_TYPE_ONE : rtm.DOUBLE_TYPE_QUESTION);
1258   }
1259 
1260   if (TypeOps::is_subtype(tm, type1, *rtm.DOUBLE_TYPE_STAR) ||
1261       TypeOps::is_subtype(tm, type2, *rtm.DOUBLE_TYPE_STAR))
1262   {
1263     return (resultQuant == TypeConstants::QUANT_ONE ?
1264             rtm.DOUBLE_TYPE_ONE : rtm.DOUBLE_TYPE_QUESTION);
1265   }
1266 
1267   if (TypeOps::is_subtype(tm, type1, *rtm.FLOAT_TYPE_STAR) ||
1268       TypeOps::is_subtype(tm, type2, *rtm.FLOAT_TYPE_STAR))
1269   {
1270     return (resultQuant == TypeConstants::QUANT_ONE ?
1271             rtm.FLOAT_TYPE_ONE : rtm.FLOAT_TYPE_QUESTION);
1272   }
1273 
1274   if (TypeOps::is_subtype(tm, type1, *rtm.INTEGER_TYPE_STAR) &&
1275       TypeOps::is_subtype(tm, type2, *rtm.INTEGER_TYPE_STAR))
1276   {
1277     return (resultQuant == TypeConstants::QUANT_ONE ?
1278             rtm.INTEGER_TYPE_ONE : rtm.INTEGER_TYPE_QUESTION);
1279   }
1280 
1281   if (TypeOps::is_subtype(tm, type1, *rtm.DECIMAL_TYPE_STAR) &&
1282       TypeOps::is_subtype(tm, type2, *rtm.DECIMAL_TYPE_STAR))
1283   {
1284     return (resultQuant == TypeConstants::QUANT_ONE ?
1285             rtm.DECIMAL_TYPE_ONE : rtm.DECIMAL_TYPE_QUESTION);
1286   }
1287 
1288   return rtm.ANY_ATOMIC_TYPE_QUESTION;
1289 }
1290 
1291 
1292 /*******************************************************************************
1293 
1294 ********************************************************************************/
get_typeident_quant(TypeConstants::quantifier_t quant)1295 static inline IdentTypes::quantifier_t get_typeident_quant(
1296     TypeConstants::quantifier_t quant)
1297 {
1298   switch(quant)
1299   {
1300   case TypeConstants::QUANT_ONE:
1301     return IdentTypes::QUANT_ONE;
1302 
1303   case TypeConstants::QUANT_QUESTION:
1304     return IdentTypes::QUANT_QUESTION;
1305 
1306   case TypeConstants::QUANT_STAR:
1307     return IdentTypes::QUANT_STAR;
1308 
1309   case TypeConstants::QUANT_PLUS:
1310     return IdentTypes::QUANT_PLUS;
1311 
1312   default:
1313     break;
1314   }
1315 
1316   return IdentTypes::QUANT_ONE;
1317 }
1318 
1319 
1320 /*******************************************************************************
1321 
1322 ********************************************************************************/
get_type_identifier(const TypeManager * tm,const XQType & type,bool nested)1323 TypeIdentifier_t TypeOps::get_type_identifier(
1324     const TypeManager* tm,
1325     const XQType& type,
1326     bool nested)
1327 {
1328   RootTypeManager& rtm = GENV_TYPESYSTEM;
1329 
1330   IdentTypes::quantifier_t q = get_typeident_quant(type.get_quantifier());
1331 
1332   switch(type.type_kind())
1333   {
1334   case XQType::EMPTY_KIND:
1335     return TypeIdentifier::createEmptyType();
1336 
1337   case XQType::ITEM_KIND:
1338     return TypeIdentifier::createItemType(q);
1339 
1340   case XQType::ATOMIC_TYPE_KIND:
1341   {
1342     const AtomicXQType& at = static_cast<const AtomicXQType&>(type);
1343     store::Item* qname = rtm.m_atomic_typecode_qname_map[at.get_type_code()];
1344 
1345     return TypeIdentifier::createNamedType(
1346         Unmarshaller::newString(qname->getNamespace()),
1347         Unmarshaller::newString(qname->getLocalName()),
1348         q);
1349   }
1350 
1351   case XQType::STRUCTURED_ITEM_KIND:
1352   {
1353     return TypeIdentifier::createStructuredItemType(q);
1354   }
1355 
1356 #ifdef ZORBA_WITH_JSON
1357   case XQType::JSON_TYPE_KIND:
1358   {
1359     const JSONXQType& t = static_cast<const JSONXQType&>(type);
1360 
1361     switch (t.get_json_kind())
1362     {
1363     case store::StoreConsts::jsonItem:
1364       return TypeIdentifier::createJSONItemType(q);
1365 
1366     case store::StoreConsts::jsonObject:
1367       return TypeIdentifier::createJSONObjectType(q);
1368 
1369     case store::StoreConsts::jsonArray:
1370       return TypeIdentifier::createJSONArrayType(q);
1371 
1372     default:
1373       ZORBA_ASSERT(false);
1374     }
1375   }
1376 #endif
1377 
1378   case XQType::NODE_TYPE_KIND:
1379   {
1380     const NodeXQType& nt = static_cast<const NodeXQType&>(type);
1381 
1382     const store::Item* nodeName = nt.get_node_name();
1383 
1384     TypeIdentifier_t content_type;
1385 
1386     if (nt.get_content_type() != NULL && !nt.is_schema_test())
1387       content_type = get_type_identifier(tm, *nt.get_content_type(), true);
1388 
1389     switch(nt.get_node_kind())
1390     {
1391     case store::StoreConsts::anyNode:
1392       return TypeIdentifier::createAnyNodeType(q);
1393 
1394     case store::StoreConsts::textNode:
1395       return TypeIdentifier::createTextType(q);
1396 
1397     case store::StoreConsts::piNode:
1398       return TypeIdentifier::createPIType(q);
1399 
1400     case store::StoreConsts::commentNode:
1401       return TypeIdentifier::createCommentType(q);
1402 
1403     case store::StoreConsts::documentNode:
1404       return TypeIdentifier::createDocumentType(content_type, q);
1405 
1406     case store::StoreConsts::elementNode:
1407     {
1408       if (nt.is_schema_test())
1409       {
1410         ZORBA_ASSERT(nodeName);
1411         String uri( Unmarshaller::newString( nodeName->getNamespace() ) );
1412         String local( Unmarshaller::newString( nodeName->getLocalName() ) );
1413 
1414         return TypeIdentifier::createSchemaElementType(uri, local, q);
1415       }
1416       else
1417       {
1418         String uri;
1419         String local;
1420         if (nodeName)
1421         {
1422           uri   = nodeName->getNamespace().c_str();
1423           local = nodeName->getLocalName().c_str();
1424         }
1425 
1426         return TypeIdentifier::createElementType(uri,
1427                                                  nodeName == NULL,
1428                                                  local,
1429                                                  nodeName == NULL,
1430                                                  content_type,
1431                                                  q);
1432       }
1433     }
1434     case store::StoreConsts::attributeNode:
1435     {
1436       if (nt.is_schema_test())
1437       {
1438         ZORBA_ASSERT(nodeName);
1439         String uri( Unmarshaller::newString( nodeName->getNamespace() ) );
1440         String local( Unmarshaller::newString( nodeName->getLocalName() ) );
1441 
1442         return TypeIdentifier::createSchemaAttributeType(uri, local, q);
1443       }
1444       else
1445       {
1446         String uri;
1447         String local;
1448         if (nodeName)
1449         {
1450           uri   = nodeName->getNamespace().c_str();
1451           local = nodeName->getLocalName().c_str();
1452         }
1453 
1454         return TypeIdentifier::createAttributeType(uri,
1455                                                    nodeName == NULL,
1456                                                    local,
1457                                                    nodeName == NULL,
1458                                                    content_type,
1459                                                    q);
1460       }
1461     }
1462     default:
1463       // cannot happen
1464       ZORBA_ASSERT(false);
1465       return NULL;
1466     }
1467   }
1468 
1469   case XQType::ANY_TYPE_KIND:
1470   {
1471     return TypeIdentifier::createNamedType(
1472       Unmarshaller::newString(rtm.XS_ANY_TYPE_QNAME->getNamespace()),
1473       Unmarshaller::newString(rtm.XS_ANY_TYPE_QNAME->getLocalName()),
1474       q);
1475   }
1476 
1477   case XQType::ANY_SIMPLE_TYPE_KIND:
1478     return TypeIdentifier::createNamedType(
1479       Unmarshaller::newString(rtm.XS_ANY_SIMPLE_TYPE_QNAME->getNamespace()),
1480       Unmarshaller::newString(rtm.XS_ANY_SIMPLE_TYPE_QNAME->getLocalName()),
1481       q);
1482 
1483   case XQType::UNTYPED_KIND:
1484     return TypeIdentifier::createNamedType(
1485       Unmarshaller::newString(rtm.XS_UNTYPED_QNAME->getNamespace()),
1486       Unmarshaller::newString(rtm.XS_UNTYPED_QNAME->getLocalName()),
1487       q);
1488 
1489   case XQType::USER_DEFINED_KIND:
1490   {
1491     ZORBA_ASSERT(nested || is_atomic(tm, type));
1492 
1493     store::Item* lQname = type.get_qname().getp();
1494 
1495     return TypeIdentifier::createNamedType(
1496       Unmarshaller::newString( lQname->getNamespace() ),
1497       Unmarshaller::newString( lQname->getLocalName() ),
1498       q
1499     );
1500   }
1501   default:
1502     break;
1503   }
1504 
1505   ZORBA_ASSERT(false);
1506   return NULL;
1507 }
1508 
1509 
1510 /*******************************************************************************
1511 
1512 ********************************************************************************/
serialize(std::ostream & os,const XQType & type)1513 std::ostream& TypeOps::serialize(std::ostream& os, const XQType& type)
1514 {
1515   return type.serialize_ostream(os);
1516 }
1517 
1518 
1519 /*******************************************************************************
1520 
1521 ********************************************************************************/
toString(const XQType & type)1522 std::string TypeOps::toString(const XQType& type)
1523 {
1524   std::ostringstream os;
1525   serialize(os, type);
1526   return os.str ();
1527 }
1528 
1529 
1530 /*******************************************************************************
1531 
1532 ********************************************************************************/
decode_quantifier(TypeConstants::quantifier_t quant)1533 const char* TypeOps::decode_quantifier(TypeConstants::quantifier_t quant)
1534 {
1535   switch (quant)
1536   {
1537   case TypeConstants::QUANT_ONE:
1538     return "";
1539   case TypeConstants::QUANT_QUESTION:
1540     return "?";
1541   case TypeConstants::QUANT_STAR:
1542     return "*";
1543   case TypeConstants::QUANT_PLUS:
1544       return "+";
1545   default:
1546     return "<unknown-quant>";
1547   }
1548 }
1549 
1550 } // namespace zorba
1551 /* vim:set et sw=2 ts=2: */
1552