Fix logic in RelWithDebInfo mode (#1397)
In and only in RelWithDebInfo mode the access of the maybe_unused variable results in segfaults, this change is making sure that does no happen ever if the maybe_unused variable is nullopt without changing the overall logic.
This commit is contained in:
parent
eceed274d9
commit
7a9c4f5ec4
@ -1276,28 +1276,59 @@ antlrcpp::Any CypherMainVisitor::visitCallProcedure(MemgraphCypher::CallProcedur
|
|||||||
call_proc->result_identifiers_.push_back(storage_->Create<Identifier>(result_alias));
|
call_proc->result_identifiers_.push_back(storage_->Create<Identifier>(result_alias));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const auto &maybe_found =
|
call_proc->is_write_ = maybe_found->second->info.is_write;
|
||||||
procedure::FindProcedure(procedure::gModuleRegistry, call_proc->procedure_name_, utils::NewDeleteResource());
|
|
||||||
if (!maybe_found) {
|
auto *yield_ctx = ctx->yieldProcedureResults();
|
||||||
throw SemanticException("There is no procedure named '{}'.", call_proc->procedure_name_);
|
if (!yield_ctx) {
|
||||||
|
if (!maybe_found->second->results.empty() && !call_proc->void_procedure_) {
|
||||||
|
throw SemanticException(
|
||||||
|
"CALL without YIELD may only be used on procedures which do not "
|
||||||
|
"return any result fields.");
|
||||||
|
}
|
||||||
|
// When we return, we will release the lock on modules. This means that
|
||||||
|
// someone may reload the procedure and change the result signature. But to
|
||||||
|
// keep the implementation simple, we ignore the case as the rest of the
|
||||||
|
// code doesn't really care whether we yield or not, so it should not break.
|
||||||
|
return call_proc;
|
||||||
}
|
}
|
||||||
const auto &[module, proc] = *maybe_found;
|
if (yield_ctx->getTokens(MemgraphCypher::ASTERISK).empty()) {
|
||||||
call_proc->result_fields_.reserve(proc->results.size());
|
call_proc->result_fields_.reserve(yield_ctx->procedureResult().size());
|
||||||
call_proc->result_identifiers_.reserve(proc->results.size());
|
call_proc->result_identifiers_.reserve(yield_ctx->procedureResult().size());
|
||||||
for (const auto &[result_name, desc] : proc->results) {
|
for (auto *result : yield_ctx->procedureResult()) {
|
||||||
bool is_deprecated = desc.second;
|
MG_ASSERT(result->variable().size() == 1 || result->variable().size() == 2);
|
||||||
if (is_deprecated) continue;
|
call_proc->result_fields_.push_back(std::any_cast<std::string>(result->variable()[0]->accept(this)));
|
||||||
call_proc->result_fields_.emplace_back(result_name);
|
std::string result_alias;
|
||||||
call_proc->result_identifiers_.push_back(storage_->Create<Identifier>(std::string(result_name)));
|
if (result->variable().size() == 2) {
|
||||||
|
result_alias = std::any_cast<std::string>(result->variable()[1]->accept(this));
|
||||||
|
} else {
|
||||||
|
result_alias = std::any_cast<std::string>(result->variable()[0]->accept(this));
|
||||||
|
}
|
||||||
|
call_proc->result_identifiers_.push_back(storage_->Create<Identifier>(result_alias));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const auto &maybe_found =
|
||||||
|
procedure::FindProcedure(procedure::gModuleRegistry, call_proc->procedure_name_, utils::NewDeleteResource());
|
||||||
|
if (!maybe_found) {
|
||||||
|
throw SemanticException("There is no procedure named '{}'.", call_proc->procedure_name_);
|
||||||
|
}
|
||||||
|
const auto &[module, proc] = *maybe_found;
|
||||||
|
call_proc->result_fields_.reserve(proc->results.size());
|
||||||
|
call_proc->result_identifiers_.reserve(proc->results.size());
|
||||||
|
for (const auto &[result_name, desc] : proc->results) {
|
||||||
|
bool is_deprecated = desc.second;
|
||||||
|
if (is_deprecated) continue;
|
||||||
|
call_proc->result_fields_.emplace_back(result_name);
|
||||||
|
call_proc->result_identifiers_.push_back(storage_->Create<Identifier>(std::string(result_name)));
|
||||||
|
}
|
||||||
|
// When we leave the scope, we will release the lock on modules. This means
|
||||||
|
// that someone may reload the procedure and change its result signature. We
|
||||||
|
// are fine with this, because if new result fields were added then we yield
|
||||||
|
// the subset of those and that will appear to a user as if they used the
|
||||||
|
// procedure before reload. Any subsequent `CALL ... YIELD *` will fetch the
|
||||||
|
// new fields as well. In case the result signature has had some result
|
||||||
|
// fields removed, then the query execution will report an error that we are
|
||||||
|
// yielding missing fields. The user can then just retry the query.
|
||||||
}
|
}
|
||||||
// When we leave the scope, we will release the lock on modules. This means
|
|
||||||
// that someone may reload the procedure and change its result signature. We
|
|
||||||
// are fine with this, because if new result fields were added then we yield
|
|
||||||
// the subset of those and that will appear to a user as if they used the
|
|
||||||
// procedure before reload. Any subsequent `CALL ... YIELD *` will fetch the
|
|
||||||
// new fields as well. In case the result signature has had some result
|
|
||||||
// fields removed, then the query execution will report an error that we are
|
|
||||||
// yielding missing fields. The user can then just retry the query.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return call_proc;
|
return call_proc;
|
||||||
|
Loading…
Reference in New Issue
Block a user