2
* Copyright 2006-2007 FLWOR Foundation.
3
* Authors: Tim Kraska, David Graf
6
#include "BooleanImpl.h"
7
#include "../types/casting.h"
8
#include "../runtime/zorba.h"
9
#include "../errors/Error.h"
10
#include "../functions/AccessorsImpl.h"
11
#include "../store/api/temp_seq.h"
16
/*______________________________________________________________________
19
| fn:boolean($arg as item()*) as xs:boolean
21
| Computes the effective boolean value of the sequence $arg.
22
|_______________________________________________________________________*/
23
FnBooleanIterator::FnBooleanIterator ( const yy::location& loc, Iterator_t& arg0, bool negate_arg )
25
Batcher<FnBooleanIterator> ( loc ), arg0_ ( arg0 ), negate ( negate_arg ) {}
27
FnBooleanIterator::~FnBooleanIterator() {}
30
FnBooleanIterator::_show ( std::ostream& os ) const
32
this->arg0_->show ( os );
37
FnBooleanIterator::effectiveBooleanValue ( const yy::location& loc, IteratorTreeStateBlock& stateBlock, Iterator_t& iter, bool negate )
43
// TODO produceNext must be replaced to allow batching
44
item = iter->produceNext(stateBlock);
48
// empty sequence => false
49
result = zorba::getZorbaForCurrentThread()->getItemFactory()->createBoolean ( negate ^ false );
51
else if ( item->isNode() )
54
result = zorba::getZorbaForCurrentThread()->getItemFactory()->createBoolean ( negate ^ true );
58
type = item->getType();
60
// TODO produceNext must be replaced to allow batching
61
( iter->produceNext(stateBlock) == NULL )
64
|| sequence_type::derives_from ( type, xs_string )
65
|| sequence_type::derives_from ( type, xs_anyURI )
66
|| sequence_type::derives_from ( type, xs_untypedAtomicValue )
67
|| sequence_type::isNumeric ( type )
71
// atomic type xs_boolean, xs_string, xs_anyURI, xs_untypedAtomic
72
// => effective boolean value is defined in the items
73
result = item->getEBV();
75
result = zorba::getZorbaForCurrentThread()->getItemFactory()->createBoolean ( negate ^ result->getBooleanValue() );
79
// else error => fn:boolean not defined
80
ZorbaErrorAlerts::error_alert (
81
error_messages::FORG0006_INVALID_ARGUMENT_TYPE,
82
error_messages::RUNTIME_ERROR,
85
"Wrong arguments in fn:boolean function!"
94
FnBooleanIterator::nextImpl(IteratorTreeStateBlock& stateBlock)
97
STACK_PUSH ( FnBooleanIterator::effectiveBooleanValue ( this->loc, stateBlock, this->arg0_, this->negate ) );
102
FnBooleanIterator::resetImpl(IteratorTreeStateBlock& stateBlock)
104
this->resetChild ( this->arg0_, stateBlock );
108
FnBooleanIterator::releaseResourcesImpl(IteratorTreeStateBlock& stateBlock)
110
this->releaseChildResources ( this->arg0_, stateBlock);
112
/* end class FnBooleanIterator */
114
/* begin class LogicIterator */
115
LogicIterator::LogicIterator ( const yy::location& loc, Iterator_t arg0, Iterator_t arg1, LogicType lt)
117
Batcher<LogicIterator> ( loc), iterLeft(arg0), iterRight(arg1), logicType(lt) {}
118
LogicIterator::~LogicIterator(){}
121
LogicIterator::nextImpl(IteratorTreeStateBlock& stateBlock)
126
switch(this->logicType)
129
bRes = FnBooleanIterator::effectiveBooleanValue(this->loc, stateBlock, this->iterLeft)->getBooleanValue()
130
&& FnBooleanIterator::effectiveBooleanValue(this->loc, stateBlock, this->iterRight)->getBooleanValue();
133
bRes = FnBooleanIterator::effectiveBooleanValue(this->loc, stateBlock, this->iterLeft)->getBooleanValue()
134
|| FnBooleanIterator::effectiveBooleanValue(this->loc, stateBlock, this->iterRight)->getBooleanValue();;
137
STACK_PUSH(zorba::getZorbaForCurrentThread()->getItemFactory()->createBoolean(bRes));
142
LogicIterator::resetImpl(IteratorTreeStateBlock& stateBlock)
144
this->resetChild( this->iterLeft, stateBlock );
145
this->resetChild( this->iterRight, stateBlock );
149
LogicIterator::releaseResourcesImpl(IteratorTreeStateBlock& stateBlock)
151
this->releaseChildResources( this->iterLeft, stateBlock );
152
this->releaseChildResources( this->iterRight, stateBlock );
154
/* end class LogicIterator */
156
/* begin class ComparisonIterator */
157
CompareIterator::CompareIterator ( const yy::location& loc, Iterator_t arg0, Iterator_t arg1, CompareType argCompType )
159
Batcher<CompareIterator> ( loc ), compareType(argCompType)
161
this->genericCast = new GenericCast();
162
this->iter0 = new FnDataIterator ( loc, arg0 );
163
this->iter1 = new FnDataIterator ( loc, arg1 );
166
CompareIterator::~CompareIterator()
168
delete this->genericCast;
172
CompareIterator::nextImpl(IteratorTreeStateBlock& stateBlock)
185
int32_t compareResult;
189
if (this->isGeneralComparison())
191
// TODO Optimizations for >, >=, < and <=
192
temp0 = zorba::getZorbaForCurrentThread()->getStore()->createTempSeq(this->iter0);
193
temp1 = zorba::getZorbaForCurrentThread()->getStore()->createTempSeq(this->iter1);
196
while (!found && temp0->containsItem(i0))
199
while (!found && temp1->containsItem(i1))
201
if (CompareIterator::generalComparison(temp0->getItem( i0 ), temp1->getItem( i1 )))
208
STACK_PUSH( zorba::getZorbaForCurrentThread()->getItemFactory()->createBoolean( found ) );
209
} /* if general comparison */
210
else if (this->isValueComparison())
212
if (( (item0 = this->consumeNext(this->iter0, stateBlock)) != NULL )
213
&& ((item1 = this->consumeNext(this->iter1, stateBlock))!=NULL))
215
STACK_PUSH( zorba::getZorbaForCurrentThread()->getItemFactory()->createBoolean( CompareIterator::valueComparison(item0, item1) ) );
216
if (this->consumeNext(this->iter0, stateBlock) != NULL || this->consumeNext(this->iter1, stateBlock) != NULL)
218
ZorbaErrorAlerts::error_alert (
219
error_messages::FOCH0004_Collation_does_not_support_collation_units,
220
error_messages::RUNTIME_ERROR,
223
"Value comparions must not be made with sequences with length greater 1!"
227
} /* if value comparison */
228
else if (this->isNodeComparison())
230
ZorbaErrorAlerts::error_alert (
231
error_messages::XQP0015_SYSTEM_NOT_YET_IMPLEMENTED,
232
error_messages::RUNTIME_ERROR,
235
"Node comparison is not yet implemented!"
237
} /* if node comparison */
243
CompareIterator::resetImpl(IteratorTreeStateBlock& stateBlock)
245
this->resetChild ( this->iter0, stateBlock );
246
this->resetChild ( this->iter1, stateBlock );
250
CompareIterator::releaseResourcesImpl(IteratorTreeStateBlock& stateBlock)
252
this->releaseChildResources ( this->iter0, stateBlock );
253
this->releaseChildResources ( this->iter1, stateBlock );
257
CompareIterator::isValueComparison()
260
switch(this->compareType)
263
case VALUE_NOT_EQUAL:
265
case VALUE_LESS_EQUAL:
267
case VALUE_GREATER_EQUAL:
278
CompareIterator::isGeneralComparison()
281
switch(this->compareType)
284
case GENERAL_NOT_EQUAL:
286
case GENERAL_LESS_EQUAL:
287
case GENERAL_GREATER:
288
case GENERAL_GREATER_EQUAL:
299
CompareIterator::isNodeComparison()
302
switch(this->compareType)
316
CompareIterator::generalComparison(Item_t item0, Item_t item1)
319
if (sequence_type::derives_from(item0->getType(), xs_untypedAtomicValue))
321
if (sequence_type::isNumeric(item1->getType()))
323
this->genericCast->setTarget(xs_double);
324
item0 = this->genericCast->cast(item0);
326
else if (sequence_type::derives_from(item1->getType(), xs_untypedAtomicValue)
327
|| sequence_type::derives_from(item1->getType(), xs_string))
329
this->genericCast->setTarget(xs_string);
330
item0 = this->genericCast->cast(item0);
334
this->genericCast->setTarget(item1->getType());
335
item0 = this->genericCast->cast(item0);
339
if (sequence_type::derives_from(item1->getType(), xs_untypedAtomicValue))
341
if (sequence_type::isNumeric(item0->getType()))
343
this->genericCast->setTarget(xs_double);
344
item1 = this->genericCast->cast(item1);
346
else if (sequence_type::derives_from(item0->getType(), xs_untypedAtomicValue)
347
|| sequence_type::derives_from(item0->getType(), xs_string))
349
this->genericCast->setTarget(xs_string);
350
item1 = this->genericCast->cast(item1);
354
this->genericCast->setTarget(item0->getType());
355
item1 = this->genericCast->cast(item1);
359
return CompareIterator::valueComparison(item0, item1);
360
} /* end CompareIterator::generalComparison (...) */
363
CompareIterator::valueComparison(Item_t item0, Item_t item1)
365
// all untyped Atomics to String
366
if (sequence_type::derives_from(item0->getType(), xs_untypedAtomicValue))
368
this->genericCast->setTarget(xs_string);
369
item0 = this->genericCast->cast(item0);
371
if (sequence_type::derives_from(item1->getType(), xs_untypedAtomicValue))
373
this->genericCast->setTarget(xs_string);
374
item1 = this->genericCast->cast(item1);
379
if (sequence_type::derives_from(item0->getType(), xs_float)) {
380
if (sequence_type::derives_from(item1->getType(), xs_decimal))
382
this->genericCast->setTarget(xs_float);
383
item1 = this->genericCast->cast(item1);
386
else if (sequence_type::derives_from(item0->getType(), xs_double))
388
if (sequence_type::derives_from(item1->getType(), xs_decimal))
390
this->genericCast->setTarget(xs_double);
391
item1 = this->genericCast->cast(item1);
393
else if (sequence_type::derives_from(item0->getType(), xs_float))
395
this->genericCast->setTarget(xs_double);
396
item1 = this->genericCast->cast(item1);
400
if (sequence_type::derives_from(item1->getType(), xs_float)) {
401
if (sequence_type::derives_from(item0->getType(), xs_decimal))
403
this->genericCast->setTarget(xs_float);
404
item0 = this->genericCast->cast(item0);
407
else if (sequence_type::derives_from(item1->getType(), xs_double))
409
if (sequence_type::derives_from(item0->getType(), xs_decimal))
411
this->genericCast->setTarget(xs_double);
412
item0 = this->genericCast->cast(item0);
414
else if (sequence_type::derives_from(item0->getType(), xs_float))
416
this->genericCast->setTarget(xs_double);
417
item0 = this->genericCast->cast(item0);
421
if (sequence_type::derives_from(item0->getType(), xs_string)
422
&& sequence_type::derives_from(item1->getType(), xs_anyURI))
424
this->genericCast->setTarget(xs_string);
425
item1 = this->genericCast->cast(item1);
427
if (sequence_type::derives_from(item1->getType(), xs_string)
428
&& sequence_type::derives_from(item0->getType(), xs_anyURI))
430
this->genericCast->setTarget(xs_string);
431
item0 = this->genericCast->cast(item0);
434
// computation of result
435
int32_t compValue = -2;
436
switch(this->compareType)
440
case VALUE_NOT_EQUAL:
441
case GENERAL_NOT_EQUAL:
442
compValue = CompareIterator::equal(item0, item1);
445
case GENERAL_GREATER:
446
case VALUE_GREATER_EQUAL:
447
case GENERAL_GREATER_EQUAL:
450
case VALUE_LESS_EQUAL:
451
case GENERAL_LESS_EQUAL:
452
compValue = CompareIterator::compare(item0, item1);
458
switch(this->compareType)
462
return compValue == 0;
464
case VALUE_NOT_EQUAL:
465
case GENERAL_NOT_EQUAL:
466
return compValue != 0;
469
case GENERAL_GREATER:
470
return compValue > 0;
472
case VALUE_GREATER_EQUAL:
473
case GENERAL_GREATER_EQUAL:
474
return compValue >= 0;
478
return compValue < 0;
480
case VALUE_LESS_EQUAL:
481
case GENERAL_LESS_EQUAL:
482
return compValue <= 0;
488
ZorbaErrorAlerts::error_alert (
489
error_messages::FOCH0004_Collation_does_not_support_collation_units,
490
error_messages::RUNTIME_ERROR,
493
"Compare of declared collation operator and operators is not possible!"
496
} /* end CompareIterator::valueComparison (...) */
499
CompareIterator::equal(const Item_t& item0, const Item_t& item1)
501
// tries first normal compare
502
int32_t compareRes = CompareIterator::compare(item0, item1);
505
else if (compareRes == -1 || compareRes == 1)
508
TypeCode type0 = item0->getType();
509
TypeCode type1 = item1->getType();
511
if (sequence_type::derives_from(type0, xs_boolean) && sequence_type::derives_from(type1, xs_boolean))
512
equal = item0->equals(item1);
524
CompareIterator::compare(const Item_t& item0, const Item_t& item1)
526
TypeCode type0 = item0->getType();
527
TypeCode type1 = item1->getType();
529
if (sequence_type::derives_from(type0, xs_float) && sequence_type::derives_from(type1, xs_float))
530
if ( item0->getFloatValue() < item1->getFloatValue())
532
else if ( item0->getFloatValue() == item1->getFloatValue())
536
else if (sequence_type::derives_from(type0, xs_double) && sequence_type::derives_from(type1, xs_double))
537
if ( item0->getDoubleValue() < item1->getDoubleValue())
539
else if ( item0->getDoubleValue() == item1->getDoubleValue())
543
else if (sequence_type::derives_from(type0, xs_decimal) && sequence_type::derives_from(type1, xs_decimal))
544
if ( item0->getDecimalValue() < item1->getDecimalValue())
546
else if ( item0->getDecimalValue() == item1->getDecimalValue())
550
else if (sequence_type::derives_from(type0, xs_string) && sequence_type::derives_from(type1, xs_string))
551
if ( item0->getStringValue() < item1->getStringValue())
553
else if ( item0->getStringValue() == item1->getStringValue())
557
// TODO comparisons for all types
561
/* end class ComparisonIterator */