Generate PARTITIONED BY SQL for partitioned tables.
Expressions not yet supported.
This commit is contained in:
parent
61f90668d8
commit
2c899bd799
8 changed files with 243 additions and 41 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#include "PgClass.h"
|
||||
#include "PgAttribute.h"
|
||||
#include "PgAttributeContainer.h"
|
||||
#include "PgClassContainer.h"
|
||||
#include "PgDatabaseCatalog.h"
|
||||
|
|
@ -7,6 +8,7 @@
|
|||
#include <QStringBuilder>
|
||||
#include "SqlFormattingUtils.h"
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
void operator<<(RelPersistence &s, const Pgsql::Value &v)
|
||||
|
|
@ -33,41 +35,60 @@ void operator<<(RelKind &s, const Pgsql::Value &v)
|
|||
const char *c = v.c_str();
|
||||
switch (*c)
|
||||
{
|
||||
case 'r':
|
||||
s = RelKind::Table;
|
||||
break;
|
||||
case 'i':
|
||||
s = RelKind::Index;
|
||||
break;
|
||||
case 'S':
|
||||
s = RelKind::Sequence;
|
||||
break;
|
||||
case 'v':
|
||||
s = RelKind::View;
|
||||
break;
|
||||
case 'm':
|
||||
s = RelKind::MaterializedView;
|
||||
break;
|
||||
case 'c':
|
||||
s = RelKind::Composite;
|
||||
break;
|
||||
case 't':
|
||||
s = RelKind::Toast;
|
||||
break;
|
||||
case 'f':
|
||||
s = RelKind::ForeignTable;
|
||||
break;
|
||||
case 'p':
|
||||
s = RelKind::PartitionedTable;
|
||||
break;
|
||||
case 'I':
|
||||
s = RelKind::PartitionedIndex;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown RelKind");
|
||||
case 'r':
|
||||
s = RelKind::Table;
|
||||
break;
|
||||
case 'i':
|
||||
s = RelKind::Index;
|
||||
break;
|
||||
case 'S':
|
||||
s = RelKind::Sequence;
|
||||
break;
|
||||
case 'v':
|
||||
s = RelKind::View;
|
||||
break;
|
||||
case 'm':
|
||||
s = RelKind::MaterializedView;
|
||||
break;
|
||||
case 'c':
|
||||
s = RelKind::Composite;
|
||||
break;
|
||||
case 't':
|
||||
s = RelKind::Toast;
|
||||
break;
|
||||
case 'f':
|
||||
s = RelKind::ForeignTable;
|
||||
break;
|
||||
case 'p':
|
||||
s = RelKind::PartitionedTable;
|
||||
break;
|
||||
case 'I':
|
||||
s = RelKind::PartitionedIndex;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown RelKind");
|
||||
}
|
||||
}
|
||||
|
||||
void operator<<(PartitioningStrategy &s, const Pgsql::Value &v)
|
||||
{
|
||||
const char *c = v.c_str();
|
||||
switch (*c)
|
||||
{
|
||||
case 'h':
|
||||
s = PartitioningStrategy::Hash;
|
||||
break;
|
||||
case 'l':
|
||||
s = PartitioningStrategy::List;
|
||||
break;
|
||||
case 'r':
|
||||
s = PartitioningStrategy::Range;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown PartitioningStrategy");
|
||||
}
|
||||
}
|
||||
|
||||
QString PgClass::createSql() const
|
||||
{
|
||||
if (createSqlCache.isEmpty())
|
||||
|
|
@ -75,6 +96,7 @@ QString PgClass::createSql() const
|
|||
switch (kind)
|
||||
{
|
||||
case RelKind::Table:
|
||||
case RelKind::PartitionedTable:
|
||||
createSqlCache = createTableSql();
|
||||
break;
|
||||
case RelKind::View:
|
||||
|
|
@ -118,7 +140,7 @@ QString PgClass::ddlTypeName() const
|
|||
{
|
||||
switch (kind)
|
||||
{
|
||||
case RelKind::PartitionedTable: return "PARTITIONED TABLE";
|
||||
case RelKind::PartitionedTable:
|
||||
return "TABLE";
|
||||
default:
|
||||
return PgNamespaceObject::ddlTypeName();
|
||||
|
|
@ -145,7 +167,9 @@ QString PgClass::createTableSql() const
|
|||
else
|
||||
sql += generateBodySql(false);
|
||||
|
||||
|
||||
sql += generateInheritsSql()
|
||||
% partitionBySql()
|
||||
% generateTablespaceSql()
|
||||
% ";\n";
|
||||
return sql;
|
||||
|
|
@ -238,6 +262,49 @@ QString PgClass::generateInheritsSql() const
|
|||
return sql;
|
||||
}
|
||||
|
||||
QString PgClass::partitionBySql() const
|
||||
{
|
||||
if (kind != RelKind::PartitionedTable)
|
||||
return {};
|
||||
|
||||
QString sql = "\nPARTITION BY " % PartitionStrategyKeyword(partitionedTable.strategy);
|
||||
sql += partitionKeySql();
|
||||
return sql;
|
||||
}
|
||||
|
||||
QString PgClass::partitionKeySql() const
|
||||
{
|
||||
QString result;
|
||||
result += "(";
|
||||
auto keyItem = partitionedTable.keyColumns.begin();
|
||||
if (keyItem != partitionedTable.keyColumns.end())
|
||||
{
|
||||
result += partitionKeyItemSql(*keyItem);
|
||||
for (++keyItem; keyItem != partitionedTable.keyColumns.end(); ++keyItem)
|
||||
result += ", " % partitionKeyItemSql(*keyItem);
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
QString PgClass::partitionKeyItemSql(
|
||||
const PartitioningKeyItem &keyItem
|
||||
) const
|
||||
{
|
||||
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
|
||||
|
||||
const PgAttribute *col = catalog().attributes()->findIf(
|
||||
[this, &keyItem] (const auto &att)
|
||||
{
|
||||
return att.relid == oid() && att.num == keyItem.attNum;
|
||||
}
|
||||
);
|
||||
|
||||
assert(col != nullptr);
|
||||
return quoteIdent(col->name);
|
||||
}
|
||||
|
||||
QString PgClass::getPartitionOfName() const
|
||||
{
|
||||
auto parents = catalog().inherits()->getParentsOf(oid());
|
||||
|
|
@ -274,4 +341,15 @@ QString PgClass::createViewSql() const
|
|||
return sql;
|
||||
}
|
||||
|
||||
|
||||
QString PartitionStrategyKeyword(PartitioningStrategy ps)
|
||||
{
|
||||
switch (ps) {
|
||||
case PartitioningStrategy::Hash:
|
||||
return "HASH";
|
||||
case PartitioningStrategy::List:
|
||||
return "LIST";
|
||||
case PartitioningStrategy::Range:
|
||||
return "RANGE";
|
||||
}
|
||||
throw std::runtime_error("Unknown PartitioningStrategy");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue