Skip to content

Commit

Permalink
Incremental parsing issue fixes (#736)
Browse files Browse the repository at this point in the history
Fix segmentation fault due to access of file ID on non-loaded file.
Eliminated use of size() on ODB query result in SourceManager. Added isSingletonResult instead to dbutil.
  • Loading branch information
dbukki authored May 8, 2024
1 parent 5f49828 commit 7ba19f9
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 7 deletions.
5 changes: 3 additions & 2 deletions parser/src/sourcemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <util/hash.h>
#include <util/logutil.h>
#include <util/dbutil.h>

#include <parser/sourcemanager.h>

Expand Down Expand Up @@ -238,9 +239,9 @@ void SourceManager::removeFile(const model::File& file_)
_transaction([&]() {
if(file_.content)
{
auto relFiles = _db->query<model::File>(
odb::result<model::File> relFiles = _db->query<model::File>(
odb::query<model::File>::content == file_.content.object_id());
if (relFiles.size() == 1)
if (util::isSingleResult(relFiles))
{
removeContent = true;
_db->erase<model::FileContent>(file_.content.object_id());
Expand Down
13 changes: 13 additions & 0 deletions plugins/cpp_metrics/model/include/model/cppastnodemetrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ struct CppRecordMetricsView
double value;
};

#pragma db view \
object(CppAstNodeMetrics) \
object(CppAstNode : CppAstNodeMetrics::astNodeId == CppAstNode::id) \
object(File : CppAstNode::location.file)
struct CppAstNodeMetricsFileView
{
#pragma db column(CppAstNode::id)
CppAstNodeId astNodeId;

#pragma db column(File::id)
FileId fileId;
};

#pragma db view \
object(CppAstNodeMetrics) \
object(CppAstNode : CppAstNodeMetrics::astNodeId == CppAstNode::id) \
Expand Down
8 changes: 3 additions & 5 deletions plugins/cpp_metrics/parser/src/cppmetricsparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,10 @@ CppMetricsParser::CppMetricsParser(ParserContext& ctx_): AbstractParser(ctx_)
_fileIdCache.insert(fm.file);
}

for (const model::CppAstNodeMetrics& anm
: _ctx.db->query<model::CppAstNodeMetrics>())
for (const model::CppAstNodeMetricsFileView& anm
: _ctx.db->query<model::CppAstNodeMetricsFileView>())
{
auto node = _ctx.db->query_one<model::CppAstNode>(
odb::query<model::CppAstNode>::id == anm.astNodeId);
_astNodeIdCache.insert({anm.astNodeId, node->location.file->id});
_astNodeIdCache.emplace(anm.astNodeId, anm.fileId);
}
});
}
Expand Down
34 changes: 34 additions & 0 deletions util/include/util/dbutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,40 @@ inline std::string getDbDriver()
#endif
}

/// @brief Determines if the specified ODB query result only contains
/// a single entity. That single entity is then stored in 'single_'.
/// @tparam TEntity The type of entities in the query result.
/// @param result_ The ODB query result in question.
/// @param single_ The variable that receives the first entity (if any).
/// @return Returns true if 'result_' only contained 'single_';
/// otherwise false.
template<typename TEntity>
bool isSingleResult(odb::result<TEntity>& result_, TEntity& single_)
{
auto it_b = result_.begin();
const auto it_e = result_.end();
if (it_b != it_e)
{
single_ = *it_b;
return ++it_b == it_e;
}
else return false;
}

/// @brief Determines if the specified ODB query result only contains
/// a single entity.
/// @tparam TEntity The type of entities in the query result.
/// @param result_ The ODB query result in question.
/// @return Returns true if 'result_' only contained a single entity;
/// otherwise false.
template<typename TEntity>
bool isSingleResult(odb::result<TEntity>& result_)
{
auto it_b = result_.begin();
const auto it_e = result_.end();
return (it_b != it_e) && (++it_b == it_e);
}

} // util
} // cc

Expand Down

0 comments on commit 7ba19f9

Please sign in to comment.