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