The table inheritance works mostly
When a table has partitions or inheritance children these are listed as subnodes. A subnode can appear multiple times under different parents as postgresql supports inheriting multiple tables. The sizes are still missing and maybe some things I have note verified yet are not correct.
This commit is contained in:
parent
ccd88d0578
commit
39dbab4d36
17 changed files with 452 additions and 127 deletions
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
20
pglablib/ui/catalog/tables/TableNode.cpp
Normal file
20
pglablib/ui/catalog/tables/TableNode.cpp
Normal 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();
|
||||
}
|
||||
25
pglablib/ui/catalog/tables/TableNode.h
Normal file
25
pglablib/ui/catalog/tables/TableNode.h
Normal 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;
|
||||
};
|
||||
6
pglablib/ui/catalog/tables/TableSize.cpp
Normal file
6
pglablib/ui/catalog/tables/TableSize.cpp
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "TableSize.h"
|
||||
|
||||
|
||||
TableSize::TableSize()
|
||||
: oid(0)
|
||||
{}
|
||||
13
pglablib/ui/catalog/tables/TableSize.h
Normal file
13
pglablib/ui/catalog/tables/TableSize.h
Normal 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();
|
||||
};
|
||||
89
pglablib/ui/catalog/tables/TableTreeBuilder.cpp
Normal file
89
pglablib/ui/catalog/tables/TableTreeBuilder.cpp
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#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::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);
|
||||
auto ret = rootNode;
|
||||
resetState();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TableTreeBuilder::resetState()
|
||||
{
|
||||
rootNode.reset();
|
||||
processedNodes.clear();
|
||||
}
|
||||
|
||||
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())
|
||||
addToplevelNode(node);
|
||||
else
|
||||
addToParents(node, parents);
|
||||
return node;
|
||||
}
|
||||
|
||||
void TableTreeBuilder::addToplevelNode(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);
|
||||
}
|
||||
}
|
||||
32
pglablib/ui/catalog/tables/TableTreeBuilder.h
Normal file
32
pglablib/ui/catalog/tables/TableTreeBuilder.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#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::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;
|
||||
|
||||
void resetState();
|
||||
bool hasParent(const PgClass &cls) const;
|
||||
std::shared_ptr<TableNode> addNode(const PgClass &cls);
|
||||
void addToplevelNode(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);
|
||||
};
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue