#include "PgAttribute.h" #include "QStringBuilder" #include "SqlFormattingUtils.h" #include "PgClass.h" #include "PgDatabaseCatalog.h" #include "PgSequenceContainer.h" #include "PgTypeContainer.h" #include "PgCollation.h" #include "PgCollationContainer.h" #include "Pgsql_oids.h" 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 {}; } 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 QString type_str; if (isSerial() && identity == '\0') { if (typid == Pgsql::int4_oid) type_str = "SERIAL"; else if (typid == Pgsql::int8_oid) type_str = "BIGSERIAL"; } else { type_str = getTypeDisplayString(cat, typid, typmod); } QString sql = quoteIdent(name) % " " % type_str; 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"; auto identity = getIdentity(); auto generated = getGenerated(); if (identity != Identity::None) { sql += " GENERATED "; if (identity == Identity::Always) sql += "ALWAYS"; else if (identity == Identity::ByDefault) sql += "BY DEFAULT"; sql += " AS IDENTITY"; auto sequence = cat.sequences()->getByObjectNsAndName(serschema, sername); auto options_string = sequence->nonDefaultOptionsString(); if (!options_string.isEmpty()) sql += "(" % options_string % ")"; } else if (generated != Generated::None) { if (generated == Generated::Stored) sql += " GENERATED ALWAYS AS " % defaultValue % " STORED"; } else { if (hasdef && !isSerial()) sql += " DEFAULT " % defaultValue; } 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; } QString PgAttribute::commentStatement(const PgDatabaseCatalog &cat, const PgClass &table) const { if (description.isEmpty()) return {}; return "COMMENT ON COLUMN " % table.fullyQualifiedQuotedObjectName() % "." % quoteIdent(name) % " IS " % escapeLiteral(description) % ";"; }