From 2c2253f75e1da3b3bfd7ec0383dac9c76cbd5623 Mon Sep 17 00:00:00 2001 From: eelke Date: Sun, 1 Dec 2019 06:40:11 +0100 Subject: [PATCH] Use (BIG)SERIAL in generated SQL when this was used when column originally defined. This is recognized by the fact that the column has a dependency on a sequence. For columns that happen to have a default which uses a pre exising sequence the dependency is the other way around. --- pglablib/catalog/PgAttribute.cpp | 17 ++++++++++++++--- pglablib/catalog/PgAttribute.h | 4 +++- pglablib/catalog/PgAttributeContainer.cpp | 14 +++++++++----- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/pglablib/catalog/PgAttribute.cpp b/pglablib/catalog/PgAttribute.cpp index 3e697d8..81b3d97 100644 --- a/pglablib/catalog/PgAttribute.cpp +++ b/pglablib/catalog/PgAttribute.cpp @@ -6,15 +6,26 @@ #include "PgTypeContainer.h" #include "PgCollation.h" #include "PgCollationContainer.h" +#include "Pgsql_oids.h" 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 - auto&& type = cat.types()->getByKey(typid); + QString type_str; + if (isSerial()) { + if (typid == Pgsql::int4_oid) + type_str = "SERIAL"; + else if (typid == Pgsql::int8_oid) + type_str = "BIGSERIAL"; + } + else { + auto&& type = cat.types()->getByKey(typid); + type_str = type->objectName(); + } - QString sql = quoteIdent(name) % " " % type->objectName(); + QString sql = quoteIdent(name) % " " % type_str; if (collation != InvalidOid) { auto&& col = cat.collations()->getByKey(collation); QString oname = col->objectName(); @@ -25,7 +36,7 @@ QString PgAttribute::columnDefinition(const PgDatabaseCatalog &cat) const if (notnull) sql += " NOT NULL"; - if (hasdef) + if (hasdef && !isSerial()) sql += " DEFAULT " % defaultValue; if (identity != '\0') { diff --git a/pglablib/catalog/PgAttribute.h b/pglablib/catalog/PgAttribute.h index de887b2..7fdf269 100644 --- a/pglablib/catalog/PgAttribute.h +++ b/pglablib/catalog/PgAttribute.h @@ -30,7 +30,7 @@ public: QString options; QString defaultValue; ///< Comes from pg_attrdef table - + QString sername, serschema; // serial sequence name and schema bool operator==(Key _k) const { return relid == std::get<0>(_k) && num == std::get<1>(_k); } bool operator==(const QString &n) const { return name == n; } @@ -41,6 +41,8 @@ public: QString columnDefinition(const PgDatabaseCatalog &cat) const; QString alterTableAddColumn(const PgDatabaseCatalog &cat, const PgClass &table) const; QString alterTableDropColumn(const PgDatabaseCatalog &cat, const PgClass &table) const; + + bool isSerial() const { return !sername.isEmpty(); } }; #endif // PGATTRIBUTE_H diff --git a/pglablib/catalog/PgAttributeContainer.cpp b/pglablib/catalog/PgAttributeContainer.cpp index 9806836..4396a92 100644 --- a/pglablib/catalog/PgAttributeContainer.cpp +++ b/pglablib/catalog/PgAttributeContainer.cpp @@ -12,12 +12,15 @@ std::string PgAttributeContainer::getLoadQuery() const std::string q = R"__( SELECT attrelid, attname, atttypid, attstattarget, attnum, attndims, atttypmod, attnotnull, atthasdef, attisdropped, - attislocal, attcollation, attacl, attoptions, pg_get_expr(adbin, adrelid) AS def_value)__"; + attislocal, attcollation, attacl, attoptions, pg_get_expr(def.adbin, def.adrelid) AS def_value, cs.relname AS sername, ns.nspname AS serschema)__"; if (m_catalog.serverVersion() >= 100000) q += ", attidentity"; - q += - "\n FROM pg_catalog.pg_attribute \n" - " LEFT JOIN pg_attrdef ON attrelid=adrelid AND attnum=adnum"; + q += R"__( + FROM pg_catalog.pg_attribute AS att + LEFT JOIN pg_attrdef AS def ON attrelid=adrelid AND attnum=adnum + LEFT JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum + LEFT JOIN pg_namespace ns ON ns.oid=cs.relnamespace)__"; + return q; } @@ -27,7 +30,8 @@ PgAttribute PgAttributeContainer::loadElem(const Pgsql::Row &row) PgAttribute v; col >> v.relid >> v.name >> v.typid >> v.stattarget >> v.num >> v.ndims >> v.typmod >> v.notnull >> v.hasdef >> v.isdropped - >> v.islocal >> v.collation >> v.acl >> v.options >> v.defaultValue; + >> v.islocal >> v.collation >> v.acl >> v.options >> v.defaultValue + >> v.sername >> v.serschema; if (m_catalog.serverVersion() >= 100000) col >> v.identity;