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