zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #17303
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
Dennis Knochenwefel has proposed merging lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba.
Commit message:
subsequence rewrite if source sequence is coming from db:collection() function (pushing start position into collection skip).
Requested reviews:
Matthias Brantner (matthias-brantner)
For more details, see:
https://code.launchpad.net/~dennis-knochenwefel/zorba/dennis-misc/+merge/144373
subsequence rewrite if first parameter is db:collection() function.
--
https://code.launchpad.net/~dennis-knochenwefel/zorba/dennis-misc/+merge/144373
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/functions/func_sequences_impl.cpp'
--- src/functions/func_sequences_impl.cpp 2012-10-24 11:32:56 +0000
+++ src/functions/func_sequences_impl.cpp 2013-01-22 18:54:32 +0000
@@ -23,6 +23,9 @@
#include "runtime/sequences/sequences.h"
#include "runtime/sequences/SequencesImpl.h"
#include "runtime/core/var_iterators.h"
+#include "runtime/core/item_iterator.h"
+#include "runtime/core/arithmetic_impl.h"
+#include "runtime/numerics/NumericsImpl.h"
#include "runtime/collections/collections_impl.h"
#include "runtime/collections/collections.h"
@@ -42,7 +45,114 @@
/*******************************************************************************
-
+********************************************************************************/
+bool
+rewriteSubsequenceCollection(static_context* aSctx,
+ const QueryLoc& aLoc,
+ std::vector<PlanIter_t>& aArgs,
+ bool aIsIntSubsequence)
+{
+ ZorbaCollectionIterator* collIter
+ = dynamic_cast<ZorbaCollectionIterator*>(aArgs[0].getp());
+ assert(collIter);
+ std::vector<PlanIter_t>& lCollectionArgs = collIter->getChildren();
+
+ SingletonIterator* lPosIter = dynamic_cast<SingletonIterator*>(aArgs[1].getp());
+ if (lPosIter == NULL)
+ {
+ return false;
+ }
+ xs_long pos;
+ const store::Item_t& lPosItem = lPosIter->getValue();
+ try
+ {
+ if (aIsIntSubsequence)
+ {
+ pos = lPosItem->getLongValue();
+ }
+ else
+ {
+ xs_double dpos = lPosItem->getDoubleValue().round();
+ xs_integer ipos(dpos.getNumber());
+ pos = to_xs_long(ipos);
+ }
+ }
+ catch (std::range_error&)
+ {
+ return false;
+ }
+ if (pos <= 1)
+ {
+ // if the start position is less than 1 we can't push this down into
+ // the collection skip parameter because the result won't be equivalent.
+ return false;
+ }
+
+ // prepare helper
+ store::Item_t lItemOne;
+ GENV_ITEMFACTORY->createInteger(lItemOne, Integer(1));
+
+ int lNumCollArgs = lCollectionArgs.size();
+ if (lNumCollArgs == 1)
+ {
+ // argument is of type collection(qname)
+ // simply move the (pos-1) of subsequence into the skip of
+ // collection function
+ // subsequence(collection(qname), 10, 20)
+ // -> subsequence(collection(qname, 10-1), 10, 20)
+ PlanIter_t& lNewCollSkipIter = aArgs[1];
+ PlanIter_t lOneIter = new SingletonIterator (aSctx, aLoc, lItemOne);
+ lCollectionArgs.push_back(
+ new NumArithIterator<zorba::SubtractOperation>(
+ collIter->getStaticContext(), collIter->getLocation(),
+ lNewCollSkipIter, lOneIter)
+ );
+ }
+ else if (lNumCollArgs <= 3 && lNumCollArgs != 0)
+ {
+ // argument is of type collection(qname,skip) or
+ // collection(qname,start_uri,skip)
+ int lSkipPosition = 1;
+ if (lNumCollArgs == 3)
+ {
+ // collection function with start reference -> skip is the 3rd param
+ lSkipPosition = 2;
+ }
+
+ // add position-1 of subsequence to collection skip
+ // subsequence(collection(qname, 10), 10, 20)
+ // -> subsequence(collection(qname, 10+10-1), 10, 20)
+ PlanIter_t& lOldCollSkipIter = lCollectionArgs[lSkipPosition];
+ PlanIter_t lOneIter = new SingletonIterator (aSctx, aLoc, lItemOne);
+ PlanIter_t& lSubseqPosIter = aArgs[1];
+ PlanIter_t lCollSkipAdditionIter
+ = new NumArithIterator<zorba::SubtractOperation>(
+ collIter->getStaticContext(), collIter->getLocation(),
+ lSubseqPosIter, lOneIter);
+ lCollectionArgs[lSkipPosition]
+ = new NumArithIterator<zorba::AddOperation>(
+ collIter->getStaticContext(), collIter->getLocation(),
+ lOldCollSkipIter, lCollSkipAdditionIter);
+ }
+ else
+ {
+ // no collection function with 0 or >3 params
+ assert(false);
+ }
+ aArgs[0] = new ZorbaCollectionIterator(collIter->getStaticContext(),
+ collIter->getLocation(), lCollectionArgs, collIter->isDynamic());
+
+ // after pushing the position param down we need to rewrite the actual
+ // position to 1:
+ // subsequence(collection(qname, 10+10-1), 10, 20)
+ // -> subsequence(collection(qname, 10+10-1), 1, 20)
+ aArgs[1] = new SingletonIterator (aSctx, aLoc, lItemOne);
+
+ return true;
+}
+
+
+/*******************************************************************************
********************************************************************************/
xqtref_t fn_unordered::getReturnType(const fo_expr* caller) const
{
@@ -408,12 +518,10 @@
std::vector<PlanIter_t>& aArgs,
expr& aAnn) const
{
+ const std::type_info& lFirstArgType = typeid(*aArgs[0]);
fo_expr& subseqExpr = static_cast<fo_expr&>(aAnn);
-
const expr* inputExpr = subseqExpr.get_arg(0);
-
const expr* posExpr = subseqExpr.get_arg(1);
-
const expr* lenExpr = (subseqExpr.num_args() > 2 ? subseqExpr.get_arg(2) : NULL);
if (inputExpr->get_expr_kind() == relpath_expr_kind &&
@@ -455,6 +563,22 @@
return aArgs[0];
}
}
+ else if (typeid(ZorbaCollectionIterator) == lFirstArgType)
+ {
+ // push down position param into collection skip if possible
+ if (rewriteSubsequenceCollection(aSctx, aLoc, aArgs, false /*no int*/))
+ {
+ // we have rewritten the subsequence to start at the beginning.
+ // if there is no length param we can remove the entire
+ // subsequence function
+ // subsequence(collection(qname, 10),1)
+ // -> collection(qname, 10)
+ if (aArgs.size() == 2)
+ {
+ return aArgs[0];
+ }
+ }
+ }
done:
return new FnSubsequenceIterator(aSctx, aLoc, aArgs);
@@ -491,17 +615,12 @@
std::vector<PlanIter_t>& aArgs,
expr& aAnn) const
{
+ const std::type_info& lFirstArgType = typeid(*aArgs[0]);
fo_expr& subseqExpr = static_cast<fo_expr&>(aAnn);
-
const expr* inputExpr = subseqExpr.get_arg(0);
-
const expr* posExpr = subseqExpr.get_arg(1);
-
const expr* lenExpr = (subseqExpr.num_args() > 2 ? subseqExpr.get_arg(2) : NULL);
- LetVarIterator* letVarIter;
- CtxVarIterator* ctxVarIter;
-
if (inputExpr->get_expr_kind() == relpath_expr_kind &&
posExpr->get_expr_kind() == const_expr_kind &&
lenExpr != NULL &&
@@ -533,32 +652,50 @@
return aArgs[0];
}
}
- else if ((letVarIter = dynamic_cast<LetVarIterator*>(aArgs[0].getp())) != NULL)
+ else if (typeid(LetVarIterator) == lFirstArgType)
{
+ LetVarIterator& letVarIter = static_cast<LetVarIterator&>(*aArgs[0]);
const var_expr* inputVar = inputExpr->get_var();
if (inputVar != NULL &&
(inputVar->get_kind() == var_expr::let_var ||
inputVar->get_kind() == var_expr::win_var ||
inputVar->get_kind() == var_expr::non_groupby_var) &&
- letVarIter->setTargetPosIter(aArgs[1]) &&
- letVarIter->setTargetLenIter(lenExpr ? aArgs[2] : NULL))
+ letVarIter.setTargetPosIter(aArgs[1]) &&
+ letVarIter.setTargetLenIter(lenExpr ? aArgs[2] : NULL))
{
return aArgs[0];
}
}
- else if ((ctxVarIter = dynamic_cast<CtxVarIterator*>(aArgs[0].getp())) != NULL)
+ else if (typeid(CtxVarIterator) == lFirstArgType)
{
+ CtxVarIterator& ctxVarIter = static_cast<CtxVarIterator&>(*aArgs[0]);
const var_expr* inputVar = inputExpr->get_var();
if (inputVar != NULL &&
!inputVar->is_context_item() &&
- ctxVarIter->setTargetPosIter(aArgs[1]) &&
- ctxVarIter->setTargetLenIter(lenExpr ? aArgs[2] : NULL))
+ ctxVarIter.setTargetPosIter(aArgs[1]) &&
+ ctxVarIter.setTargetLenIter(lenExpr ? aArgs[2] : NULL))
{
return aArgs[0];
}
}
+ else if (typeid(ZorbaCollectionIterator) == lFirstArgType)
+ {
+ // push down position param into collection skip if possible
+ if (rewriteSubsequenceCollection(aSctx, aLoc, aArgs, true /*flag int*/))
+ {
+ // we have rewritten the subsequence to start from the beginning.
+ // if there is no length param we can remove the entire
+ // subsequence function
+ // subsequence(collection(qname, 10),1)
+ // -> collection(qname, 10)
+ if (aArgs.size() == 2)
+ {
+ return aArgs[0];
+ }
+ }
+ }
done:
return new SubsequenceIntIterator(aSctx, aLoc, aArgs);
=== modified file 'src/runtime/collections/collections_impl.cpp'
--- src/runtime/collections/collections_impl.cpp 2012-12-14 13:23:51 +0000
+++ src/runtime/collections/collections_impl.cpp 2013-01-22 18:54:32 +0000
@@ -247,7 +247,7 @@
}
lCount = coll->size();
- if (theChildren.size() > 1)
+ if (theChildren.size() == 2)
{
// skip parameter passed
store::Item_t lSkipItem;
@@ -258,6 +258,14 @@
// negative is transformed into 0
lCount = ( lCount < xs_integer::zero() ? xs_integer::zero() : lCount );
}
+ else if(theChildren.size() > 2)
+ {
+ // if ref is passed to the collections function, count cannot be
+ // optimized anymore. Hence this iterator must not be used.
+ // In this case ZorbaCollectionIterator::isCountOptimizable() returns
+ // false.
+ assert(false);
+ }
STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, lCount), state);
Follow ups
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: noreply, 2013-01-31
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Zorba Build Bot, 2013-01-31
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Zorba Build Bot, 2013-01-31
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Dennis Knochenwefel, 2013-01-31
-
Re: [Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Dennis Knochenwefel, 2013-01-31
-
Re: [Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Matthias Brantner, 2013-01-31
-
Re: [Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Matthias Brantner, 2013-01-31
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Zorba Build Bot, 2013-01-23
-
Re: [Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Zorba Build Bot, 2013-01-23
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Zorba Build Bot, 2013-01-23
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Zorba Build Bot, 2013-01-23
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Dennis Knochenwefel, 2013-01-23
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Zorba Build Bot, 2013-01-22
-
Re: [Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Zorba Build Bot, 2013-01-22
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Zorba Build Bot, 2013-01-22
-
[Merge] lp:~dennis-knochenwefel/zorba/dennis-misc into lp:zorba
From: Dennis Knochenwefel, 2013-01-22