/** * 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()); }