Improve support for declarative partitioning.

Generated SQL for a partition is now correct (atleast for simple cases)
Switched to C++ 20 so the ranges library can be used in this case
to filter unwanted items.
This commit is contained in:
eelke 2023-01-18 19:43:12 +01:00
parent 7a4d8f3410
commit 60fb4ce285
4 changed files with 92 additions and 38 deletions

View file

@ -6,7 +6,7 @@
#include "PgInheritsContainer.h"
#include <QStringBuilder>
#include "SqlFormattingUtils.h"
#include <ranges>
void operator<<(RelPersistence &s, const Pgsql::Value &v)
@ -125,52 +125,90 @@ QString PgClass::createTableSql() const
sql += "TEMP ";
sql += "TABLE ";
sql += fullyQualifiedQuotedObjectName();
sql += " (\n ";
auto && cols = catalog().attributes()->getColumnsForRelation(oid());
bool first = true;
for (auto && col : cols)
if (!partitionBoundaries.isEmpty())
{
if (col.num > 0 && !col.isdropped)
{
if (first)
{
first = false;
}
else
sql += ",\n ";
if (!col.islocal) sql += "-- ";
sql += col.columnDefinition(catalog());
}
// { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
// | table_constraint
// ] )
}
auto && constraints = catalog().constraints()->getConstraintsForRelation(oid());
for (auto && constraint: constraints)
{
if (first)
{
sql += "\n ";
first = false;
}
else
sql += ",\n ";
sql += getConstraintDefinition(catalog(), constraint, " ");
}
sql += " PARTITION OF " + getPartitionOfName();
sql += generateBodySql(true);
}
else
sql += generateBodySql(false);
sql += "\n)"
% generateInheritsSql()
// [ PARTITION BY { RANGE | LIST } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
// [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
// [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
sql += generateInheritsSql()
% generateTablespaceSql()
% ";\n";
return sql;
}
QString PgClass::generateBodySql(bool isPartition) const
{
// - also remove commented inherited column list? They are listed in the column view no need for them in sql
// - mark them in the view as inherited?
// - detect when body empty and leave it out completely (only for partitions, is leaving it out always legal?)
// - need to detect "inherited" constraint because these should not be listed either
auto colsFilter = isPartition ?
[] (const PgAttribute &c)
{
return c.num > 0 // ignore system columns
&& !c.isdropped // ignore dropped columns
&& c.islocal;
}
:
[] (const PgAttribute &c)
{
return c.num > 0 // ignore system columns
&& !c.isdropped; // ignore dropped columns
}
;
auto && cols = catalog().attributes()->getColumnsForRelation(oid())
| std::views::filter(colsFilter);
auto && constraints = catalog().constraints()->getConstraintsForRelation(oid())
| std::views::filter([] (const auto &c) { return c.islocal; });
if (cols.empty() && constraints.empty())
return {};
QString sql = " (\n ";
bool first = true;
for (auto && col : cols)
{
if (first)
{
first = false;
}
else
sql += ",\n ";
if (!col.islocal) sql += "-- ";
sql += col.columnDefinition(catalog());
}
for (auto && constraint: constraints)
{
if (first)
{
sql += "\n ";
first = false;
}
else
sql += ",\n ";
sql += getConstraintDefinition(catalog(), constraint, " ");
}
sql += "\n)";
return sql;
}
QString PgClass::generateInheritsSql() const
{
if (!partitionBoundaries.isEmpty())
return "\n" + partitionBoundaries;
QString sql;
// [ INHERITS ( parent_table [, ... ] ) ]
auto parents = catalog().inherits()->getParentsOf(oid());
@ -189,6 +227,16 @@ QString PgClass::generateInheritsSql() const
return sql;
}
QString PgClass::getPartitionOfName() const
{
auto parents = catalog().inherits()->getParentsOf(oid());
if (!parents.empty())
{
return catalog().classes()->getByKey(parents.front())->fullyQualifiedQuotedObjectName();
}
throw std::logic_error("Should only be called if there is a parent table");
}
QString PgClass::generateTablespaceSql() const
{
if (tablespace != 0)

View file

@ -62,7 +62,9 @@ private:
mutable QString createSqlCache;
QString createTableSql() const;
QString generateBodySql(bool isPartition) const;
QString generateInheritsSql() const;
QString getPartitionOfName() const;
QString generateTablespaceSql() const;
QString createViewSql() const;
};

View file

@ -79,6 +79,10 @@ public:
QString dropSql() const override;
QString createSql() const override;
bool isInherited() const
{
return inhcount > 0;
}
};