~zorba-coders/zorba/bug1123016

« back to all changes in this revision

Viewing changes to src/functions/func_sequences_impl.cpp

  • Committer: Sorin Marian Nasoi
  • Date: 2013-04-09 11:44:43 UTC
  • mfrom: (11301.1.53 zorba)
  • Revision ID: spungi@gmail.com-20130409114443-89vz57gpyjzwoiok
Merged lp:zorba trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include "runtime/core/arithmetic_impl.h"
28
28
#include "runtime/numerics/NumericsImpl.h"
29
29
 
30
 
#include "runtime/collections/collections_impl.h"
31
30
#include "runtime/collections/collections.h"
32
 
#include "runtime/indexing/index_ddl.h"
33
31
 
34
32
#include "system/globalenv.h"
35
33
 
45
43
 
46
44
 
47
45
/*******************************************************************************
 
46
 
48
47
********************************************************************************/
49
 
bool
50
 
rewriteSubsequenceCollection(static_context* aSctx,
51
 
                             const QueryLoc& aLoc,
52
 
                             std::vector<PlanIter_t>& aArgs,
53
 
                             bool aIsIntSubsequence)
 
48
bool rewriteSubsequenceCollection(
 
49
    static_context* aSctx,
 
50
    const QueryLoc& aLoc,
 
51
    std::vector<PlanIter_t>& aArgs,
 
52
    bool aIsIntSubsequence)
54
53
{
55
 
  ZorbaCollectionIterator* collIter 
56
 
    = dynamic_cast<ZorbaCollectionIterator*>(aArgs[0].getp());
 
54
  ZorbaCollectionIterator* collIter = 
 
55
  dynamic_cast<ZorbaCollectionIterator*>(aArgs[0].getp());
57
56
  assert(collIter);
 
57
 
58
58
  std::vector<PlanIter_t>& lCollectionArgs = collIter->getChildren();
59
59
 
60
60
  SingletonIterator* lPosIter = dynamic_cast<SingletonIterator*>(aArgs[1].getp());
62
62
  {
63
63
    return false;
64
64
  }
 
65
 
65
66
  xs_long pos;
66
67
  const store::Item_t& lPosItem = lPosIter->getValue();
 
68
 
67
69
  try
68
70
  {
69
71
    if (aIsIntSubsequence)
81
83
  {
82
84
    return false;
83
85
  }
 
86
 
84
87
  if (pos <= 1)
85
88
  {
86
89
    // if the start position is less than 1 we can't push this down into
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);
 
108
 
105
109
    lCollectionArgs.push_back(
106
 
        new NumArithIterator<zorba::SubtractOperation>(
107
 
          collIter->getStaticContext(), collIter->getLocation(),
108
 
          lNewCollSkipIter, lOneIter)
109
 
        );
 
110
      new NumArithIterator<zorba::SubtractOperation>(aSctx,
 
111
                                                     collIter->getLocation(),
 
112
                                                     lNewCollSkipIter,
 
113
                                                     lOneIter)
 
114
                              );
110
115
  }
111
116
  else if (lNumCollArgs <= 3 && lNumCollArgs != 0)
112
117
  {
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);
 
133
 
 
134
    PlanIter_t lCollSkipAdditionIter = 
 
135
    new NumArithIterator<zorba::SubtractOperation>(aSctx,
 
136
                                                   collIter->getLocation(),
 
137
                                                   lSubseqPosIter,
 
138
                                                   lOneIter);
 
139
    lCollectionArgs[lSkipPosition] = 
 
140
    new NumArithIterator<zorba::AddOperation>(aSctx,
 
141
                                              collIter->getLocation(), 
 
142
                                              lOldCollSkipIter,
 
143
                                              lCollSkipAdditionIter);
136
144
  }
137
145
  else
138
146
  {
139
147
    // no collection function with 0 or >3 params
140
148
    assert(false);
141
149
  }
142
 
  aArgs[0] = new ZorbaCollectionIterator(collIter->getStaticContext(),
143
 
      collIter->getLocation(), lCollectionArgs, collIter->isDynamic());
 
150
 
 
151
  aArgs[0] = new ZorbaCollectionIterator(aSctx,
 
152
                                         collIter->getLocation(),
 
153
                                         lCollectionArgs,
 
154
                                         collIter->isDynamic());
144
155
 
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);
150
161
 
151
162
  return true;
152
163
}
539
550
xqtref_t fn_subsequence::getReturnType(const fo_expr* caller) const
540
551
{
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();
543
554
 
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)
548
559
  {
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();
550
561
 
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);
553
564
  }
554
 
  return tm->create_type_x_quant(*list_type, TypeConstants::QUANT_QUESTION);
 
565
 
 
566
  return tm->create_type_x_quant(*argType, TypeConstants::QUANT_QUESTION);
555
567
}
556
568
 
557
569
 
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)
621
632
      {
622
633
        return aArgs[0];
635
646
xqtref_t op_zorba_subsequence_int::getReturnType(const fo_expr* caller) const
636
647
{
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();
639
650
 
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)
644
655
  {
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();
646
657
 
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);
649
660
  }
650
661
 
651
 
  return tm->create_type_x_quant(*list_type, TypeConstants::QUANT_QUESTION);
 
662
  return tm->create_type_x_quant(*argType, TypeConstants::QUANT_QUESTION);
652
663
}
653
664
 
654
665
 
660
671
    expr& aAnn) const
661
672
{
662
673
  const std::type_info& lFirstArgType = typeid(*aArgs[0]);
 
674
 
663
675
  fo_expr& subseqExpr = static_cast<fo_expr&>(aAnn);
664
676
  const expr* inputExpr = subseqExpr.get_arg(0);
665
677
  const expr* posExpr = subseqExpr.get_arg(1);
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)
738
749
      {
739
750
        return aArgs[0];
862
873
  std::vector<PlanIter_t>& argv,
863
874
  expr& ann) const
864
875
{
865
 
  const std::type_info& counted_type = typeid(*argv[0]);
866
 
 
867
 
  if (typeid(ZorbaCollectionIterator) == counted_type)
868
 
  {
869
 
    ZorbaCollectionIterator& collection =
870
 
    static_cast<ZorbaCollectionIterator&>(*argv[0]);
871
 
 
872
 
    if (collection.isCountOptimizable())
873
 
    {
874
 
      return new CountCollectionIterator(
875
 
                   sctx,
876
 
                   loc,
877
 
                   collection.getChildren(),
878
 
                   (
879
 
                     collection.isDynamic()
880
 
                       ? CountCollectionIterator::ZORBADYNAMIC
881
 
                       : CountCollectionIterator::ZORBASTATIC
882
 
                   )
883
 
                 );
884
 
    }
885
 
  }
886
 
  else if (typeid(FnCollectionIterator) == counted_type)
887
 
  {
888
 
    FnCollectionIterator& collection =
889
 
    static_cast<FnCollectionIterator&>(*argv[0]);
890
 
 
891
 
    return new CountCollectionIterator(sctx,
892
 
                                       loc,
893
 
                                       collection.getChildren(),
894
 
                                       CountCollectionIterator::W3C);
895
 
  }
896
 
  else if (typeid(ProbeIndexPointValueIterator) == counted_type)
897
 
  {
898
 
    ProbeIndexPointValueIterator& lIter
899
 
      = static_cast<ProbeIndexPointValueIterator&>(*argv[0]);
900
 
 
901
 
    return new ProbeIndexPointValueIterator(
902
 
        sctx, loc, lIter.getChildren(), true, lIter.hasSkip());
903
 
  }
904
 
  else if (typeid(ProbeIndexRangeValueIterator) == counted_type)
905
 
  {
906
 
    ProbeIndexRangeValueIterator& lIter
907
 
      = static_cast<ProbeIndexRangeValueIterator&>(*argv[0]);
908
 
 
909
 
    return new ProbeIndexRangeValueIterator(
910
 
        sctx, loc, lIter.getChildren(), true, lIter.hasSkip());
911
 
  }
912
 
  else if (typeid(ProbeIndexPointGeneralIterator) == counted_type)
913
 
  {
914
 
    ProbeIndexPointGeneralIterator& lIter
915
 
      = static_cast<ProbeIndexPointGeneralIterator&>(*argv[0]);
916
 
 
917
 
    return new ProbeIndexPointGeneralIterator(
918
 
        sctx, loc, lIter.getChildren(), true);
919
 
  }
920
 
  else if (typeid(ProbeIndexRangeGeneralIterator) == counted_type)
921
 
  {
922
 
    ProbeIndexRangeGeneralIterator& lIter
923
 
      = static_cast<ProbeIndexRangeGeneralIterator&>(*argv[0]);
924
 
 
925
 
    return new ProbeIndexRangeGeneralIterator(
926
 
        sctx, loc, lIter.getChildren(), true);
927
 
  }
928
 
  
929
 
  // fallback
930
876
  return new FnCountIterator(sctx, loc, argv);
931
877
}
932
878