mirror of https://gitee.com/bigwinds/arangodb
issue 380.1: reuse resolver used during injectBindParameters(...) in the query transaction (#5548)
This commit is contained in:
parent
e117a97fb4
commit
6fae53fb1b
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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<ExecutionPlan> 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<AqlTransaction> 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();
|
||||
|
|
Loading…
Reference in New Issue