The table inheritance works mostly

This commit is contained in:
Eelke Klein 2023-01-24 17:47:52 +00:00
parent ccd88d0578
commit 2ff9577d41
22 changed files with 473 additions and 145 deletions

View file

@ -4,17 +4,24 @@
#include "PgContainer.h"
#include "PgInherits.h"
#include "Pgsql_declare.h"
class IFindParents
{
public:
virtual std::vector<Oid> getParentsOf(Oid oid) const = 0;
};
class PgInheritsContainer : public PgContainer<PgInherits, PgInherits::Key> {
class PgInheritsContainer
: public PgContainer<PgInherits, PgInherits::Key>
, public IFindParents
{
public:
using PgContainer<PgInherits, PgInherits::Key>::PgContainer;
virtual std::string getLoadQuery() const override;
/// Returns the parents in the correct order
std::vector<Oid> getParentsOf(Oid oid) const;
std::vector<Oid> getParentsOf(Oid oid) const override;
protected:
PgInherits loadElem(const Pgsql::Row &row) override;
};

View file

@ -45,6 +45,9 @@ SOURCES += \
catalog/PgConstraintContainer.cpp \
ParamListJson.cpp \
ParamListModel.cpp \
ui/catalog/tables/TableNode.cpp \
ui/catalog/tables/TableSize.cpp \
ui/catalog/tables/TableTreeBuilder.cpp \
util.cpp \
SqlFormattingUtils.cpp \
catalog/PgKeywordList.cpp \
@ -113,6 +116,9 @@ HEADERS += \
catalog/PgConstraintContainer.h \
ParamListJson.h \
ParamListModel.h \
ui/catalog/tables/TableNode.h \
ui/catalog/tables/TableSize.h \
ui/catalog/tables/TableTreeBuilder.h \
util.h \
SqlFormattingUtils.h \
catalog/PgCatalogTypes.h \

View file

@ -0,0 +1,20 @@
#include "TableNode.h"
#include "catalog/PgDatabaseCatalog.h"
namespace {
PgDatabaseCatalog dummyCatalog;
}
TableNode::TableNode()
: _class(dummyCatalog, InvalidOid, "", InvalidOid)
{
}
TableNode::TableNode(const PgClass &cls)
: _class(cls)
{}
const TableNode *TableNode::getChildPtr(int index) const
{
return children.at(index).get();
}

View file

@ -0,0 +1,25 @@
#pragma once
#include "TableSize.h"
#include "catalog/PgClass.h"
class TableNode;
using t_Tables = std::vector<std::shared_ptr<TableNode>>;
class TableNode {
public:
PgClass _class;
TableSize sizes;
int myIndex;
std::weak_ptr<TableNode> parent; // hope we do not need it (must be weak to prevent circular reference)
t_Tables children;
TableNode();
TableNode(const PgClass &cls);
const TableNode* getChildPtr(int index) const;
};

View file

@ -0,0 +1,6 @@
#include "TableSize.h"
TableSize::TableSize()
: oid(0)
{}

View file

@ -0,0 +1,13 @@
#pragma once
#include <cstdint>
class TableSize {
public:
int oid;
int64_t totalBytes = -1;
int64_t indexBytes = -1;
int64_t toastBytes = -1;
TableSize();
};

View file

@ -0,0 +1,82 @@
#include "TableTreeBuilder.h"
#include "catalog/PgInheritsContainer.h"
#include "TableNode.h"
#include <ranges>
TableTreeBuilder::TableTreeBuilder(
const std::map<Oid, PgClass> &source,
const IFindParents &inheritance
)
: source(source)
, inheritance(inheritance)
{
}
std::tuple<std::shared_ptr<TableNode>, std::map<Oid, std::shared_ptr<TableNode>>> TableTreeBuilder::Build()
{
rootNode = std::make_shared<TableNode>();
// when childrens are ordered before there parents
// the parent will automatically be added first (recursively)
// processed nodes are tracked in the nodes member
for (auto && e : source | std::views::filter(
[this] (auto &e)
{
return processedNodes.count(e.first) == 0;
})
)
{
addNode(e.second);
}
AssignNodeIndexesAndParents(rootNode);
return { rootNode, std::move(processedNodes) };
}
std::shared_ptr<TableNode> TableTreeBuilder::addNode(const PgClass &cls)
{
std::shared_ptr<TableNode> node = std::make_shared<TableNode>(cls);
processedNodes.emplace(cls.oid(), node);
std::vector<Oid> parents = inheritance.getParentsOf(cls.oid());
if (parents.empty())
addToToplevel(node);
else
addToParents(node, parents);
return node;
}
void TableTreeBuilder::addToToplevel(std::shared_ptr<TableNode> node)
{
rootNode->children.push_back(node);
}
void TableTreeBuilder::addToParents(std::shared_ptr<TableNode> node, const std::vector<Oid> &parents)
{
for (auto &parent : parents)
{
getParent(parent)->children.push_back(node);
}
}
std::shared_ptr<TableNode> TableTreeBuilder::getParent(Oid oid)
{
auto parent = processedNodes.find(oid);
if (parent != processedNodes.end())
return parent->second;
// Not present, find in source list and add now
auto source_iter = source.find(oid);
assert(source_iter != source.end());
return addNode(source_iter->second);
}
void TableTreeBuilder::AssignNodeIndexesAndParents(std::shared_ptr<TableNode> parent)
{
int index = 0;
for (auto &n : parent->children)
{
n->parent = parent;
n->myIndex = index++;
AssignNodeIndexesAndParents(n);
}
}

View file

@ -0,0 +1,31 @@
#pragma once
#include "Pgsql_oids.h"
#include <map>
#include <memory>
class PgClass;
class TableNode;
class IFindParents;
class TableTreeBuilder
{
public:
TableTreeBuilder(const std::map<Oid, PgClass> &source, const IFindParents &inheritance);
std::tuple<std::shared_ptr<TableNode>, std::map<Oid, std::shared_ptr<TableNode>>> Build();
private:
const std::map<Oid, PgClass> &source;
const IFindParents &inheritance;
std::map<Oid, std::shared_ptr<TableNode>> processedNodes;
std::shared_ptr<TableNode> rootNode;
bool hasParent(const PgClass &cls) const;
std::shared_ptr<TableNode> addNode(const PgClass &cls);
void addToToplevel(std::shared_ptr<TableNode> node);
void addToParents(std::shared_ptr<TableNode> node, const std::vector<Oid> &parents);
std::shared_ptr<TableNode> getParent(Oid oid);
void AssignNodeIndexesAndParents(std::shared_ptr<TableNode> parent);
};