diff --git a/arangod/Aql/Ast.cpp b/arangod/Aql/Ast.cpp index 9546e9fcd2..d5289c50df 100644 --- a/arangod/Aql/Ast.cpp +++ b/arangod/Aql/Ast.cpp @@ -1459,7 +1459,10 @@ AstNode* Ast::createNodeNaryOperator(AstNodeType type, AstNode const* child) { } /// @brief injects bind parameters into the AST -void Ast::injectBindParameters(BindParameters& parameters) { +void Ast::injectBindParameters( + BindParameters& parameters, + arangodb::CollectionNameResolver const& resolver +) { auto& p = parameters.get(); auto func = [&](AstNode* node) -> AstNode* { @@ -1499,9 +1502,6 @@ void Ast::injectBindParameters(BindParameters& parameters) { ); } - // FIXME use external resolver - arangodb::CollectionNameResolver resolver(_query->vocbase()); - switch (node->getMemberUnchecked(0)->type) { case NODE_TYPE_COLLECTION: { auto dataSource = resolver.getCollection(value.copyString()); @@ -1522,20 +1522,21 @@ void Ast::injectBindParameters(BindParameters& parameters) { arangodb::StringRef paramRef(param); - for (auto const& it : _writeCollections) { auto const& c = it.first; if (c->type == NODE_TYPE_PARAMETER && paramRef == StringRef(c->getStringValue(), c->getStringLength())) { isWriteCollection = true; + break; } } - node = createNodeCollection(name, isWriteCollection - ? AccessMode::Type::WRITE - : AccessMode::Type::READ); + node = createNodeCollection( + name, + isWriteCollection ? AccessMode::Type::WRITE : AccessMode::Type::READ + ); if (isWriteCollection) { // must update AST info now for all nodes that contained this parameter diff --git a/arangod/Aql/Ast.h b/arangod/Aql/Ast.h index 4fc06afd5f..072664064c 100644 --- a/arangod/Aql/Ast.h +++ b/arangod/Aql/Ast.h @@ -384,7 +384,10 @@ class Ast { AstNode* createNodeNaryOperator(AstNodeType, AstNode const*); /// @brief injects bind parameters into the AST - void injectBindParameters(BindParameters&); + void injectBindParameters( + BindParameters& parameters, + arangodb::CollectionNameResolver const& resolver + ); /// @brief replace variables AstNode* replaceVariables( diff --git a/arangod/Aql/Query.cpp b/arangod/Aql/Query.cpp index 9c9f88bcb5..1669f1d6fd 100644 --- a/arangod/Aql/Query.cpp +++ b/arangod/Aql/Query.cpp @@ -429,14 +429,22 @@ ExecutionPlan* Query::preparePlan() { LOG_TOPIC(DEBUG, Logger::QUERIES) << TRI_microtime() - _startTime << " " << "Query::prepare" << " this: " << (uintptr_t) this; + + auto ctx = createTransactionContext(); std::unique_ptr plan; + if (!ctx) { + THROW_ARANGO_EXCEPTION_MESSAGE( + TRI_ERROR_INTERNAL, "failed to create query transaction context" + ); + } + if (!_queryString.empty()) { Parser parser(this); parser.parse(false); // put in bind parameters - parser.ast()->injectBindParameters(_bindParameters); + parser.ast()->injectBindParameters(_bindParameters, ctx->resolver()); } TRI_ASSERT(_trx == nullptr); @@ -450,9 +458,12 @@ ExecutionPlan* Query::preparePlan() { #endif std::unique_ptr trx(AqlTransaction::create( - createTransactionContext(), _collections.collections(), - _queryOptions.transactionOptions, - _part == PART_MAIN, inaccessibleCollections)); + std::move(ctx), + _collections.collections(), + _queryOptions.transactionOptions, + _part == PART_MAIN, + inaccessibleCollections + )); TRI_DEFER(trx.release()); // create the transaction object, but do not start it yet _trx = trx.get(); @@ -908,19 +919,24 @@ QueryResult Query::explain() { init(); enterState(QueryExecutionState::ValueType::PARSING); + auto ctx = createTransactionContext(); Parser parser(this); parser.parse(true); + // put in bind parameters - parser.ast()->injectBindParameters(_bindParameters); + parser.ast()->injectBindParameters(_bindParameters, ctx->resolver()); // optimize and validate the ast enterState(QueryExecutionState::ValueType::AST_OPTIMIZATION); // create the transaction object, but do not start it yet - _trx = AqlTransaction::create(createTransactionContext(), - _collections.collections(), - _queryOptions.transactionOptions, true); + _trx = AqlTransaction::create( + std::move(ctx), + _collections.collections(), + _queryOptions.transactionOptions, + true + ); // we have an AST Result res = _trx->begin();