pgLab/pglablib/catalog/PgClassContainer.cpp
eelke 2c899bd799 Generate PARTITIONED BY SQL for partitioned tables.
Expressions not yet supported.
2023-02-06 20:31:00 +01:00

122 lines
3.4 KiB
C++

#include "PgClassContainer.h"
#include "Pgsql_Connection.h"
#include "Pgsql_Col.h"
#include "PgDatabaseCatalog.h"
#include "PgNamespaceContainer.h"
#include <iterator>
std::string PgClassContainer::getLoadQuery() const
{
std::string q = "SELECT pg_class.oid, relname, relnamespace, reltype, reloftype, "
" relowner, relam, relfilenode, reltablespace, relpages, "
" reltuples, reltoastrelid, relisshared, relpersistence, "
" relkind, relispopulated, relfrozenxid, relminmxid, "
" reloptions, d.description, "
" relacl, pg_get_viewdef(pg_class.oid)";
if (lessThenVersion(120000))
q += ", relhasoids ";
if (minimumVersion(100000))
q +=
", pg_get_expr(relpartbound, oid)"
", partstrat, partnatts, partattrs, partclass, partcollation"; // TODO: , partexprs";
if (minimumVersion(110000))
q += ", partdefid";
// pg_get_expr must be called on each element in partexprs
q +=
"\nFROM pg_catalog.pg_class \n"
" LEFT JOIN pg_catalog.pg_description AS d ON (objoid=pg_class.oid AND objsubid=0) \n";
if (minimumVersion(100000))
q += " LEFT JOIN pg_partitioned_table AS pt ON (partrelid=pg_class.oid) \n";
q +=
"WHERE relkind IN ('r', 'i', 'p', 'I', 'v', 'm', 'f')";
return q;
}
namespace {
class PartitionedTableKeyItemsBuilder {
public:
int16_t attCount;
std::vector<int16_t> attNums;
std::vector<Oid> attOpClass;
std::vector<Oid> attCollation;
PartitioningKeyItems Build()
{
PartitioningKeyItems result(attCount);
for (int attIdx = 0; attIdx < attCount; ++attIdx)
{
auto& item = result[attIdx];
item.attNum = attNums[attIdx];
item.opClass = attOpClass[attIdx];
item.collation = attCollation[attIdx];
}
return result;
}
};
}
PgClass PgClassContainer::loadElem(const Pgsql::Row &row)
{
Pgsql::Col col(row);
Oid class_oid = col.nextValue();
QString name = col.nextValue();
Oid schema_oid = col.nextValue();
PgClass v(m_catalog, class_oid, name, schema_oid);
Oid owner;
col >> v.type >> v.oftype
>> owner >> v.am >> v.filenode >> v.tablespace >> v.pages_est
>> v.tuples_est >> v.toastrelid >> v.isshared >> v.persistence
>> v.kind >> v.ispopulated >> v.frozenxid >> v.minmxid
>> v.options >> v.description;
v.setOwnerOid(owner);
AclList acl_list;
col >> acl_list;
v.setAcls(std::move(acl_list));
auto vd = col.nextValue();
if (!vd.null())
v.viewdef = vd.asQString();
if (lessThenVersion(120000))
col >> v.hasoids;
PgPartitionedTable &pt = v.partitionedTable;
if (minimumVersion(100000))
{
PartitionedTableKeyItemsBuilder kibuilder;
col >> v.partitionBoundaries;
auto strategy = col.nextValue();
if (strategy.null())
{
int s = minimumVersion(110000) ? 5 : 4;
col.skip(s);
}
else
{
pt.strategy << strategy;
col >> kibuilder.attCount;
col.getAsVector<int16_t>(std::back_inserter(kibuilder.attNums));
col.getAsVector<Oid>(std::back_inserter(kibuilder.attOpClass));
col.getAsVector<Oid>(std::back_inserter(kibuilder.attCollation));
pt.keyColumns = kibuilder.Build();
if (minimumVersion(110000))
col >> pt.defaultPartition;
}
}
return v;
}