From fd5ad9bbf0d32149a26ed387ae18402c3340b150 Mon Sep 17 00:00:00 2001 From: eelke Date: Sun, 11 Apr 2021 07:56:37 +0200 Subject: [PATCH] On the list of indexes of a table show which were created as part of the creation of a constraint The explicit column is true when the index was manually created In SQL only a comment is given that the index was implicitly created --- pglab/IndexModel.cpp | 17 +++++++++++++-- pglab/IndexModel.h | 1 + pglablib/catalog/PgConstraintContainer.cpp | 18 +++++++++------- pglablib/catalog/PgConstraintContainer.h | 1 + pglablib/catalog/PgIndex.cpp | 25 ++++++++++++++++++++-- pglablib/catalog/PgIndex.h | 14 ++++++------ 6 files changed, 56 insertions(+), 20 deletions(-) diff --git a/pglab/IndexModel.cpp b/pglab/IndexModel.cpp index 9bdb97d..0180f71 100644 --- a/pglab/IndexModel.cpp +++ b/pglab/IndexModel.cpp @@ -36,9 +36,16 @@ int IndexModel::columnCount(const QModelIndex &/*parent*/) const return colCount; } -Oid IndexModel::getType(int /*column*/) const +Oid IndexModel::getType(int column) const { - return Pgsql::varchar_oid; + switch (column) { + case SizeCol: + return Pgsql::int8_oid; + case ExplicitIndexCol: + return Pgsql::bool_oid; + default: + return Pgsql::varchar_oid; + } } QVariant IndexModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -66,6 +73,9 @@ QVariant IndexModel::headerData(int section, Qt::Orientation orientation, int ro case SizeCol: c = tr("Size"); break; + case ExplicitIndexCol: + c = tr("Explicit"); + break; // case DefinitionCol: // c = tr("Definition"); // break; @@ -106,6 +116,9 @@ QVariant IndexModel::getData(const QModelIndex &index) const case SizeCol: v = dat.sizeBytes; break; + case ExplicitIndexCol: + v = !dat.isSupportingIndex(); + break; } return v; } diff --git a/pglab/IndexModel.h b/pglab/IndexModel.h index 43267a3..6281294 100644 --- a/pglab/IndexModel.h +++ b/pglab/IndexModel.h @@ -23,6 +23,7 @@ public: ColumnsCol, /// ConditionCol, SizeCol, + ExplicitIndexCol, colCount }; // oid diff --git a/pglablib/catalog/PgConstraintContainer.cpp b/pglablib/catalog/PgConstraintContainer.cpp index 59d69d7..0b55f20 100644 --- a/pglablib/catalog/PgConstraintContainer.cpp +++ b/pglablib/catalog/PgConstraintContainer.cpp @@ -57,9 +57,6 @@ std::vector PgConstraintContainer::getFKeyForTableColumn(Oid relid std::vector PgConstraintContainer::getConstraintsForRelation(Oid relid) const { std::vector result; -// for (const auto &e : m_container) -// if (e.relid == relid) -// result.push_back(e); std::copy_if(m_container.begin(), m_container.end(), std::back_inserter(result), [relid] (auto && item) { return item.relid == relid; }); return result; @@ -80,10 +77,15 @@ std::optional PgConstraintContainer::getPrimaryForRelation(Oid rel std::vector PgConstraintContainer::getReferencedForRelation(Oid relid) const { std::vector result; -// for (const auto &e : m_container) -// if (e.frelid == relid) -// result.push_back(e); - std::copy_if(m_container.begin(), m_container.end(), std::back_inserter(result), + std::copy_if(m_container.begin(), m_container.end(), std::back_inserter(result), [relid] (auto && item) { return item.frelid == relid; }); - return result; + return result; +} + +std::vector PgConstraintContainer::getSupportedByIndex(Oid indexrelid) const +{ + std::vector result; + std::copy_if(m_container.begin(), m_container.end(), std::back_inserter(result), + [indexrelid] (auto && item) { return item.indid == indexrelid; }); + return result; } diff --git a/pglablib/catalog/PgConstraintContainer.h b/pglablib/catalog/PgConstraintContainer.h index 256fcbe..0d53957 100644 --- a/pglablib/catalog/PgConstraintContainer.h +++ b/pglablib/catalog/PgConstraintContainer.h @@ -18,6 +18,7 @@ public: std::vector getConstraintsForRelation(Oid relid) const; std::optional getPrimaryForRelation(Oid relid) const; std::vector getReferencedForRelation(Oid relid) const; + std::vector getSupportedByIndex(Oid indexrelid) const; protected: virtual PgConstraint loadElem(const Pgsql::Row &row) override; }; diff --git a/pglablib/catalog/PgIndex.cpp b/pglablib/catalog/PgIndex.cpp index 17e8426..991c7ea 100644 --- a/pglablib/catalog/PgIndex.cpp +++ b/pglablib/catalog/PgIndex.cpp @@ -1,6 +1,8 @@ #include "PgIndex.h" #include "PgDatabaseCatalog.h" #include "PgClassContainer.h" +#include "PgConstraint.h" +#include "PgConstraintContainer.h" #include "PgAmContainer.h" #include @@ -19,6 +21,8 @@ QString PgIndex::getAm() const QString PgIndex::createSql() const { + if (isSupportingIndex()) + return "-- implicitly created index"; return definition + ";"; // const PgClass *table_class = catalog.classes()->getByKey(index.relid); @@ -69,7 +73,10 @@ QString PgIndex::createSql() const QString PgIndex::dropSql() const { - QString result; + if (isSupportingIndex()) + return "-- implicitly created index"; + + QString result; result = "DROP INDEX " % fullyQualifiedQuotedObjectName() % ";"; @@ -78,5 +85,19 @@ QString PgIndex::dropSql() const QString PgIndex::typeName() const { - return "INDEX"; + return "INDEX"; +} + +bool PgIndex::isSupportingIndex() const +{ + // This function looks at the supporting index for constaints but this is not completely the + // same thing. For example a fkey is supported by a unique constraint on the referred table but this + // index has not been created as part of the constraint creation so it does not count. + // + // For now we assume that when the constraint and index are on the same table the index was created + // implicitly. + + auto c = catalog().constraints()->getSupportedByIndex(oid()); + auto find_result = std::find_if(c.begin(), c.end(), [this] (auto && item) { return item.relid == relid; }); + return (find_result != c.end()); } diff --git a/pglablib/catalog/PgIndex.h b/pglablib/catalog/PgIndex.h index 1d77422..626066c 100644 --- a/pglablib/catalog/PgIndex.h +++ b/pglablib/catalog/PgIndex.h @@ -9,7 +9,6 @@ class PgIndex : public PgNamespaceObject { public: -// Oid indexrelid = InvalidOid; // oid of pg_class for this index Oid relid = InvalidOid; // oid of table (pg_class) where this is an index on int16_t natts = 0; bool isunique = false; @@ -34,15 +33,14 @@ public: using PgNamespaceObject::PgNamespaceObject; QString getAm() const; -// bool operator==(Oid _oid) const { return indexrelid == _oid; } -// //bool operator==(const QString &n) const { return name == n; } -// bool operator<(Oid _oid) const { return indexrelid < _oid; } -// bool operator<(const PgIndex &rhs) const { return indexrelid < rhs.indexrelid; } - - QString createSql() const; - QString dropSql() const; + QString createSql() const override; + QString dropSql() const override; QString typeName() const override; + + /// Returns true when this index has been created as part of the creation + /// of a constaint. + bool isSupportingIndex() const; }; #endif // PGINDEX_H