2017-12-12 20:13:53 +01:00
|
|
|
|
#include "PgAttribute.h"
|
2018-11-29 20:21:36 +01:00
|
|
|
|
#include "QStringBuilder"
|
|
|
|
|
|
#include "SqlFormattingUtils.h"
|
|
|
|
|
|
#include "PgClass.h"
|
|
|
|
|
|
#include "PgDatabaseCatalog.h"
|
2022-09-06 11:17:18 +00:00
|
|
|
|
#include "PgSequenceContainer.h"
|
2018-11-29 20:21:36 +01:00
|
|
|
|
#include "PgTypeContainer.h"
|
|
|
|
|
|
#include "PgCollation.h"
|
|
|
|
|
|
#include "PgCollationContainer.h"
|
2019-12-01 06:40:11 +01:00
|
|
|
|
#include "Pgsql_oids.h"
|
2018-11-29 20:21:36 +01:00
|
|
|
|
|
2022-09-06 11:17:18 +00:00
|
|
|
|
|
|
|
|
|
|
PgAttribute::Identity PgAttribute::getIdentity() const
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (identity)
|
|
|
|
|
|
{
|
|
|
|
|
|
case '\0': return Identity::None;
|
|
|
|
|
|
case 'a': return Identity::Always;
|
|
|
|
|
|
case 'd': return Identity::ByDefault;
|
|
|
|
|
|
}
|
|
|
|
|
|
assert(false); // we shouldn't get here
|
|
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PgAttribute::Generated PgAttribute::getGenerated() const
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (generated)
|
|
|
|
|
|
{
|
|
|
|
|
|
case '\0': return Generated::None;
|
|
|
|
|
|
case 's': return Generated::Stored;
|
|
|
|
|
|
}
|
|
|
|
|
|
assert(false); // we shouldn't get here
|
|
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-29 20:21:36 +01:00
|
|
|
|
QString PgAttribute::columnDefinition(const PgDatabaseCatalog &cat) const
|
|
|
|
|
|
{
|
|
|
|
|
|
// create: column_name data_type [ COLLATE collation ] [ column_constraint [ ... ]
|
|
|
|
|
|
// alter: column_name data_type [ COLLATE collation ] [ column_constraint [ ... ]
|
|
|
|
|
|
// constraints NULL/NOT NULL, DEFAULT, GENERATED other constraints will be ignored here a
|
2019-12-01 06:40:11 +01:00
|
|
|
|
QString type_str;
|
2022-09-06 11:17:18 +00:00
|
|
|
|
if (isSerial() && identity == '\0') {
|
2019-12-01 06:40:11 +01:00
|
|
|
|
if (typid == Pgsql::int4_oid)
|
|
|
|
|
|
type_str = "SERIAL";
|
|
|
|
|
|
else if (typid == Pgsql::int8_oid)
|
|
|
|
|
|
type_str = "BIGSERIAL";
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
2020-10-15 19:21:44 +02:00
|
|
|
|
type_str = getTypeDisplayString(cat, typid, typmod);
|
2019-12-01 06:40:11 +01:00
|
|
|
|
}
|
2018-11-29 20:21:36 +01:00
|
|
|
|
|
2019-12-01 06:40:11 +01:00
|
|
|
|
QString sql = quoteIdent(name) % " " % type_str;
|
2018-11-29 20:21:36 +01:00
|
|
|
|
if (collation != InvalidOid) {
|
|
|
|
|
|
auto&& col = cat.collations()->getByKey(collation);
|
|
|
|
|
|
QString oname = col->objectName();
|
|
|
|
|
|
if (oname != "default")
|
|
|
|
|
|
sql += " COLLATE " % quoteIdent(oname);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (notnull)
|
|
|
|
|
|
sql += " NOT NULL";
|
|
|
|
|
|
|
2022-09-06 11:17:18 +00:00
|
|
|
|
auto identity = getIdentity();
|
|
|
|
|
|
auto generated = getGenerated();
|
|
|
|
|
|
if (identity != Identity::None) {
|
2018-11-29 20:21:36 +01:00
|
|
|
|
sql += " GENERATED ";
|
2022-09-06 11:17:18 +00:00
|
|
|
|
if (identity == Identity::Always)
|
|
|
|
|
|
sql += "ALWAYS";
|
|
|
|
|
|
else if (identity == Identity::ByDefault)
|
|
|
|
|
|
sql += "BY DEFAULT";
|
2018-11-29 20:21:36 +01:00
|
|
|
|
sql += " AS IDENTITY";
|
2022-09-06 11:17:18 +00:00
|
|
|
|
|
|
|
|
|
|
auto sequence = cat.sequences()->getByObjectNsAndName(serschema, sername);
|
|
|
|
|
|
auto options_string = sequence->nonDefaultOptionsString();
|
|
|
|
|
|
if (!options_string.isEmpty())
|
|
|
|
|
|
sql += "(" % options_string % ")";
|
2018-11-29 20:21:36 +01:00
|
|
|
|
}
|
2022-09-06 11:17:18 +00:00
|
|
|
|
else if (generated != Generated::None)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (generated == Generated::Stored)
|
|
|
|
|
|
sql += " GENERATED ALWAYS AS " % defaultValue % " STORED";
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (hasdef && !isSerial())
|
|
|
|
|
|
sql += " DEFAULT " % defaultValue;
|
|
|
|
|
|
}
|
2018-11-29 20:21:36 +01:00
|
|
|
|
|
|
|
|
|
|
return sql;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString PgAttribute::alterTableAddColumn(const PgDatabaseCatalog &cat, const PgClass &table) const
|
|
|
|
|
|
{
|
|
|
|
|
|
QString sql = "ALTER TABLE " % table.fullyQualifiedQuotedObjectName()
|
|
|
|
|
|
% " ADD COLUMN " % columnDefinition(cat) % ";";
|
|
|
|
|
|
return sql;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString PgAttribute::alterTableDropColumn(const PgDatabaseCatalog &cat, const PgClass &table) const
|
|
|
|
|
|
{
|
|
|
|
|
|
QString sql = "ALTER TABLE " % table.fullyQualifiedQuotedObjectName()
|
|
|
|
|
|
% " DROP COLUMN " % quoteIdent(name) % ";";
|
|
|
|
|
|
return sql;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-02 20:42:32 +02:00
|
|
|
|
QString PgAttribute::commentStatement(const PgDatabaseCatalog &cat, const PgClass &table) const
|
|
|
|
|
|
{
|
|
|
|
|
|
if (description.isEmpty())
|
|
|
|
|
|
return {};
|
2017-12-12 20:13:53 +01:00
|
|
|
|
|
2021-07-02 20:42:32 +02:00
|
|
|
|
return "COMMENT ON COLUMN " % table.fullyQualifiedQuotedObjectName() % "."
|
|
|
|
|
|
% quoteIdent(name) % " IS " % escapeLiteral(description) % ";";
|
|
|
|
|
|
}
|