New column page
Shows SQL for columns ALTER TABLE ... [ADD|DROP] COLUMN combines a selection of multiple columns into a single alter table. Show collation in list of columns. (order of columns isn't what is should be but that should maybe be fixed by a generic column selection and ordering mechanism that knows what the default sort should be)
This commit is contained in:
parent
73c4cf4790
commit
57217974f4
19 changed files with 345 additions and 55 deletions
|
|
@ -1,2 +1,56 @@
|
|||
#include "PgAttribute.h"
|
||||
#include "QStringBuilder"
|
||||
#include "SqlFormattingUtils.h"
|
||||
#include "PgClass.h"
|
||||
#include "PgDatabaseCatalog.h"
|
||||
#include "PgTypeContainer.h"
|
||||
#include "PgCollation.h"
|
||||
#include "PgCollationContainer.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 sql = quoteIdent(name) % " " % type->name;
|
||||
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";
|
||||
|
||||
if (hasdef)
|
||||
sql += " DEFAULT " % defaultValue;
|
||||
|
||||
if (identity != ' ') {
|
||||
sql += " GENERATED ";
|
||||
if (identity == 'a') sql += "ALWAYS";
|
||||
else if (identity == 'd') sql += "BY DEFAULT";
|
||||
sql += " AS IDENTITY";
|
||||
}
|
||||
// TODO sequence options might be missing
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@
|
|||
#include <libpq-fe.h>
|
||||
#include <tuple>
|
||||
|
||||
class PgClass;
|
||||
class PgDatabaseCatalog;
|
||||
|
||||
class PgAttribute {
|
||||
public:
|
||||
using Key = std::tuple<Oid, int16_t>;
|
||||
|
||||
// Oid oid = InvalidOid;
|
||||
Oid relid = InvalidOid;
|
||||
QString name;
|
||||
Oid typid = InvalidOid;
|
||||
|
|
@ -20,6 +22,7 @@ public:
|
|||
int32_t typmod = -1;
|
||||
bool notnull = false;
|
||||
bool hasdef = false;
|
||||
char identity = ' ';
|
||||
bool isdropped = false;
|
||||
Oid collation = InvalidOid;
|
||||
QString acl;
|
||||
|
|
@ -33,6 +36,10 @@ public:
|
|||
bool operator<(Key _k) const { return relid < std::get<0>(_k) || (relid == std::get<0>(_k) && num < std::get<1>(_k)); }
|
||||
bool operator<(const PgAttribute &rhs) const { return relid < rhs.relid || (relid == rhs.relid && num < rhs.num); }
|
||||
|
||||
/// Return the part of the SQL create statement that can be reused for both the CREATE TABLE and ALTER TABLE ADD COLUMN
|
||||
QString columnDefinition(const PgDatabaseCatalog &cat) const;
|
||||
QString alterTableAddColumn(const PgDatabaseCatalog &cat, const PgClass &table) const;
|
||||
QString alterTableDropColumn(const PgDatabaseCatalog &cat, const PgClass &table) const;
|
||||
};
|
||||
|
||||
#endif // PGATTRIBUTE_H
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "PgAttributeContainer.h"
|
||||
#include "Pgsql_Col.h"
|
||||
#include "PgDatabaseCatalog.h"
|
||||
|
||||
//SELECT attname, pg_get_expr(adbin, adrelid) AS def_value
|
||||
//FROM pg_attribute
|
||||
|
|
@ -8,12 +9,16 @@
|
|||
|
||||
std::string PgAttributeContainer::getLoadQuery() const
|
||||
{
|
||||
return R"__(
|
||||
std::string q = R"__(
|
||||
SELECT attrelid, attname, atttypid, attstattarget,
|
||||
attnum, attndims, atttypmod, attnotnull, atthasdef, attisdropped,
|
||||
attcollation, attacl, attoptions, pg_get_expr(adbin, adrelid) AS def_value
|
||||
FROM pg_catalog.pg_attribute
|
||||
LEFT JOIN pg_attrdef ON attrelid=adrelid AND attnum=adnum)__";
|
||||
attcollation, attacl, attoptions, pg_get_expr(adbin, adrelid) AS def_value)__";
|
||||
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";
|
||||
return q;
|
||||
}
|
||||
|
||||
PgAttribute PgAttributeContainer::loadElem(const Pgsql::Row &row)
|
||||
|
|
@ -23,6 +28,9 @@ PgAttribute PgAttributeContainer::loadElem(const Pgsql::Row &row)
|
|||
col >> v.relid >> v.name >> v.typid >> v.stattarget
|
||||
>> v.num >> v.ndims >> v.typmod >> v.notnull >> v.hasdef >> v.isdropped
|
||||
>> v.collation >> v.acl >> v.options >> v.defaultValue;
|
||||
if (m_catalog.serverVersion() >= 100000)
|
||||
col >> v.identity;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
|
|||
2
pglablib/PgCollation.cpp
Normal file
2
pglablib/PgCollation.cpp
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#include "PgCollation.h"
|
||||
|
||||
25
pglablib/PgCollation.h
Normal file
25
pglablib/PgCollation.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef PGCOLLATION_H
|
||||
#define PGCOLLATION_H
|
||||
|
||||
#include "PgNamespaceObject.h"
|
||||
#include "PgOwnedObject.h"
|
||||
#include <QString>
|
||||
#include <libpq-fe.h>
|
||||
#include "Pgsql_Value.h"
|
||||
//#include <vector>
|
||||
|
||||
class PgCollation: public PgNamespaceObject, public PgOwnedObject {
|
||||
public:
|
||||
using PgNamespaceObject::PgNamespaceObject;
|
||||
|
||||
// Oid oid; // oid
|
||||
// QString collname; // name
|
||||
// Oid collnamespace; // oid
|
||||
// Oid collowner; // oid
|
||||
int32_t collencoding; // integer
|
||||
QString collcollate; // name
|
||||
QString collctype; // name
|
||||
|
||||
};
|
||||
|
||||
#endif // PGCOLLATION_H
|
||||
28
pglablib/PgCollationContainer.cpp
Normal file
28
pglablib/PgCollationContainer.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include "PgCollationContainer.h"
|
||||
#include "Pgsql_Connection.h"
|
||||
#include "Pgsql_Col.h"
|
||||
#include "PgDatabaseCatalog.h"
|
||||
#include <iterator>
|
||||
|
||||
std::string PgCollationContainer::getLoadQuery() const
|
||||
{
|
||||
return "SELECT oid, collname, collnamespace, collowner, collencoding, \n"
|
||||
" collcollate, collctype \n"
|
||||
"FROM pg_collation";
|
||||
}
|
||||
|
||||
PgCollation PgCollationContainer::loadElem(const Pgsql::Row &row)
|
||||
{
|
||||
Pgsql::Col col(row);
|
||||
Oid class_oid = col.nextValue();
|
||||
QString name = col.nextValue();
|
||||
Oid ns_oid = col.nextValue();
|
||||
|
||||
PgCollation v(m_catalog, class_oid, name, ns_oid);
|
||||
Oid owner ;
|
||||
|
||||
col >> owner >> v.collencoding >> v.collcollate >> v.collctype;
|
||||
v.setOwnerOid(m_catalog, owner);
|
||||
|
||||
return v;
|
||||
}
|
||||
25
pglablib/PgCollationContainer.h
Normal file
25
pglablib/PgCollationContainer.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef PGCOLLATIONCONTAINER_H
|
||||
#define PGCOLLATIONCONTAINER_H
|
||||
|
||||
#include "PgContainer.h"
|
||||
#include "PgCollation.h"
|
||||
|
||||
namespace Pgsql {
|
||||
|
||||
class Result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
class PgCollationContainer: public PgContainer<PgCollation> {
|
||||
public:
|
||||
using PgContainer<PgCollation>::PgContainer;
|
||||
|
||||
virtual std::string getLoadQuery() const override;
|
||||
protected:
|
||||
PgCollation loadElem(const Pgsql::Row &row) override;
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif // PGCOLLATIONCONTAINER_H
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
#include "PgTriggerContainer.h"
|
||||
#include "PgTypeContainer.h"
|
||||
#include "PgProcContainer.h"
|
||||
#include "PgCollationContainer.h"
|
||||
#include "Pgsql_Connection.h"
|
||||
#include "Pgsql_oids.h"
|
||||
|
||||
|
|
@ -160,6 +161,9 @@ void PgDatabaseCatalog::loadAll(Pgsql::Connection &conn,
|
|||
|
||||
// Load database objects
|
||||
load2(m_namespaces, conn);
|
||||
if (progress_callback && !progress_callback(++n, count))
|
||||
return;
|
||||
load2(m_collations, conn);
|
||||
if (progress_callback && !progress_callback(++n, count))
|
||||
return;
|
||||
load2(m_classes, conn); // needs namespaces
|
||||
|
|
@ -294,3 +298,8 @@ std::shared_ptr<const PgProcContainer> PgDatabaseCatalog::procs() const
|
|||
{
|
||||
return m_procs;
|
||||
}
|
||||
|
||||
std::shared_ptr<const PgCollationContainer> PgDatabaseCatalog::collations() const
|
||||
{
|
||||
return m_collations;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ class PgTablespaceContainer;
|
|||
class PgTriggerContainer;
|
||||
class PgTypeContainer;
|
||||
class PgProcContainer;
|
||||
class PgCollationContainer;
|
||||
|
||||
|
||||
class PgDatabaseCatalog: public QObject, public std::enable_shared_from_this<PgDatabaseCatalog> {
|
||||
Q_OBJECT
|
||||
|
|
@ -57,6 +59,7 @@ public:
|
|||
std::shared_ptr<const PgTriggerContainer> triggers() const;
|
||||
std::shared_ptr<const PgTypeContainer> types() const;
|
||||
std::shared_ptr<const PgProcContainer> procs() const;
|
||||
std::shared_ptr<const PgCollationContainer> collations() const;
|
||||
|
||||
enum RefreshFlag {
|
||||
Attributes = 1,
|
||||
|
|
@ -94,6 +97,7 @@ private:
|
|||
std::shared_ptr<PgTriggerContainer> m_triggers;
|
||||
std::shared_ptr<PgTypeContainer> m_types;
|
||||
std::shared_ptr<PgProcContainer> m_procs;
|
||||
std::shared_ptr<PgCollationContainer> m_collations;
|
||||
|
||||
template <typename T>
|
||||
void load2(std::shared_ptr<T> &ptr, Pgsql::Connection &conn)
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ bool identNeedsQuotes(QString ident)
|
|||
if (ident[0].isDigit())
|
||||
return true;
|
||||
for (auto c : ident)
|
||||
if ((c < 'a' || c > 'z') && c != '_')
|
||||
if ((c < 'a' || c > 'z') && c != '_' && (c < '0' || c > '9'))
|
||||
return true;
|
||||
|
||||
auto kw = getPgsqlKeyword(ident);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,9 @@ codebuilder/StructureTemplate.cpp \
|
|||
PgDatabaseObject.cpp \
|
||||
PgServerObject.cpp \
|
||||
PgOwnedObject.cpp \
|
||||
PgNamespaceObject.cpp
|
||||
PgNamespaceObject.cpp \
|
||||
PgCollation.cpp \
|
||||
PgCollationContainer.cpp
|
||||
|
||||
HEADERS += \
|
||||
Pglablib.h \
|
||||
|
|
@ -125,7 +127,9 @@ codebuilder/StructureTemplate.h \
|
|||
PgDatabaseObject.h \
|
||||
PgServerObject.h \
|
||||
PgOwnedObject.h \
|
||||
PgNamespaceObject.h
|
||||
PgNamespaceObject.h \
|
||||
PgCollation.h \
|
||||
PgCollationContainer.h
|
||||
|
||||
unix {
|
||||
target.path = /usr/lib
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue