1
0
Fork 0

issue 380.1: reuse resolver used during injectBindParameters(...) in the query transaction (#5548)

This commit is contained in:
Vasiliy 2018-06-07 00:23:05 +03:00 committed by Andrey Abramov
parent e117a97fb4
commit 6fae53fb1b
3 changed files with 37 additions and 17 deletions

View File

@ -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

View File

@ -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(

View File

@ -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();