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 "system/globalenv.h"
19
20 #include "compiler/expression/fo_expr.h"
21
22 #include "functions/func_booleans_impl.h"
23 #include "functions/function_impl.h"
24 #include "functions/library.h"
25
26 #include "runtime/booleans/BooleanImpl.h"
27 #include "runtime/booleans/booleans.h"
28 #include "runtime/core/item_iterator.h"
29
30 #include "store/api/item_factory.h"
31
32 #include "types/typeops.h"
33 #include "zorbamisc/ns_consts.h"
34
35
36 namespace zorba
37 {
38
39 /*******************************************************************************
40 Glass GenericOpComparison is the base class for both value and general
41 comparisons.
42 ********************************************************************************/
43 class GenericOpComparison : public function
44 {
45 public:
GenericOpComparison(const signature & sig,FunctionConsts::FunctionKind kind)46 GenericOpComparison(const signature& sig, FunctionConsts::FunctionKind kind)
47 :
48 function(sig, kind)
49 {
50 }
51
isComparisonFunction() const52 bool isComparisonFunction() const { return true; }
53
comparison_name() const54 virtual const char* comparison_name() const { return ""; }
55
toValueComp(static_context *) const56 virtual function* toValueComp(static_context *) const { return NULL; }
57
specializable() const58 virtual bool specializable() const { return true; }
59
60 function* specialize(
61 static_context* sctx,
62 const std::vector<xqtref_t>& argTypes) const;
63
ignoresSortedNodes(expr * fo,csize input) const64 BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const
65 {
66 return ANNOTATION_TRUE;
67 }
68
ignoresDuplicateNodes(expr * fo,csize input) const69 BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const
70 {
71 return ANNOTATION_TRUE;
72 }
73
codegen(CompilerCB * cb,static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv,expr & ann) const74 virtual PlanIter_t codegen(
75 CompilerCB* cb,
76 static_context* sctx,
77 const QueryLoc& loc,
78 std::vector<PlanIter_t>& argv,
79 expr &ann) const
80 {
81 return createIterator(sctx, loc, argv);
82 }
83
84 protected:
85 virtual PlanIter_t createIterator(
86 static_context* sctx,
87 const QueryLoc& loc,
88 std::vector<PlanIter_t>& ) const = 0;
89 };
90
91
92
specialize(static_context * sctx,const std::vector<xqtref_t> & argTypes) const93 function* GenericOpComparison::specialize(
94 static_context* sctx,
95 const std::vector<xqtref_t>& argTypes) const
96 {
97 const TypeManager* tm = sctx->get_typemanager();
98 xqtref_t t0 = argTypes[0];
99 xqtref_t t1 = argTypes[1];
100
101 if (! (TypeOps::is_builtin_atomic(tm, *t0) && TypeOps::is_builtin_atomic(tm, *t1)))
102 return NULL;
103
104 store::SchemaTypeCode tc0 = TypeOps::get_atomic_type_code(*t0);
105 store::SchemaTypeCode tc1 = TypeOps::get_atomic_type_code(*t1);
106
107 if (tc0 == store::XS_UNTYPED_ATOMIC ||
108 tc1 == store::XS_UNTYPED_ATOMIC ||
109 tc0 == store::XS_ANY_ATOMIC ||
110 tc1 == store::XS_ANY_ATOMIC)
111 return NULL;
112
113 return toValueComp(sctx);
114 }
115
116
117 /*******************************************************************************
118 class ValueOpComparison
119 ********************************************************************************/
120 class ValueOpComparison : public GenericOpComparison
121 {
122 public:
ValueOpComparison(const signature & sig,FunctionConsts::FunctionKind kind)123 ValueOpComparison(const signature& sig, FunctionConsts::FunctionKind kind)
124 :
125 GenericOpComparison(sig, kind)
126 {
127 }
128
isValueComparisonFunction() const129 bool isValueComparisonFunction() const { return true; }
130
131 xqtref_t getReturnType(const fo_expr* caller) const;
132
133 function* specialize(
134 static_context* sctx,
135 const std::vector<xqtref_t>& argTypes) const;
136 };
137
138
getReturnType(const fo_expr * caller) const139 xqtref_t ValueOpComparison::getReturnType(const fo_expr* caller) const
140 {
141 TypeManager* tm = caller->get_type_manager();
142 const QueryLoc& loc = caller->get_loc();
143
144 xqtref_t empty = GENV_TYPESYSTEM.EMPTY_TYPE;
145 TypeConstants::quantifier_t quant = TypeConstants::QUANT_ONE;
146
147 for (int i = 0; i < 2; i++)
148 {
149 if (TypeOps::is_equal(tm, *empty, *caller->get_arg(i)->get_return_type(), loc))
150 return empty;
151
152 TypeConstants::quantifier_t aq =
153 caller->get_arg(i)->get_return_type()->get_quantifier();
154
155 if (aq == TypeConstants::QUANT_QUESTION || aq == TypeConstants::QUANT_STAR)
156 {
157 quant = TypeConstants::QUANT_QUESTION;
158 }
159 }
160
161 return (quant == TypeConstants::QUANT_QUESTION ?
162 GENV_TYPESYSTEM.BOOLEAN_TYPE_QUESTION :
163 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE);
164 }
165
166
167 #define SPECIALIZE_VALUE_COMP_FUNCTION(kind, type) \
168 switch (kind) \
169 { \
170 case FunctionConsts::OP_VALUE_EQUAL_2: \
171 return GET_BUILTIN_FUNCTION(OP_VALUE_EQUAL_##type##_2); \
172 \
173 case FunctionConsts::OP_VALUE_NOT_EQUAL_2: \
174 return GET_BUILTIN_FUNCTION(OP_VALUE_NOT_EQUAL_##type##_2); \
175 \
176 case FunctionConsts::OP_VALUE_LESS_EQUAL_2: \
177 return GET_BUILTIN_FUNCTION(OP_VALUE_LESS_EQUAL_##type##_2); \
178 \
179 case FunctionConsts::OP_VALUE_LESS_2: \
180 return GET_BUILTIN_FUNCTION(OP_VALUE_LESS_##type##_2); \
181 \
182 case FunctionConsts::OP_VALUE_GREATER_EQUAL_2: \
183 return GET_BUILTIN_FUNCTION(OP_VALUE_GREATER_EQUAL_##type##_2); \
184 \
185 case FunctionConsts::OP_VALUE_GREATER_2: \
186 return GET_BUILTIN_FUNCTION(OP_VALUE_GREATER_##type##_2); \
187 \
188 default: \
189 ZORBA_ASSERT(false); \
190 }
191
192
specialize(static_context * sctx,const std::vector<xqtref_t> & argTypes) const193 function* ValueOpComparison::specialize(
194 static_context* sctx,
195 const std::vector<xqtref_t>& argTypes) const
196 {
197 const TypeManager* tm = sctx->get_typemanager();
198 xqtref_t t0 = argTypes[0];
199 xqtref_t t1 = argTypes[1];
200
201 if (TypeOps::is_builtin_simple(tm, *t0) && TypeOps::is_builtin_simple(tm, *t1))
202 {
203 store::SchemaTypeCode tc0 = TypeOps::get_atomic_type_code(*t0);
204 store::SchemaTypeCode tc1 = TypeOps::get_atomic_type_code(*t1);
205
206 if (tc0 == tc1)
207 {
208 switch(tc0)
209 {
210 case store::XS_DOUBLE:
211 SPECIALIZE_VALUE_COMP_FUNCTION(theKind, DOUBLE);
212
213 case store::XS_DECIMAL:
214 SPECIALIZE_VALUE_COMP_FUNCTION(theKind, DECIMAL);
215
216 case store::XS_FLOAT:
217 SPECIALIZE_VALUE_COMP_FUNCTION(theKind, FLOAT);
218
219 case store::XS_INTEGER:
220 SPECIALIZE_VALUE_COMP_FUNCTION(theKind, INTEGER);
221
222 case store::XS_STRING:
223 SPECIALIZE_VALUE_COMP_FUNCTION(theKind, STRING);
224
225 default:
226 return NULL;
227 }
228 }
229 }
230 return NULL;
231 }
232
233
234 /*******************************************************************************
235
236 Specific instances of ValueOpComparison. Specialization is based on both the
237 comparison kind (eq, gt, etc) and the type of the operands. One class is
238 created for each comparison kind, and another class foreach combination of
239 comparison kind and data type. For example:
240
241 class op_value_greater : SpecificValueComparison<CompareConsts::GREATER>
242
243 class op_value_greater_double : TypedValueComparison<CompareConsts::GREATER,
244 store::XS_DOUBLE>
245
246
247 ********************************************************************************/
248
249 template<enum CompareConsts::CompareType CC>
250 class SpecificValueComparison : public ValueOpComparison
251 {
252 public:
SpecificValueComparison(const signature & sig,FunctionConsts::FunctionKind kind)253 SpecificValueComparison(const signature& sig, FunctionConsts::FunctionKind kind)
254 :
255 ValueOpComparison(sig, kind)
256 {
257 }
258
createIterator(static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv) const259 virtual PlanIter_t createIterator(
260 static_context* sctx,
261 const QueryLoc& loc,
262 std::vector<PlanIter_t>& argv ) const
263 {
264 return new CompareIterator(sctx, loc, argv[0], argv[1], CC);
265 }
266 };
267
268
269 template<enum CompareConsts::CompareType CC, store::SchemaTypeCode t>
270 class TypedValueComparison : public SpecificValueComparison<CC>
271 {
272 public:
TypedValueComparison(const signature & sig,FunctionConsts::FunctionKind kind)273 TypedValueComparison(const signature& sig, FunctionConsts::FunctionKind kind)
274 :
275 SpecificValueComparison<CC>(sig, kind)
276 {
277 }
278
specializable() const279 bool specializable() const { return false; }
280
createIterator(static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv) const281 PlanIter_t createIterator(
282 static_context* sctx,
283 const QueryLoc& loc,
284 std::vector<PlanIter_t>& argv) const
285 {
286 return new TypedValueCompareIterator<t> (sctx, loc, argv, CC);
287 }
288 };
289
290
291 #define DECL_SPECIFIC_TYPED_OP( cc, op, t, xqt ) \
292 class op_value_##op##_##t : \
293 public TypedValueComparison<CompareConsts::VALUE_##cc, \
294 store::XS_##xqt> \
295 { \
296 public: \
297 op_value_##op##_##t(const signature& sig) \
298 : \
299 TypedValueComparison<CompareConsts::VALUE_##cc, \
300 store::XS_##xqt> \
301 (sig, FunctionConsts::OP_VALUE_##cc##_##xqt##_2) \
302 { \
303 } \
304 \
305 CompareConsts::CompareType comparisonKind() const \
306 { \
307 return CompareConsts::VALUE_##cc; \
308 } \
309 };
310
311
312 #define DECL_SPECIFIC_OPS(OP, op) \
313 class op_value_##op : \
314 public SpecificValueComparison<CompareConsts::VALUE_##OP> \
315 { \
316 public: \
317 op_value_##op(const signature& sig) \
318 : \
319 SpecificValueComparison<CompareConsts::VALUE_##OP> \
320 (sig, FunctionConsts::OP_VALUE_##OP##_2) \
321 { \
322 } \
323 \
324 CompareConsts::CompareType comparisonKind() const \
325 { \
326 return CompareConsts::VALUE_##OP; \
327 } \
328 }; \
329 \
330 DECL_SPECIFIC_TYPED_OP (OP, op, double, DOUBLE); \
331 DECL_SPECIFIC_TYPED_OP (OP, op, decimal, DECIMAL); \
332 DECL_SPECIFIC_TYPED_OP (OP, op, float, FLOAT); \
333 DECL_SPECIFIC_TYPED_OP (OP, op, integer, INTEGER); \
334 DECL_SPECIFIC_TYPED_OP (OP, op, string, STRING)
335
336
337 DECL_SPECIFIC_OPS (EQUAL, equal);
338 DECL_SPECIFIC_OPS (NOT_EQUAL, not_equal);
339 DECL_SPECIFIC_OPS (GREATER, greater);
340 DECL_SPECIFIC_OPS (LESS, less);
341 DECL_SPECIFIC_OPS (GREATER_EQUAL, greater_equal);
342 DECL_SPECIFIC_OPS (LESS_EQUAL, less_equal);
343
344 #undef DECL_ALL_SPECIFIC_OPS
345 #undef DECL_SPECIFIC_OP
346
347
348
349 /*******************************************************************************
350 class GeneralOpComparison
351 ********************************************************************************/
352 class GeneralOpComparison : public GenericOpComparison
353 {
354 public:
GeneralOpComparison(const signature & sig,FunctionConsts::FunctionKind kind)355 GeneralOpComparison(const signature& sig, FunctionConsts::FunctionKind kind)
356 :
357 GenericOpComparison(sig, kind)
358 {
359 }
360
isGeneralComparisonFunction() const361 bool isGeneralComparisonFunction() const { return true; }
362 };
363
364
365
366 /*******************************************************************************
367 Specific instances of GeneralOpComparison.
368 ********************************************************************************/
369 class op_equal : public GeneralOpComparison
370 {
371 public:
op_equal(const signature & sig)372 op_equal(const signature& sig)
373 :
374 GeneralOpComparison(sig, FunctionConsts::OP_EQUAL_2)
375 {
376 }
377
createIterator(static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv) const378 PlanIter_t createIterator(
379 static_context* sctx,
380 const QueryLoc& loc,
381 std::vector<PlanIter_t>& argv) const
382 {
383 return new CompareIterator(sctx,
384 loc,
385 argv[0],
386 argv[1],
387 CompareConsts::GENERAL_EQUAL);
388 }
389
toValueComp(static_context * sctx) const390 function* toValueComp(static_context* sctx) const
391 {
392 return GET_BUILTIN_FUNCTION(OP_VALUE_EQUAL_2);
393 }
394
comparisonKind() const395 CompareConsts::CompareType comparisonKind() const
396 {
397 return CompareConsts::GENERAL_EQUAL;
398 }
399 };
400
401
402 class op_not_equal : public GeneralOpComparison
403 {
404 public:
op_not_equal(const signature & sig)405 op_not_equal(const signature& sig)
406 :
407 GeneralOpComparison(sig, FunctionConsts::OP_NOT_EQUAL_2)
408 {
409 }
410
createIterator(static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv) const411 PlanIter_t createIterator(
412 static_context* sctx,
413 const QueryLoc& loc,
414 std::vector<PlanIter_t>& argv) const
415 {
416 return new CompareIterator(sctx,
417 loc,
418 argv[0],
419 argv[1],
420 CompareConsts::GENERAL_NOT_EQUAL);
421 }
422
comparisonKind() const423 CompareConsts::CompareType comparisonKind() const
424 {
425 return CompareConsts::GENERAL_NOT_EQUAL;
426 }
427
toValueComp(static_context * sctx) const428 function* toValueComp(static_context* sctx) const
429 {
430 return GET_BUILTIN_FUNCTION(OP_VALUE_NOT_EQUAL_2);
431 }
432 };
433
434
435 class op_less_equal : public GeneralOpComparison
436 {
437 public:
op_less_equal(const signature & sig)438 op_less_equal(const signature& sig)
439 :
440 GeneralOpComparison(sig, FunctionConsts::OP_LESS_EQUAL_2)
441 {
442 }
443
createIterator(static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv) const444 PlanIter_t createIterator(
445 static_context* sctx,
446 const QueryLoc& loc,
447 std::vector<PlanIter_t>& argv) const
448 {
449 return new CompareIterator(sctx,
450 loc,
451 argv[0],
452 argv[1],
453 CompareConsts::GENERAL_LESS_EQUAL);
454 }
455
comparisonKind() const456 CompareConsts::CompareType comparisonKind() const
457 {
458 return CompareConsts::GENERAL_LESS_EQUAL;
459 }
460
toValueComp(static_context * sctx) const461 function* toValueComp(static_context* sctx) const
462 {
463 return GET_BUILTIN_FUNCTION(OP_VALUE_LESS_EQUAL_2);
464 }
465 };
466
467
468 class op_less : public GeneralOpComparison
469 {
470 public:
op_less(const signature & sig)471 op_less(const signature& sig)
472 :
473 GeneralOpComparison(sig, FunctionConsts::OP_LESS_2)
474 {
475 }
476
createIterator(static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv) const477 PlanIter_t createIterator(
478 static_context* sctx,
479 const QueryLoc& loc,
480 std::vector<PlanIter_t>& argv) const
481 {
482 return new CompareIterator(sctx,
483 loc,
484 argv[0],
485 argv[1],
486 CompareConsts::GENERAL_LESS);
487 }
488
comparisonKind() const489 CompareConsts::CompareType comparisonKind() const
490 {
491 return CompareConsts::GENERAL_LESS;
492 }
493
toValueComp(static_context * sctx) const494 function* toValueComp(static_context* sctx) const
495 {
496 return GET_BUILTIN_FUNCTION(OP_VALUE_LESS_2);
497 }
498 };
499
500
501 class op_greater_equal : public GeneralOpComparison
502 {
503 public:
op_greater_equal(const signature & sig)504 op_greater_equal(const signature& sig)
505 :
506 GeneralOpComparison(sig, FunctionConsts::OP_GREATER_EQUAL_2)
507 {
508 }
509
createIterator(static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv) const510 PlanIter_t createIterator(
511 static_context* sctx,
512 const QueryLoc& loc,
513 std::vector<PlanIter_t>& argv) const
514 {
515 return new CompareIterator(sctx,
516 loc,
517 argv[0],
518 argv[1],
519 CompareConsts::GENERAL_GREATER_EQUAL);
520 }
521
comparisonKind() const522 CompareConsts::CompareType comparisonKind() const
523 {
524 return CompareConsts::GENERAL_GREATER_EQUAL;
525 }
526
toValueComp(static_context * sctx) const527 function* toValueComp(static_context* sctx) const
528 {
529 return GET_BUILTIN_FUNCTION(OP_VALUE_GREATER_EQUAL_2);
530 }
531 };
532
533
534 class op_greater : public GeneralOpComparison
535 {
536 public:
op_greater(const signature & sig)537 op_greater(const signature& sig)
538 :
539 GeneralOpComparison(sig, FunctionConsts::OP_GREATER_2)
540 {
541 }
542
createIterator(static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv) const543 PlanIter_t createIterator(
544 static_context* sctx,
545 const QueryLoc& loc,
546 std::vector<PlanIter_t>& argv) const
547 {
548 return new CompareIterator(sctx,
549 loc,
550 argv[0],
551 argv[1],
552 CompareConsts::GENERAL_GREATER);
553 }
554
comparisonKind() const555 CompareConsts::CompareType comparisonKind() const
556 {
557 return CompareConsts::GENERAL_GREATER;
558 }
559
toValueComp(static_context * sctx) const560 function* toValueComp(static_context* sctx) const
561 {
562 return GET_BUILTIN_FUNCTION(OP_VALUE_GREATER_2);
563 }
564 };
565
566
567 /*******************************************************************************
568 Atomic Values Equivalent comparing function
569
570 http://www.w3.org/TR/xquery-11/#dt-equivalence-two-atomic-values
571 ********************************************************************************/
572 class op_atomic_values_equivalent : public function
573 {
574 public:
op_atomic_values_equivalent(const signature & sig)575 op_atomic_values_equivalent(const signature& sig)
576 :
577 function(sig, FunctionConsts::OP_ATOMIC_VALUES_EQUIVALENT_2)
578 {
579 }
580
codegen(CompilerCB *,static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv,expr & ann) const581 PlanIter_t codegen(
582 CompilerCB* /*cb*/,
583 static_context* sctx,
584 const QueryLoc& loc,
585 std::vector<PlanIter_t>& argv,
586 expr& ann) const
587 {
588 return new AtomicValuesEquivalenceIterator(sctx, loc, argv[0], argv[1]);
589 }
590 };
591
592
593 /*******************************************************************************
594 Logic Operators (and/or)
595 ********************************************************************************/
596
597 class op_and : public function
598 {
599 public:
op_and(const signature & sig)600 op_and (const signature& sig)
601 :
602 function(sig, FunctionConsts::OP_AND_N)
603 {
604 }
605
mustCopyInputNodes(expr * fo,csize input) const606 bool mustCopyInputNodes(expr* fo, csize input) const
607 {
608 return false;
609 }
610
ignoresSortedNodes(expr * fo,csize input) const611 BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const
612 {
613 return ANNOTATION_TRUE;
614 }
615
ignoresDuplicateNodes(expr * fo,csize input) const616 BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const
617 {
618 return ANNOTATION_TRUE;
619 }
620
codegen(CompilerCB *,static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv,expr & ann) const621 PlanIter_t codegen(
622 CompilerCB* /*cb*/,
623 static_context* sctx,
624 const QueryLoc& loc,
625 std::vector<PlanIter_t>& argv,
626 expr& ann) const
627 {
628 assert(argv.size() > 0);
629 return new AndIterator(sctx, loc, argv);
630 }
631 };
632
633
634 class op_or : public function
635 {
636 public:
op_or(const signature & sig)637 op_or (const signature& sig)
638 :
639 function(sig, FunctionConsts::OP_OR_N)
640 {
641 }
642
mustCopyInputNodes(expr * fo,csize input) const643 bool mustCopyInputNodes(expr* fo, csize input) const
644 {
645 return false;
646 }
647
ignoresSortedNodes(expr * fo,csize input) const648 BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const
649 {
650 return ANNOTATION_TRUE;
651 }
652
ignoresDuplicateNodes(expr * fo,csize input) const653 BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const
654 {
655 return ANNOTATION_TRUE;
656 }
657
codegen(CompilerCB *,static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv,expr & ann) const658 PlanIter_t codegen(
659 CompilerCB* /*cb*/,
660 static_context* sctx,
661 const QueryLoc& loc,
662 std::vector<PlanIter_t>& argv,
663 expr& ann) const
664 {
665 assert(argv.size() > 0);
666 return new OrIterator(sctx, loc, argv);
667 }
668 };
669
670
671 /*******************************************************************************
672 9 Functions and Operators on Boolean Values
673
674 9.1.1 fn:true
675 9.1.2 fn:false
676 9.3.1 fn:not
677 ********************************************************************************/
678
679 class fn_true : public function
680 {
681 public:
fn_true(const signature & sig)682 fn_true(const signature& sig) : function(sig, FunctionConsts::FN_TRUE_0) {}
683
codegen(CompilerCB *,static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv,expr & ann) const684 PlanIter_t codegen(
685 CompilerCB* /*cb*/,
686 static_context* sctx,
687 const QueryLoc& loc,
688 std::vector<PlanIter_t>& argv,
689 expr& ann) const
690 {
691 store::Item_t res;
692 GENV_ITEMFACTORY->createBoolean(res, true);
693 return new SingletonIterator(sctx, loc, res);
694 }
695 };
696
697
698 /*******************************************************************************
699 fn:false
700 ********************************************************************************/
701 class fn_false : public function
702 {
703 public:
fn_false(const signature & sig)704 fn_false(const signature& sig) : function(sig, FunctionConsts::FN_FALSE_0) {}
705
codegen(CompilerCB *,static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv,expr & ann) const706 PlanIter_t codegen(
707 CompilerCB* /*cb*/,
708 static_context* sctx,
709 const QueryLoc& loc,
710 std::vector<PlanIter_t>& argv,
711 expr& ann) const
712 {
713 store::Item_t res;
714 GENV_ITEMFACTORY->createBoolean(res, false);
715 return new SingletonIterator(sctx, loc, res);
716 }
717 };
718
719
720 /*******************************************************************************
721 fn:not
722 ********************************************************************************/
723 class fn_not : public function
724 {
725 public:
fn_not(const signature & sig)726 fn_not(const signature& sig) : function(sig, FunctionConsts::FN_NOT_1) {}
727
mustCopyInputNodes(expr * fo,csize input) const728 bool mustCopyInputNodes(expr* fo, csize input) const
729 {
730 return false;
731 }
732
ignoresSortedNodes(expr * fo,csize input) const733 BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const
734 {
735 return ANNOTATION_TRUE;
736 }
737
ignoresDuplicateNodes(expr * fo,csize input) const738 BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const
739 {
740 return ANNOTATION_TRUE;
741 }
742
codegen(CompilerCB *,static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv,expr & ann) const743 PlanIter_t codegen(
744 CompilerCB* /*cb*/,
745 static_context* sctx,
746 const QueryLoc& loc,
747 std::vector<PlanIter_t>& argv,
748 expr& ann) const
749 {
750 return new FnBooleanIterator(sctx, loc, argv[0], true);
751 }
752
753 };
754
755
756 /*******************************************************************************
757 fn:boolean
758 ********************************************************************************/
759 class fn_boolean : public function
760 {
761 public:
fn_boolean(const signature & sig)762 fn_boolean(const signature& sig) : function(sig, FunctionConsts::FN_BOOLEAN_1)
763 {
764 }
765
mustCopyInputNodes(expr * fo,csize input) const766 bool mustCopyInputNodes(expr* fo, csize input) const
767 {
768 return false;
769 }
770
ignoresSortedNodes(expr * fo,csize input) const771 BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const
772 {
773 return ANNOTATION_TRUE;
774 }
775
ignoresDuplicateNodes(expr * fo,csize input) const776 BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const
777 {
778 return ANNOTATION_TRUE;
779 }
780
codegen(CompilerCB *,static_context * sctx,const QueryLoc & loc,std::vector<PlanIter_t> & argv,expr & ann) const781 PlanIter_t codegen(
782 CompilerCB* /*cb*/,
783 static_context* sctx,
784 const QueryLoc& loc,
785 std::vector<PlanIter_t>& argv,
786 expr& ann) const
787 {
788 return new FnBooleanIterator(sctx, loc, argv[0]);
789 }
790 };
791
792
793 /*******************************************************************************
794
795 ********************************************************************************/
populateContext_Comparison(static_context * sctx)796 void populateContext_Comparison(static_context* sctx)
797 {
798 const char* zorba_ns = static_context::ZORBA_OP_NS;
799
800 // General Comparison;
801 DECL(sctx, op_equal,
802 (createQName(zorba_ns, "", "equal"),
803 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
804 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
805 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
806
807 DECL(sctx, op_not_equal,
808 (createQName(zorba_ns, "", "not-equal"),
809 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
810 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
811 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
812
813 DECL(sctx, op_greater,
814 (createQName(zorba_ns, "", "greater"),
815 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
816 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
817 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
818
819 DECL(sctx, op_greater_equal,
820 (createQName(zorba_ns, "", "greater-equal"),
821 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
822 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
823 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
824
825 DECL(sctx, op_less,
826 (createQName(zorba_ns, "", "less"),
827 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
828 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
829 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
830
831 DECL(sctx, op_less_equal,
832 (createQName(zorba_ns, "", "less-equal"),
833 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
834 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
835 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
836
837 // Value Comparison
838
839 #define DECL_TYPED_VAL( sctx, op, name, type, xqt ) \
840 DECL(sctx, op_value_##op##_##type, \
841 (createQName (zorba_ns, "", "value-" name "-" #type), \
842 GENV_TYPESYSTEM.xqt##_TYPE_QUESTION, \
843 GENV_TYPESYSTEM.xqt##_TYPE_QUESTION, \
844 GENV_TYPESYSTEM.BOOLEAN_TYPE_QUESTION))
845
846 #define DECL_ALL_VAL( sctx, op, name ) \
847 DECL(sctx, op_value_##op, \
848 (createQName (zorba_ns, "", "value-" name), \
849 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_QUESTION, \
850 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_QUESTION, \
851 GENV_TYPESYSTEM.BOOLEAN_TYPE_QUESTION)); \
852 \
853 DECL_TYPED_VAL( sctx, op, name, double, DOUBLE ); \
854 DECL_TYPED_VAL( sctx, op, name, float, FLOAT ); \
855 DECL_TYPED_VAL( sctx, op, name, decimal, DECIMAL ); \
856 DECL_TYPED_VAL( sctx, op, name, integer, INTEGER ); \
857 DECL_TYPED_VAL( sctx, op, name, string, STRING )
858
859
860 DECL_ALL_VAL(sctx, equal, "equal");
861 DECL_ALL_VAL(sctx, not_equal, "not-equal");
862 DECL_ALL_VAL(sctx, less, "less");
863 DECL_ALL_VAL(sctx, greater, "greater");
864 DECL_ALL_VAL(sctx, less_equal, "less-equal");
865 DECL_ALL_VAL(sctx, greater_equal, "greater-equal");
866
867 #undef DECL_ALL_VAL
868 #undef DECL_TYPED_VAL
869
870 // Atomic Values Equivalent comparing function
871 // http://www.w3.org/TR/xquery-11/#dt-equivalence-two-atomic-values
872 DECL(sctx, op_atomic_values_equivalent,
873 (createQName(zorba_ns, "", "atomic-values-equivalent"),
874 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
875 GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR,
876 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
877
878 }
879
880
populate_context_booleans_impl(static_context * sctx)881 void populate_context_booleans_impl(static_context* sctx)
882 {
883 const char* xquery_op_ns = static_context::XQUERY_OP_NS;
884 const char* fn_ns = static_context::W3C_FN_NS;
885
886 // Boolean
887 DECL(sctx, fn_true,
888 (createQName(fn_ns, "", "true"),
889 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
890
891 DECL(sctx, fn_false,
892 (createQName(fn_ns, "", "false"),
893 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
894
895 DECL(sctx, fn_boolean,
896 (createQName(fn_ns, "", "boolean"),
897 GENV_TYPESYSTEM.ITEM_TYPE_STAR,
898 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
899
900 DECL(sctx, fn_not,
901 (createQName(fn_ns, "", "not"),
902 GENV_TYPESYSTEM.ITEM_TYPE_STAR,
903 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
904
905 // Logic
906 DECL(sctx, op_and,
907 (createQName(xquery_op_ns, "", "and"),
908 GENV_TYPESYSTEM.ITEM_TYPE_STAR,
909 true,
910 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
911
912 DECL(sctx, op_or,
913 (createQName(xquery_op_ns, "", "or"),
914 GENV_TYPESYSTEM.ITEM_TYPE_STAR,
915 true,
916 GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE));
917
918 }
919
920
921 }
922 /* vim:set et sw=2 ts=2: */
923