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