Support expressions as partitioning keys

This commit is contained in:
eelke 2023-03-21 16:20:25 +01:00
parent 2c899bd799
commit 3cc28231f9
2 changed files with 9 additions and 7 deletions

View file

@ -292,7 +292,7 @@ QString PgClass::partitionKeyItemSql(
) const ) const
{ {
if (keyItem.attNum == 0) if (keyItem.attNum == 0)
return "\"<expr>\""; // TODO add expression support for now use this to prevent a crash here because column 0 does not exist return keyItem.expression;
const PgAttribute *col = catalog().attributes()->findIf( const PgAttribute *col = catalog().attributes()->findIf(
[this, &keyItem] (const auto &att) [this, &keyItem] (const auto &att)

View file

@ -1,8 +1,6 @@
#include "PgClassContainer.h" #include "PgClassContainer.h"
#include "Pgsql_Connection.h"
#include "Pgsql_Col.h" #include "Pgsql_Col.h"
#include "PgDatabaseCatalog.h" #include "PgDatabaseCatalog.h"
#include "PgNamespaceContainer.h"
#include <iterator> #include <iterator>
std::string PgClassContainer::getLoadQuery() const std::string PgClassContainer::getLoadQuery() const
@ -18,13 +16,12 @@ std::string PgClassContainer::getLoadQuery() const
q += ", relhasoids "; q += ", relhasoids ";
if (minimumVersion(100000)) if (minimumVersion(100000))
q += q +=
", pg_get_expr(relpartbound, oid)" ", pg_get_expr(relpartbound, pg_class.oid)"
", partstrat, partnatts, partattrs, partclass, partcollation"; // TODO: , partexprs"; ", partstrat, partnatts, partattrs, partclass, partcollation "
", pg_get_expr(partexprs, partrelid) AS partexprs";
if (minimumVersion(110000)) if (minimumVersion(110000))
q += ", partdefid"; q += ", partdefid";
// pg_get_expr must be called on each element in partexprs
q += q +=
"\nFROM pg_catalog.pg_class \n" "\nFROM pg_catalog.pg_class \n"
" LEFT JOIN pg_catalog.pg_description AS d ON (objoid=pg_class.oid AND objsubid=0) \n"; " LEFT JOIN pg_catalog.pg_description AS d ON (objoid=pg_class.oid AND objsubid=0) \n";
@ -46,9 +43,11 @@ namespace {
std::vector<int16_t> attNums; std::vector<int16_t> attNums;
std::vector<Oid> attOpClass; std::vector<Oid> attOpClass;
std::vector<Oid> attCollation; std::vector<Oid> attCollation;
std::vector<QString> expressions;
PartitioningKeyItems Build() PartitioningKeyItems Build()
{ {
int expr_idx = 0;
PartitioningKeyItems result(attCount); PartitioningKeyItems result(attCount);
for (int attIdx = 0; attIdx < attCount; ++attIdx) for (int attIdx = 0; attIdx < attCount; ++attIdx)
{ {
@ -56,6 +55,8 @@ namespace {
item.attNum = attNums[attIdx]; item.attNum = attNums[attIdx];
item.opClass = attOpClass[attIdx]; item.opClass = attOpClass[attIdx];
item.collation = attCollation[attIdx]; item.collation = attCollation[attIdx];
if (item.attNum == 0)
item.expression = expressions[expr_idx++];
} }
return result; return result;
} }
@ -111,6 +112,7 @@ PgClass PgClassContainer::loadElem(const Pgsql::Row &row)
col.getAsVector<int16_t>(std::back_inserter(kibuilder.attNums)); col.getAsVector<int16_t>(std::back_inserter(kibuilder.attNums));
col.getAsVector<Oid>(std::back_inserter(kibuilder.attOpClass)); col.getAsVector<Oid>(std::back_inserter(kibuilder.attOpClass));
col.getAsVector<Oid>(std::back_inserter(kibuilder.attCollation)); col.getAsVector<Oid>(std::back_inserter(kibuilder.attCollation));
col.getAsVector<QString>(std::back_inserter(kibuilder.expressions));
pt.keyColumns = kibuilder.Build(); pt.keyColumns = kibuilder.Build();
if (minimumVersion(110000)) if (minimumVersion(110000))