27
27
#include "runtime/core/arithmetic_impl.h"
28
28
#include "runtime/numerics/NumericsImpl.h"
30
#include "runtime/collections/collections_impl.h"
31
30
#include "runtime/collections/collections.h"
32
#include "runtime/indexing/index_ddl.h"
34
32
#include "system/globalenv.h"
47
45
/*******************************************************************************
48
47
********************************************************************************/
50
rewriteSubsequenceCollection(static_context* aSctx,
52
std::vector<PlanIter_t>& aArgs,
53
bool aIsIntSubsequence)
48
bool rewriteSubsequenceCollection(
49
static_context* aSctx,
51
std::vector<PlanIter_t>& aArgs,
52
bool aIsIntSubsequence)
55
ZorbaCollectionIterator* collIter
56
= dynamic_cast<ZorbaCollectionIterator*>(aArgs[0].getp());
54
ZorbaCollectionIterator* collIter =
55
dynamic_cast<ZorbaCollectionIterator*>(aArgs[0].getp());
58
58
std::vector<PlanIter_t>& lCollectionArgs = collIter->getChildren();
60
60
SingletonIterator* lPosIter = dynamic_cast<SingletonIterator*>(aArgs[1].getp());
99
102
// simply move the (pos-1) of subsequence into the skip of
100
103
// collection function
101
104
// subsequence(collection(qname), 10, 20)
102
// -> subsequence(collection(qname, 10-1), 10, 20)
105
// -> subsequence(collection(qname, 10-1), 1, 20)
103
106
PlanIter_t& lNewCollSkipIter = aArgs[1];
104
PlanIter_t lOneIter = new SingletonIterator (aSctx, aLoc, lItemOne);
107
PlanIter_t lOneIter = new SingletonIterator(aSctx, aLoc, lItemOne);
105
109
lCollectionArgs.push_back(
106
new NumArithIterator<zorba::SubtractOperation>(
107
collIter->getStaticContext(), collIter->getLocation(),
108
lNewCollSkipIter, lOneIter)
110
new NumArithIterator<zorba::SubtractOperation>(aSctx,
111
collIter->getLocation(),
111
116
else if (lNumCollArgs <= 3 && lNumCollArgs != 0)
125
130
PlanIter_t& lOldCollSkipIter = lCollectionArgs[lSkipPosition];
126
131
PlanIter_t lOneIter = new SingletonIterator (aSctx, aLoc, lItemOne);
127
132
PlanIter_t& lSubseqPosIter = aArgs[1];
128
PlanIter_t lCollSkipAdditionIter
129
= new NumArithIterator<zorba::SubtractOperation>(
130
collIter->getStaticContext(), collIter->getLocation(),
131
lSubseqPosIter, lOneIter);
132
lCollectionArgs[lSkipPosition]
133
= new NumArithIterator<zorba::AddOperation>(
134
collIter->getStaticContext(), collIter->getLocation(),
135
lOldCollSkipIter, lCollSkipAdditionIter);
134
PlanIter_t lCollSkipAdditionIter =
135
new NumArithIterator<zorba::SubtractOperation>(aSctx,
136
collIter->getLocation(),
139
lCollectionArgs[lSkipPosition] =
140
new NumArithIterator<zorba::AddOperation>(aSctx,
141
collIter->getLocation(),
143
lCollSkipAdditionIter);
139
147
// no collection function with 0 or >3 params
142
aArgs[0] = new ZorbaCollectionIterator(collIter->getStaticContext(),
143
collIter->getLocation(), lCollectionArgs, collIter->isDynamic());
151
aArgs[0] = new ZorbaCollectionIterator(aSctx,
152
collIter->getLocation(),
154
collIter->isDynamic());
145
156
// after pushing the position param down we need to rewrite the actual
146
157
// position to 1:
147
158
// subsequence(collection(qname, 10+10-1), 10, 20)
148
159
// -> subsequence(collection(qname, 10+10-1), 1, 20)
149
aArgs[1] = new SingletonIterator (aSctx, aLoc, lItemOne);
160
aArgs[1] = new SingletonIterator(aSctx, aLoc, lItemOne);
539
550
xqtref_t fn_subsequence::getReturnType(const fo_expr* caller) const
541
552
TypeManager* tm = caller->get_type_manager();
542
xqtref_t list_type = caller->get_arg(0)->get_return_type();
553
xqtref_t argType = caller->get_arg(0)->get_return_type();
544
555
//When there is a length argument and it's 1 then we know we will return
545
556
//a value type T? where the input sequence was type T* or T+
546
557
if (caller->num_args() > 2 &&
547
558
caller->get_arg(2)->get_expr_kind() == const_expr_kind)
549
store::Item* len_item = static_cast<const_expr*>(caller->get_arg(2))->get_val();
560
store::Item* len = static_cast<const_expr*>(caller->get_arg(2))->get_val();
551
if (len_item->getDoubleValue().round().getNumber() == 1)
552
return tm->create_type(*list_type, TypeConstants::QUANT_QUESTION);
562
if (len->getDoubleValue().round().getNumber() == 1)
563
return tm->create_type(*argType, TypeConstants::QUANT_QUESTION);
554
return tm->create_type_x_quant(*list_type, TypeConstants::QUANT_QUESTION);
566
return tm->create_type_x_quant(*argType, TypeConstants::QUANT_QUESTION);
615
627
// we have rewritten the subsequence to start at the beginning.
616
628
// if there is no length param we can remove the entire
617
629
// subsequence function
618
// subsequence(collection(qname, 10),1)
619
// -> collection(qname, 10)
630
// subsequence(collection(qname, 10), 1) -> collection(qname, 10)
620
631
if (aArgs.size() == 2)
635
646
xqtref_t op_zorba_subsequence_int::getReturnType(const fo_expr* caller) const
637
648
TypeManager* tm = caller->get_type_manager();
638
xqtref_t list_type = caller->get_arg(0)->get_return_type();
649
xqtref_t argType = caller->get_arg(0)->get_return_type();
640
651
//When there is a length argument and it's 1 then we know we will return
641
652
//a value type T? where the input sequence was type T* or T+
642
653
if (caller->num_args() > 2 &&
643
654
caller->get_arg(2)->get_expr_kind() == const_expr_kind)
645
store::Item* len_item = static_cast<const_expr*>(caller->get_arg(2))->get_val();
656
store::Item* len = static_cast<const_expr*>(caller->get_arg(2))->get_val();
647
if (len_item->getIntegerValue() == Integer(1))
648
return tm->create_type(*list_type, TypeConstants::QUANT_QUESTION);
658
if (len->getIntegerValue() == Integer(1))
659
return tm->create_type(*argType, TypeConstants::QUANT_QUESTION);
651
return tm->create_type_x_quant(*list_type, TypeConstants::QUANT_QUESTION);
662
return tm->create_type_x_quant(*argType, TypeConstants::QUANT_QUESTION);
732
744
// we have rewritten the subsequence to start from the beginning.
733
745
// if there is no length param we can remove the entire
734
746
// subsequence function
735
// subsequence(collection(qname, 10),1)
736
// -> collection(qname, 10)
747
// subsequence(collection(qname, 10), 1) -> collection(qname, 10)
737
748
if (aArgs.size() == 2)
862
873
std::vector<PlanIter_t>& argv,
865
const std::type_info& counted_type = typeid(*argv[0]);
867
if (typeid(ZorbaCollectionIterator) == counted_type)
869
ZorbaCollectionIterator& collection =
870
static_cast<ZorbaCollectionIterator&>(*argv[0]);
872
if (collection.isCountOptimizable())
874
return new CountCollectionIterator(
877
collection.getChildren(),
879
collection.isDynamic()
880
? CountCollectionIterator::ZORBADYNAMIC
881
: CountCollectionIterator::ZORBASTATIC
886
else if (typeid(FnCollectionIterator) == counted_type)
888
FnCollectionIterator& collection =
889
static_cast<FnCollectionIterator&>(*argv[0]);
891
return new CountCollectionIterator(sctx,
893
collection.getChildren(),
894
CountCollectionIterator::W3C);
896
else if (typeid(ProbeIndexPointValueIterator) == counted_type)
898
ProbeIndexPointValueIterator& lIter
899
= static_cast<ProbeIndexPointValueIterator&>(*argv[0]);
901
return new ProbeIndexPointValueIterator(
902
sctx, loc, lIter.getChildren(), true, lIter.hasSkip());
904
else if (typeid(ProbeIndexRangeValueIterator) == counted_type)
906
ProbeIndexRangeValueIterator& lIter
907
= static_cast<ProbeIndexRangeValueIterator&>(*argv[0]);
909
return new ProbeIndexRangeValueIterator(
910
sctx, loc, lIter.getChildren(), true, lIter.hasSkip());
912
else if (typeid(ProbeIndexPointGeneralIterator) == counted_type)
914
ProbeIndexPointGeneralIterator& lIter
915
= static_cast<ProbeIndexPointGeneralIterator&>(*argv[0]);
917
return new ProbeIndexPointGeneralIterator(
918
sctx, loc, lIter.getChildren(), true);
920
else if (typeid(ProbeIndexRangeGeneralIterator) == counted_type)
922
ProbeIndexRangeGeneralIterator& lIter
923
= static_cast<ProbeIndexRangeGeneralIterator&>(*argv[0]);
925
return new ProbeIndexRangeGeneralIterator(
926
sctx, loc, lIter.getChildren(), true);
930
876
return new FnCountIterator(sctx, loc, argv);