Esempio n. 1
0
/**
 * If one or more of the arguments of the function call depend on query only
 * state (query local but not a query parameter reference), then rewrite
 * all of the arguments to be query local and return the rewritten
 * function call (the query processor has to either figure out a way to call
 * the function or must cause a runtime error when faced with the call).
 * Otherwise, rewrite the call as a query parameter reference.
 */
ExpressionPtr CaptureExtractor::rewriteCall(SimpleFunctionCallPtr sfc) {
  assert(sfc != nullptr);
  if (sfc->hadBackslash() || sfc->getClass() || sfc->hasStaticClass()) {
    return newQueryParamRef(sfc);
  }
  auto args = sfc->getParams();
  auto pc = args == nullptr ? 0 : args->getCount();
  bool isQueryCall = false;
  for (int i = 0; i < pc; i++) {
    auto arg = (*args)[i];
    assert(arg != nullptr);
    isQueryCall |= this->dependsOnQueryOnlyState(arg);
  }
  if (!isQueryCall) return newQueryParamRef(sfc);
  auto newArgs =
    std::make_shared<ExpressionList>(args->getScope(), args->getRange());
  bool noRewrites = true;
  for (int i = 0; i < pc; i++) {
    auto arg = (*args)[i];
    auto newArg = rewrite(arg);
    if (arg != newArg) noRewrites = false;
    newArgs->addElement(newArg);
  }
  if (noRewrites) return sfc;
  return std::make_shared<SimpleFunctionCall>(
    sfc->getScope(), sfc->getRange(),
    sfc->getOriginalName(), false, newArgs, ExpressionPtr());
}