Auf SQL-Ebene ist dies nicht möglich, da alle diese Aufgaben vom Tabellenbesitz abhängen.
Der CREATE
Wert für einen Tabellenbereich ist erforderlich , reicht jedoch nicht aus , um einen Index für eine Tabelle zu erstellen und den Index in diesem Tabellenbereich zu speichern. Wenn Sie nicht über das CREATE
Recht für den Tabellenbereich verfügen, in den Sie den Index einfügen möchten, können Sie CREATE INDEX
diesen Index nicht verwenden. Dieses Recht zu haben, reicht jedoch nicht aus. Andernfalls könnte jeder Index für jede Tabelle erstellen, wenn er das Recht hätte, irgendetwas in einem beliebigen Tabellenbereich zu erstellen, und das wollen wir nicht. Indizes haben Leistungskosten, nehmen während der Erstellung schwere Sperren in Anspruch, und vielleicht am wichtigsten ist, dass ein Ausdrucksindex über eine böswillige Funktion oder einen böswilligen Operator Daten über die Tabelle verlieren kann. Sie müssen also auch die Tabelle besitzen, für die der Index erstellt werden soll.
Die Unterstützung für ein separates INDEX
Recht für eine Tabelle könnte zu PostgreSQL hinzugefügt werden, wurde jedoch nicht unterstützt und wird möglicherweise nicht akzeptiert, wenn sie eingereicht wird. Im Moment müssen Sie den Tisch nicht mehr besitzen.
Sie können eine C-Erweiterung schreiben, die eine installiert ProcessUtility_hook
, die überprüft, welche Vorgänge ausgeführt werden, und die aktuelle Benutzeridentität, und diese dann ablehnt oder gegebenenfalls zulässt. Beispiele für die ProcessUtility_hook
Verwendung in contrib/sepgsql
und extern in der bdr_commandfilter.c
Datei finden Sie im Quellcode des BDR-Projekts. Sie müssen die Erweiterung kompilieren, im Dateisystem installieren und dann hinzufügen, um sie zu shared_preload_libraries
installieren. Daher benötigen Sie vollständigen Zugriff auf den Server auf Dateisystemebene und normalerweise Root-Zugriff.
Ein praktischerer Ansatz besteht darin, eine SECURITY DEFINER
Funktion als Wrapper zu verwenden. Schreiben Sie eine PL / PgSQL-Funktion, die als Tabelleneigentümer ausgeführt wird und die zu indizierende Tabelle, die zu indizierenden Spalten usw. als Argumente akzeptiert. Lassen Sie den CREATE INDEX
Ausdruck erstellen format(...)
und übergeben Sie ihn dann an EXECUTE
. Haben nicht erlauben dem Benutzer , beliebige SQL - Ausdrücke als Argumente zu übergeben, oder du bist im Grunde ihnen vollen Zugriff über SQL - Injection zu geben. Willst du mehrere Spalten? Sie müssen colname text[]
als Argument und quote_ident
jedes akzeptieren . Und so weiter. Suchen Sie nach "dynamic SQL plpgsql", um mehr über diesen Ansatz zu erfahren.
CONCURRENTLY
häufig der richtige Weg ist, um ein Blockieren zu vermeiden. Dies ist aus einer Funktion leider nicht möglich.Obwohl plpgsql- Ereignisauslöser in aktuellen Versionen ziemlich begrenzt sind, können Sie das besondere Ergebnis erzielen, wenn Sie nur
DROP TABLE
mit ihnen nicht zulassen .Bedenken Sie:
Als Benutzer postgres (Superuser):
Auf der anderen Seite
CREATE INDEX
funktioniert:quelle