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:
parent
7a4d8f3410
commit
60fb4ce285
4 changed files with 92 additions and 38 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue