Fixes to indexes and constraints to be shown properly in OE (#463)

Addresses issues described in microsoft/azuredatastudio-postgresql#452 and microsoft/azuredatastudio-postgresql#453.

- Indexes should now show scripting options regardless of if they are unique or not
- Indexes will not show primary key, but this will show up in constraints. This is following the pattern of PgAdmin
- Constraints should properly show the associated constraints
    1. Check constraints
    2. Exclusion constraints
    3. Index constraints (primary key and unique key)
    4. Foreign key constraints
- Template files were updated for all constraint types
This commit is contained in:
samir-puranik 2023-08-23 13:29:39 -04:00 коммит произвёл GitHub
Родитель f3f941ccaa
Коммит eec418ec10
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
79 изменённых файлов: 525 добавлений и 509 удалений

Просмотреть файл

@ -332,8 +332,10 @@ def _constraints(is_refresh: bool, current_path: str, session: ObjectExplorerSes
for node in table.exclusion_constraints])
node_info.extend([_get_node_info(node, current_path, 'Key_ForeignKey')
for node in table.foreign_key_constraints])
node_info.extend([_get_node_info(node, current_path, 'Constraint')
for node in table.index_constraints])
node_info.extend([_get_node_info(node, current_path, 'Key_PrimaryKey')
for node in table.primary_key_constraints])
node_info.extend([_get_node_info(node, current_path, 'Key_UniqueKey')
for node in table.unique_key_constraints])
return sorted(node_info, key=lambda x: x.label)
@ -361,13 +363,13 @@ def _indexes(is_refresh: bool, current_path: str, session: ObjectExplorerSession
for index in indexes:
attribs = ['Clustered' if index.is_clustered else 'Non-Clustered']
if index.is_primary:
node_type = 'Key_PrimaryKey'
elif index.is_unique:
node_type = 'Key_UniqueKey'
# TODO: Add back in the correct node_type, but making sure the SCRIPT AS options still appear in the right-click menu
# if index.is_primary:
# node_type = 'Key_PrimaryKey'
if index.is_unique:
# node_type = 'Key_UniqueKey'
attribs.insert(0, 'Unique')
else:
node_type = 'Index'
node_type = 'Index'
attrib_str = '(' + ', '.join(attribs) + ')'
yield _get_node_info(index, current_path, node_type, label=f'{index.name} {attrib_str}')

Просмотреть файл

@ -12,7 +12,9 @@ from pgsmo.objects.table_objects.constraints import (
CheckConstraint,
ExclusionConstraint,
ForeignKeyConstraint,
IndexConstraint
IndexConstraint,
PrimaryKeyConstraint,
UniqueKeyConstraint
)
from pgsmo.objects.table_objects.constraints_utils import (
get_index_constraints,
@ -63,13 +65,27 @@ class Table(NodeObject, ScriptableCreate, ScriptableDelete, ScriptableUpdate, Sc
# Declare child items
self._check_constraints: NodeCollection[CheckConstraint] = self._register_child_collection(CheckConstraint)
self._columns: NodeCollection[Column] = self._register_child_collection(Column)
# Constraints
self._exclusion_constraints: NodeCollection[ExclusionConstraint] = self._register_child_collection(
ExclusionConstraint
)
self._foreign_key_constraints: NodeCollection[ForeignKeyConstraint] = self._register_child_collection(
ForeignKeyConstraint
)
self._primary_key_constraints: NodeCollection[PrimaryKeyConstraint] = self._register_child_collection(
PrimaryKeyConstraint,
context_args={"constraint_type": "p"}
)
self._unique_key_constraints: NodeCollection[UniqueKeyConstraint] = self._register_child_collection(
UniqueKeyConstraint,
context_args={"constraint_type": "u"}
)
# Index constraints should be comprised of primary key constraints ("p"), unique key constraints ("u"), and exclusion constraints ("x"). Exclusion
# constraints have their own separate templates, while primary key and unique key constraints share templates from constraint_index
self._index_constraints: NodeCollection[IndexConstraint] = self._register_child_collection(IndexConstraint)
self._indexes: NodeCollection[Index] = self._register_child_collection(Index)
self._rules: NodeCollection[Rule] = self._register_child_collection(Rule)
self._triggers: NodeCollection[Trigger] = self._register_child_collection(Trigger)
@ -113,6 +129,14 @@ class Table(NodeObject, ScriptableCreate, ScriptableDelete, ScriptableUpdate, Sc
def index_constraints(self) -> NodeCollection[IndexConstraint]:
return self._index_constraints
@property
def primary_key_constraints(self) -> NodeCollection[PrimaryKeyConstraint]:
return self._primary_key_constraints
@property
def unique_key_constraints(self) -> NodeCollection[UniqueKeyConstraint]:
return self._unique_key_constraints
@property
def indexes(self) -> NodeCollection[Index]:
return self._indexes

Просмотреть файл

@ -5,11 +5,13 @@
# This software is released under the PostgreSQL Licence
#}
{% if data %}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} CHECK ({{ data.consrc }});
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} CHECK ({{ data.consrc }}){% if data.convalidated %}
NOT VALID{% endif %}{% if data.connoinherit %} NO INHERIT{% endif %};
{% endif %}
{% if data.comment %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
{% endif %}
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}

Просмотреть файл

@ -5,5 +5,5 @@
# This software is released under the PostgreSQL Licence
#}
{% if data %}
ALTER TABLE {{ conn|qtIdent(data.nspname, data.relname) }} DROP CONSTRAINT {{ conn|qtIdent(data.name) }};
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.nspname, data.relname) }} DROP CONSTRAINT IF EXISTS {{ conn|qtIdent(data.name) }};
{% endif %}

Просмотреть файл

@ -4,7 +4,8 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT conname as name
FROM pg_constraint ct
SELECT conname as name,
NOT convalidated as convalidated
FROM pg_catalog.pg_constraint ct
WHERE contype = 'c'
AND ct.oid = {{cid}}::oid
AND ct.oid = {{cid}}::oid

Просмотреть файл

@ -5,9 +5,10 @@
# This software is released under the PostgreSQL Licence
#}
SELECT
oid, conname as name
oid, conname as name,
NOT convalidated as convalidated
FROM
pg_constraint
pg_catalog.pg_constraint
WHERE
conrelid = {{tid}}::oid
AND conname={{ name }};
AND conname={{ name|qtLiteral(conn) }};

Просмотреть файл

@ -5,7 +5,9 @@
# This software is released under the PostgreSQL Licence
#}
SELECT ct.oid,
ct.conname as name
FROM pg_constraint ct
ct.conname as name,
NOT convalidated as convalidated
FROM pg_catalog.pg_constraint ct
WHERE contype='c' AND
conrelid = {{tid}}::oid LIMIT 1;
conrelid = {{tid}}::oid
ORDER BY ct.oid DESC LIMIT 1;

Просмотреть файл

@ -7,7 +7,7 @@
SELECT nsp.nspname AS schema,
rel.relname AS table
FROM
pg_class rel
JOIN pg_namespace nsp
pg_catalog.pg_class rel
JOIN pg_catalog.pg_namespace nsp
ON rel.relnamespace = nsp.oid::oid
WHERE rel.oid = {{tid}}::oid
WHERE rel.oid = {{tid}}::oid

Просмотреть файл

@ -5,9 +5,13 @@
# This software is released under the PostgreSQL Licence
#}
SELECT c.oid, conname as name,
NOT convalidated as convalidated
FROM pg_constraint c
NOT convalidated as convalidated, conislocal, description as comment
FROM pg_catalog.pg_constraint c
LEFT OUTER JOIN
pg_catalog.pg_description des ON (des.objoid=c.oid AND
des.classoid='pg_constraint'::regclass)
WHERE contype = 'c'
{% if tid %}
AND conrelid = {{ parent_id }}::oid
{% if cid %}
AND c.oid = {{ cid }}::oid
{% endif %}

Просмотреть файл

@ -4,16 +4,17 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT c.oid, conname as name, relname, nspname, description as comment ,
pg_get_expr(conbin, conrelid, true) as consrc
FROM pg_constraint c
JOIN pg_class cl ON cl.oid=conrelid
JOIN pg_namespace nl ON nl.oid=relnamespace
SELECT c.oid, conname as name, relname, nspname, description as comment,
pg_catalog.pg_get_expr(conbin, conrelid, true) as consrc,
connoinherit, NOT convalidated as convalidated, conislocal
FROM pg_catalog.pg_constraint c
JOIN pg_catalog.pg_class cl ON cl.oid=conrelid
JOIN pg_catalog.pg_namespace nl ON nl.oid=relnamespace
LEFT OUTER JOIN
pg_description des ON (des.objoid=c.oid AND
pg_catalog.pg_description des ON (des.objoid=c.oid AND
des.classoid='pg_constraint'::regclass)
WHERE contype = 'c'
AND conrelid = {{ tid }}::oid
{% if cid %}
AND c.oid = {{ cid }}::oid
{% endif %}
{% endif %}

Просмотреть файл

@ -4,7 +4,16 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
{% if data %}
{% if data.name != o_data.name %}
ALTER TABLE IF EXISTS {{ conn|qtIdent(o_data.nspname, data.table) }}
RENAME CONSTRAINT {{ conn|qtIdent(o_data.name) }} TO {{ conn|qtIdent(data.name) }};{% endif -%}
{% if 'convalidated' in data and o_data.convalidated != data.convalidated and not data.convalidated %}
ALTER TABLE IF EXISTS {{ conn|qtIdent(o_data.nspname, data.table) }}
VALIDATE CONSTRAINT {{ conn|qtIdent(data.name) }};{% endif -%}
{% if data.comment is defined and data.comment != o_data.comment %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(o_data.name) }} ON {{ conn|qtIdent(o_data.nspname, o_data.relname) }}
IS {{ data.comment }};
{% endif %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(o_data.nspname, data.table) }}
IS {{ data.comment|qtLiteral(conn) }};{% endif %}
{% endif -%}

Просмотреть файл

@ -4,5 +4,5 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
VALIDATE CONSTRAINT {{ conn|qtIdent(data.name) }};
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
VALIDATE CONSTRAINT {{ conn|qtIdent(data.name) }};

Просмотреть файл

@ -1,17 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
{% if data %}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} CHECK ({{ data.consrc }}){% if data.convalidated %}
NOT VALID{% endif %}{% if data.connoinherit %} NO INHERIT{% endif %};
{% endif %}
{% if data.comment %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
{% endif %}

Просмотреть файл

@ -1,11 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT conname as name,
NOT convalidated as convalidated
FROM pg_constraint ct
WHERE contype = 'c'
AND ct.oid = {{cid}}::oid

Просмотреть файл

@ -1,14 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT
oid, conname as name,
NOT convalidated as convalidated
FROM
pg_constraint
WHERE
conrelid = {{tid}}::oid
AND conname={{ name }};

Просмотреть файл

@ -1,12 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT ct.oid,
ct.conname as name,
NOT convalidated as convalidated
FROM pg_constraint ct
WHERE contype='c' AND
conrelid = {{tid}}::oid LIMIT 1;

Просмотреть файл

@ -1,13 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT c.oid, conname as name,
NOT convalidated as convalidated
FROM pg_constraint c
WHERE contype = 'c'
{% if tid %}
AND conrelid = {{ parent_id }}::oid
{% endif %}

Просмотреть файл

@ -1,20 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT c.oid, conname as name, relname, nspname, description as comment,
pg_get_expr(conbin, conrelid, true) as consrc,
connoinherit, NOT convalidated as convalidated
FROM pg_constraint c
JOIN pg_class cl ON cl.oid=conrelid
JOIN pg_namespace nl ON nl.oid=relnamespace
LEFT OUTER JOIN
pg_description des ON (des.objoid=c.oid AND
des.classoid='pg_constraint'::regclass)
WHERE contype = 'c'
AND conrelid = {{ tid }}::oid
{% if cid %}
AND c.oid = {{ cid }}::oid
{% endif %}

Просмотреть файл

@ -1,19 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
{% if data %}
{% if data.name != o_data.name %}
ALTER TABLE {{ conn|qtIdent(o_data.nspname, data.table) }}
RENAME CONSTRAINT {{ conn|qtIdent(o_data.name) }} TO {{ conn|qtIdent(data.name) }};{% endif -%}
{% if 'convalidated' in data and o_data.convalidated != data.convalidated and not data.convalidated %}
ALTER TABLE {{ conn|qtIdent(o_data.nspname, data.table) }}
VALIDATE CONSTRAINT {{ conn|qtIdent(data.name) }};{% endif -%}
{% if data.comment is defined and data.comment != o_data.comment %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(o_data.nspname, data.table) }}
IS {{ data.comment }};{% endif %}
{% endif -%}

Просмотреть файл

@ -1 +1,7 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
BEGIN;

Просмотреть файл

@ -4,20 +4,22 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} EXCLUDE {% if data.amname and data.amname != '' %}USING {{data.amname}}{% endif %} (
{% for col in data.columns %}{% if loop.index != 1 %},
{% endif %}{{ conn|qtIdent(col.column)}}{% if col.oper_class and col.oper_class != '' %} {{col.oper_class}}{% endif%}{% if col.order is defined and col.is_sort_nulls_applicable %}{% if col.order %} ASC{% else %} DESC{% endif %} NULLS{% endif %} {% if col.nulls_order is defined and col.is_sort_nulls_applicable %}{% if col.nulls_order %}FIRST {% else %}LAST {% endif %}{% endif %}WITH {{col.operator}}{% endfor %}){% if data.fillfactor %}
{% endif %}{% if col.is_exp %}{{col.column}}{% else %}{{ conn|qtIdent(col.column)}}{% endif %}{% if col.oper_class and col.oper_class != '' %} {{col.oper_class}}{% endif%}{% if col.order is defined and col.is_sort_nulls_applicable %}{% if col.order %} ASC{% else %} DESC{% endif %} NULLS{% endif %} {% if col.nulls_order is defined and col.is_sort_nulls_applicable %}{% if col.nulls_order %}FIRST {% else %}LAST {% endif %}{% endif %}WITH {{col.operator}}{% endfor %}){% if data.fillfactor %}
WITH (FILLFACTOR={{data.fillfactor}}){% endif %}{% if data.spcname and data.spcname != "pg_default" %}
USING INDEX TABLESPACE {{ conn|qtIdent(data.spcname) }}{% endif %}
USING INDEX TABLESPACE {{ conn|qtIdent(data.spcname) }}{% endif %}{% if data.indconstraint %}
WHERE ({{data.indconstraint}}){% endif%}
{% if data.condeferrable %}
DEFERRABLE{% if data.condeferred %}
INITIALLY DEFERRED{% endif%}
{% endif%}{% if data.constraint %} WHERE ({{data.constraint}}){% endif%};
INITIALLY DEFERRED{% endif%}{% endif%};
{% if data.comment and data.name %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
{% endif %}
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}

Просмотреть файл

@ -5,5 +5,5 @@
# This software is released under the PostgreSQL Licence
#}
{% if data %}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }} DROP CONSTRAINT {{ conn|qtIdent(data.name) }}{% if cascade%} CASCADE{% endif %};
{% endif %}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }} DROP CONSTRAINT IF EXISTS {{ conn|qtIdent(data.name) }}{% if cascade%} CASCADE{% endif %};
{% endif %}

Просмотреть файл

@ -1 +1,7 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
END;

Просмотреть файл

@ -5,8 +5,8 @@
# This software is released under the PostgreSQL Licence
#}
SELECT amname
FROM pg_am
FROM pg_catalog.pg_am
WHERE EXISTS (SELECT 1
FROM pg_proc
WHERE oid=amgettuple)
ORDER BY amname;
FROM pg_catalog.pg_proc
WHERE oid=amhandler)
ORDER BY amname;

Просмотреть файл

@ -10,19 +10,20 @@ UNION
{% endif %}
SELECT
i.indoption[{{loop.index -1}}] AS options,
pg_get_indexdef(i.indexrelid, {{loop.index}}, true) AS coldef,
pg_catalog.pg_get_indexdef(i.indexrelid, {{loop.index}}, true) AS coldef,
op.oprname,
CASE WHEN (o.opcdefault = FALSE) THEN o.opcname ELSE null END AS opcname
,
coll.collname,
nspc.nspname as collnspname,
format_type(ty.oid,NULL) AS col_type
FROM pg_index i
JOIN pg_attribute a ON (a.attrelid = i.indexrelid AND attnum = {{loop.index}})
JOIN pg_type ty ON ty.oid=a.atttypid
LEFT OUTER JOIN pg_opclass o ON (o.oid = i.indclass[{{loop.index -1}}])
LEFT OUTER JOIN pg_constraint c ON (c.conindid = i.indexrelid) LEFT OUTER JOIN pg_operator op ON (op.oid = c.conexclop[{{loop.index}}])
LEFT OUTER JOIN pg_collation coll ON a.attcollation=coll.oid
LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid
pg_catalog.format_type(ty.oid,NULL) AS datatype,
CASE WHEN pg_catalog.pg_get_indexdef(i.indexrelid, {{loop.index}}, true) = a.attname THEN FALSE ELSE TRUE END AS is_exp
FROM pg_catalog.pg_index i
JOIN pg_catalog.pg_attribute a ON (a.attrelid = i.indexrelid AND attnum = {{loop.index}})
JOIN pg_catalog.pg_type ty ON ty.oid=a.atttypid
LEFT OUTER JOIN pg_catalog.pg_opclass o ON (o.oid = i.indclass[{{loop.index -1}}])
LEFT OUTER JOIN pg_catalog.pg_constraint c ON (c.conindid = i.indexrelid) LEFT OUTER JOIN pg_catalog.pg_operator op ON (op.oid = c.conexclop[{{loop.index}}])
LEFT OUTER JOIN pg_catalog.pg_collation coll ON a.attcollation=coll.oid
LEFT OUTER JOIN pg_catalog.pg_namespace nspc ON coll.collnamespace=nspc.oid
WHERE i.indexrelid = {{cid}}::oid
{% endfor %}
{% endfor %}

Просмотреть файл

@ -5,5 +5,5 @@
# This software is released under the PostgreSQL Licence
#}
SELECT conname as name
FROM pg_constraint ct
WHERE ct.conindid = {{cid}}::oid
FROM pg_catalog.pg_constraint ct
WHERE ct.conindid = {{cid}}::oid

Просмотреть файл

@ -5,6 +5,6 @@
# This software is released under the PostgreSQL Licence
#}
SELECT ct.conindid AS oid
FROM pg_constraint ct
FROM pg_catalog.pg_constraint ct
WHERE contype='x' AND
ct.conname = {{ name }};
ct.conname = {{ name|qtLiteral(conn) }};

Просмотреть файл

@ -7,6 +7,7 @@
SELECT ct.conindid AS oid,
ct.conname AS name,
NOT convalidated AS convalidated
FROM pg_constraint ct
FROM pg_catalog.pg_constraint ct
WHERE contype='x' AND
conrelid = {{tid}}::oid LIMIT 1;
conrelid = {{tid}}::oid
ORDER BY oid DESC LIMIT 1;

Просмотреть файл

@ -5,9 +5,9 @@
# This software is released under the PostgreSQL Licence
#}
SELECT opcname
FROM pg_opclass opc,
pg_am am
FROM pg_catalog.pg_opclass opc,
pg_catalog.pg_am am
WHERE opcmethod=am.oid AND
am.amname ={{indextype}} AND
am.amname ={{indextype|qtLiteral(conn)}} AND
NOT opcdefault
ORDER BY 1
ORDER BY 1

Просмотреть файл

@ -4,32 +4,39 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
{% if type is not none %}
SELECT DISTINCT op.oprname as oprname
FROM pg_operator op,
FROM pg_catalog.pg_operator op,
( SELECT oid
FROM (SELECT format_type(t.oid,NULL) AS typname,
FROM (SELECT pg_catalog.format_type(t.oid,NULL) AS typname,
t.oid as oid
FROM pg_type t
JOIN pg_namespace nsp ON typnamespace=nsp.oid
FROM pg_catalog.pg_type t
JOIN pg_catalog.pg_namespace nsp ON typnamespace=nsp.oid
WHERE (NOT (typname = 'unknown' AND nspname = 'pg_catalog')) AND
typisdefined AND
typtype IN ('b', 'c', 'd', 'e', 'r') AND
NOT EXISTS (SELECT 1
FROM pg_class
FROM pg_catalog.pg_class
WHERE relnamespace=typnamespace AND
relname = typname AND
relkind != 'c') AND
(typname NOT LIKE '_%' OR
NOT EXISTS (SELECT 1
FROM pg_class
FROM pg_catalog.pg_class
WHERE relnamespace=typnamespace AND
relname = SUBSTRING(typname FROM 2)::name AND
relkind != 'c'))
{% if not show_sysobj %}
AND nsp.nspname != 'information_schema'
{% endif %}
UNION SELECT 'smallserial', 0
UNION SELECT 'bigserial', 0
UNION SELECT 'serial', 0) t1
WHERE typname = {{type}}) AS types
WHERE typname = {{type|qtLiteral(conn)}}) AS types
WHERE oprcom > 0 AND
(op.oprleft=types.oid OR op.oprright=types.oid)
(op.oprleft=types.oid OR op.oprright=types.oid)
{% else %}
SELECT DISTINCT op.oprname as oprname
FROM pg_catalog.pg_operator op
WHERE oprcom > 0
{% endif %}

Просмотреть файл

@ -7,7 +7,7 @@
SELECT nsp.nspname AS schema,
rel.relname AS table
FROM
pg_class rel
JOIN pg_namespace nsp
pg_catalog.pg_class rel
JOIN pg_catalog.pg_namespace nsp
ON rel.relnamespace = nsp.oid::oid
WHERE rel.oid = {{tid}}::oid
WHERE rel.oid = {{tid}}::oid

Просмотреть файл

@ -6,11 +6,13 @@
#}
SELECT conindid as oid,
conname as name,
NOT convalidated as convalidated
FROM pg_constraint ct
NOT convalidated as convalidated,
desp.description AS comment
FROM pg_catalog.pg_constraint ct
LEFT OUTER JOIN pg_catalog.pg_description desp ON (desp.objoid=ct.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
WHERE contype='x' AND
conrelid = {{parent_id}}::oid
{% if exid %}
AND conindid = {{exid}}::oid
{% endif %}
ORDER BY conname
ORDER BY conname

Просмотреть файл

@ -6,11 +6,11 @@
#}
SELECT cls.oid,
cls.relname as name,
indnatts,
indnatts as col_count,
amname,
CASE WHEN length(spcname) > 0 THEN spcname ELSE
(SELECT sp.spcname FROM pg_database dtb
JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid
CASE WHEN length(spcname::text) > 0 THEN spcname ELSE
(SELECT sp.spcname FROM pg_catalog.pg_database dtb
JOIN pg_catalog.pg_tablespace sp ON dtb.dattablespace=sp.oid
WHERE dtb.oid = {{ did }}::oid)
END as spcname,
CASE contype
@ -21,20 +21,19 @@ SELECT cls.oid,
END AS comment,
condeferrable,
condeferred,
substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace
JOIN pg_namespace n ON n.oid=tab.relnamespace
JOIN pg_am am ON am.oid=cls.relam
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
substring(pg_catalog.array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor,
pg_catalog.pg_get_expr(idx.indpred, idx.indrelid, true) AS indconstraint
FROM pg_catalog.pg_index idx
JOIN pg_catalog.pg_class cls ON cls.oid=indexrelid
LEFT OUTER JOIN pg_catalog.pg_tablespace ta on ta.oid=cls.reltablespace
JOIN pg_catalog.pg_am am ON am.oid=cls.relam
LEFT JOIN pg_catalog.pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_catalog.pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_catalog.pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_catalog.pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
WHERE indrelid = {{tid}}::oid
{% if cid %}
AND cls.oid = {{cid}}::oid
{% endif %}
AND contype='x'
ORDER BY cls.relname
ORDER BY cls.relname

Просмотреть файл

@ -10,7 +10,7 @@ SELECT
idx_tup_fetch AS {{ conn|qtIdent(_('Index tuples fetched')) }},
idx_blks_read AS {{ conn|qtIdent(_('Index blocks read')) }},
idx_blks_hit AS {{ conn|qtIdent(_('Index blocks hit')) }},
pg_relation_size({{ exid }}::OID) AS {{ conn|qtIdent(_('Index size')) }}
pg_catalog.pg_relation_size({{ exid }}::OID) AS {{ conn|qtIdent(_('Index size')) }}
{#=== Extended stats ===#}
{% if is_pgstattuple %}
,version AS {{ conn|qtIdent(_('Version')) }},
@ -24,11 +24,11 @@ SELECT
avg_leaf_density AS {{ conn|qtIdent(_('Average leaf density')) }},
leaf_fragmentation AS {{ conn|qtIdent(_('Leaf fragmentation')) }}
FROM
pgstatindex('{{conn|qtIdent(schema)}}.{{conn|qtIdent(name)}}'), pg_stat_all_indexes stat
pgstatindex('{{conn|qtIdent(schema)}}.{{conn|qtIdent(name)}}'), pg_catalog.pg_stat_all_indexes stat
{% else %}
FROM
pg_stat_all_indexes stat
pg_catalog.pg_stat_all_indexes stat
{% endif %}
JOIN pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid
JOIN pg_class cl ON cl.oid=stat.indexrelid
JOIN pg_catalog.pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid
JOIN pg_catalog.pg_class cl ON cl.oid=stat.indexrelid
WHERE stat.indexrelid = {{ exid }}::OID

Просмотреть файл

@ -8,21 +8,25 @@
{% if data %}
{# ==== To update exclusion constraint name ==== #}
{% if data.name != o_data.name %}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
RENAME CONSTRAINT {{ conn|qtIdent(o_data.name) }} TO {{ conn|qtIdent(data.name) }};
{% endif %}
{# ==== To update exclusion constraint tablespace ==== #}
{% if data.spcname and data.spcname != o_data.spcname %}
ALTER INDEX {{ conn|qtIdent(data.schema, data.name) }}
ALTER INDEX IF EXISTS {{ conn|qtIdent(data.schema, data.name) }}
SET TABLESPACE {{ conn|qtIdent(data.spcname) }};
{% endif %}
{% if data.fillfactor and data.fillfactor != o_data.fillfactor %}
ALTER INDEX {{ conn|qtIdent(data.schema, data.name) }}
ALTER INDEX IF EXISTS {{ conn|qtIdent(data.schema, data.name) }}
SET (FILLFACTOR={{ data.fillfactor }});
{% endif %}
{% if data.fillfactor == "" and data.fillfactor != o_data.fillfactor %}
ALTER INDEX IF EXISTS {{ conn|qtIdent(data.schema, data.name) }}
RESET (FILLFACTOR);
{% endif %}
{# ==== To update exclusion constraint comments ==== #}
{% if data.comment is defined and data.comment != o_data.comment %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}
{% endif %}
{% endif %}

Просмотреть файл

@ -4,17 +4,17 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} EXCLUDE {% if data.amname and data.amname != '' %}USING {{data.amname}}{% endif %} (
{% for col in data.columns %}{% if loop.index != 1 %},
{% endif %}{{ conn|qtIdent(col.column)}}{% if col.oper_class and col.oper_class != '' %} {{col.oper_class}}{% endif%}{% if col.order is defined and col.is_sort_nulls_applicable %}{% if col.order %} ASC{% else %} DESC{% endif %} NULLS{% endif %} {% if col.nulls_order is defined and col.is_sort_nulls_applicable %}{% if col.nulls_order %}FIRST {% else %}LAST {% endif %}{% endif %}WITH {{col.operator}}{% endfor %})
{% if data.include|length > 0 %}
INCLUDE({% for col in data.include %}{% if loop.index != 1 %}, {% endif %}{{conn|qtIdent(col)}}{% endfor %}){% endif %}
{% if data.fillfactor %}
{% endif %}{% if col.is_exp %}{{col.column}}{% else %}{{ conn|qtIdent(col.column)}}{% endif %}{% if col.oper_class and col.oper_class != '' %} {{col.oper_class}}{% endif%}{% if col.order is defined and col.is_sort_nulls_applicable %}{% if col.order %} ASC{% else %} DESC{% endif %} NULLS{% endif %} {% if col.nulls_order is defined and col.is_sort_nulls_applicable %}{% if col.nulls_order %}FIRST {% else %}LAST {% endif %}{% endif %}WITH {{col.operator}}{% endfor %}){% if data.include|length > 0 %}
INCLUDE ({% for col in data.include %}{% if loop.index != 1 %}, {% endif %}{{conn|qtIdent(col)}}{% endfor %}){% endif %}{% if data.fillfactor %}
WITH (FILLFACTOR={{data.fillfactor}}){% endif %}{% if data.spcname and data.spcname != "pg_default" %}
USING INDEX TABLESPACE {{ conn|qtIdent(data.spcname) }}{% endif %}{% if data.indconstraint %}
WHERE ({{data.indconstraint}}){% endif%}
{% if data.condeferrable %}
@ -23,5 +23,5 @@ ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
{% if data.comment and data.name %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}

Просмотреть файл

@ -11,12 +11,12 @@ FROM (
SELECT
i.indnkeyatts,
i.indrelid,
unnest(indkey) AS table_colnum,
unnest(ARRAY(SELECT generate_series(1, i.indnatts) AS n)) attnum
pg_catalog.unnest(indkey) AS table_colnum,
pg_catalog.unnest(ARRAY(SELECT pg_catalog.generate_series(1, i.indnatts) AS n)) attnum
FROM
pg_index i
pg_catalog.pg_index i
WHERE i.indexrelid = {{cid}}::OID
) i JOIN pg_attribute a
) i JOIN pg_catalog.pg_attribute a
ON (a.attrelid = i.indrelid AND i.table_colnum = a.attnum)
WHERE i.attnum > i.indnkeyatts
ORDER BY i.attnum

Просмотреть файл

@ -8,9 +8,9 @@ SELECT cls.oid,
cls.relname as name,
indnkeyatts as col_count,
amname,
CASE WHEN length(spcname) > 0 THEN spcname ELSE
(SELECT sp.spcname FROM pg_database dtb
JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid
CASE WHEN length(spcname::text) > 0 THEN spcname ELSE
(SELECT sp.spcname FROM pg_catalog.pg_database dtb
JOIN pg_catalog.pg_tablespace sp ON dtb.dattablespace=sp.oid
WHERE dtb.oid = {{ did }}::oid)
END as spcname,
CASE contype
@ -21,18 +21,16 @@ SELECT cls.oid,
END AS comment,
condeferrable,
condeferred,
substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor,
pg_get_expr(idx.indpred, idx.indrelid) AS indconstraint
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace
JOIN pg_namespace n ON n.oid=tab.relnamespace
JOIN pg_am am ON am.oid=cls.relam
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
substring(pg_catalog.array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor,
pg_catalog.pg_get_expr(idx.indpred, idx.indrelid, true) AS indconstraint
FROM pg_catalog.pg_index idx
JOIN pg_catalog.pg_class cls ON cls.oid=indexrelid
LEFT OUTER JOIN pg_catalog.pg_tablespace ta on ta.oid=cls.reltablespace
JOIN pg_catalog.pg_am am ON am.oid=cls.relam
LEFT JOIN pg_catalog.pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_catalog.pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_catalog.pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_catalog.pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
WHERE indrelid = {{tid}}::oid
{% if cid %}
AND cls.oid = {{cid}}::oid

Просмотреть файл

@ -1,29 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
{% for n in range(colcnt|int) %}
{% if loop.index != 1 %}
UNION
{% endif %}
SELECT
i.indoption[{{loop.index -1}}] AS options,
pg_catalog.pg_get_indexdef(i.indexrelid, {{loop.index}}, true) AS coldef,
op.oprname,
CASE WHEN (o.opcdefault = FALSE) THEN o.opcname ELSE null END AS opcname
,
coll.collname,
nspc.nspname as collnspname,
pg_catalog.format_type(ty.oid,NULL) AS datatype,
CASE WHEN pg_catalog.pg_get_indexdef(i.indexrelid, {{loop.index}}, true) = a.attname THEN FALSE ELSE TRUE END AS is_exp
FROM pg_catalog.pg_index i
JOIN pg_catalog.pg_attribute a ON (a.attrelid = i.indexrelid AND attnum = {{loop.index}})
JOIN pg_catalog.pg_type ty ON ty.oid=a.atttypid
LEFT OUTER JOIN pg_catalog.pg_opclass o ON (o.oid = i.indclass[{{loop.index -1}}])
LEFT OUTER JOIN pg_catalog.pg_constraint c ON (c.conindid = i.indexrelid) LEFT OUTER JOIN pg_catalog.pg_operator op ON (op.oid = c.conexclop[{{loop.index}}])
LEFT OUTER JOIN pg_catalog.pg_collation coll ON a.attcollation=coll.oid
LEFT OUTER JOIN pg_catalog.pg_namespace nspc ON coll.collnamespace=nspc.oid
WHERE i.indexrelid = {{cid}}::oid
{% endfor %}

Просмотреть файл

@ -1,36 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT DISTINCT op.oprname as oprname
FROM pg_operator op,
( SELECT oid
FROM (SELECT format_type(t.oid,NULL) AS typname,
t.oid as oid
FROM pg_type t
JOIN pg_namespace nsp ON typnamespace=nsp.oid
WHERE (NOT (typname = 'unknown' AND nspname = 'pg_catalog')) AND
typisdefined AND
typtype IN ('b', 'c', 'd', 'e', 'r') AND
NOT EXISTS (SELECT 1
FROM pg_class
WHERE relnamespace=typnamespace AND
relname = typname AND
relkind != 'c') AND
(typname NOT LIKE '_%' OR
NOT EXISTS (SELECT 1
FROM pg_class
WHERE relnamespace=typnamespace AND
relname = SUBSTRING(typname FROM 2)::name AND
relkind != 'c'))
{% if not show_sysobj %}
AND nsp.nspname != 'information_schema'
{% endif %}
UNION SELECT 'smallserial', 0
UNION SELECT 'bigserial', 0
UNION SELECT 'serial', 0) t1
WHERE typname = {{type}}) AS types
WHERE oprcom > 0 AND
(op.oprleft=types.oid OR op.oprright=types.oid)

Просмотреть файл

@ -1,12 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT amname
FROM pg_am
WHERE EXISTS (SELECT 1
FROM pg_proc
WHERE oid=amhandler)
ORDER BY amname;

Просмотреть файл

@ -1 +1,7 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
BEGIN;

Просмотреть файл

@ -4,35 +4,36 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} FOREIGN KEY ({% for columnobj in data.columns %}{% if loop.index != 1 %}
, {% endif %}{{ conn|qtIdent(columnobj.local_column)}}{% endfor %})
REFERENCES {{ conn|qtIdent(data.remote_schema, data.remote_table) }} ({% for columnobj in data.columns %}{% if loop.index != 1 %}
, {% endif %}{{ conn|qtIdent(columnobj.referenced)}}{% endfor %}) {% if data.confmatchtype %}MATCH FULL{% else %}MATCH SIMPLE{% endif%}
, {% endif %}{{ conn|qtIdent(columnobj.referenced)}}{% endfor %}){% if data.confmatchtype is defined %} {% if data.confmatchtype %}MATCH FULL{% else %}MATCH SIMPLE{% endif%}{% endif%}{% if data.confupdtype is defined %}
ON UPDATE{% if data.confupdtype == 'a' %}
NO ACTION{% elif data.confupdtype == 'r' %}
RESTRICT{% elif data.confupdtype == 'c' %}
CASCADE{% elif data.confupdtype == 'n' %}
SET NULL{% elif data.confupdtype == 'd' %}
SET DEFAULT{% endif %}
SET DEFAULT{% endif %}{% endif %}{% if data.confdeltype is defined %}
ON DELETE{% if data.confdeltype == 'a' %}
NO ACTION{% elif data.confdeltype == 'r' %}
RESTRICT{% elif data.confdeltype == 'c' %}
CASCADE{% elif data.confdeltype == 'n' %}
SET NULL{% elif data.confdeltype == 'd' %}
SET DEFAULT{% endif %}
SET DEFAULT{% endif %}{% endif %}
{% if data.condeferrable %}
DEFERRABLE{% if data.condeferred %}
INITIALLY DEFERRED{% endif%}
{% endif%}
{% if data.convalidated %}
{% if not data.convalidated %}
NOT VALID{% endif%};
{% if data.comment and data.name %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
{% endif %}
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}

Просмотреть файл

@ -4,8 +4,8 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
{% if data.autoindex %}
CREATE INDEX {{ conn|qtIdent(data.coveringindex) }}
{% if data.autoindex and data.coveringindex%}
CREATE INDEX IF NOT EXISTS {{ conn|qtIdent(data.coveringindex) }}
ON {{ conn|qtIdent(data.schema, data.table) }}({% for columnobj in data.columns %}{% if loop.index != 1 %}
, {% endif %}{{ conn|qtIdent(columnobj.local_column)}}{% endfor %});
{% endif %}
{% endif %}

Просмотреть файл

@ -5,5 +5,5 @@
# This software is released under the PostgreSQL Licence
#}
{% if data %}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }} DROP CONSTRAINT {{ conn|qtIdent(data.name) }}{% if cascade%} CASCADE{% endif %};
{% endif %}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }} DROP CONSTRAINT IF EXISTS {{ conn|qtIdent(data.name) }}{% if cascade%} CASCADE{% endif %};
{% endif %}

Просмотреть файл

@ -1 +1,7 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
END;

Просмотреть файл

@ -1,7 +1,13 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
{% for n in range(colcnt|int) %}
{% if loop.index != 1 %}
UNION SELECT pg_get_indexdef({{ cid|string }}, {{ loop.index|string }}, true) AS column
UNION SELECT pg_catalog.pg_get_indexdef({{ cid|string }}, {{ loop.index|string }}, true) AS column
{% else %}
SELECT pg_get_indexdef({{ cid|string }} , {{ loop.index|string }} , true) AS column
SELECT pg_catalog.pg_get_indexdef({{ cid|string }} , {{ loop.index|string }} , true) AS column
{% endif %}
{% endfor %}
{% endfor %}

Просмотреть файл

@ -6,14 +6,14 @@
#}
{% for keypair in keys %}
{% if loop.index != 1 %}
UNION
UNION ALL
{% endif %}
SELECT a1.attname as conattname,
a2.attname as confattname
FROM pg_attribute a1,
pg_attribute a2
FROM pg_catalog.pg_attribute a1,
pg_catalog.pg_attribute a2
WHERE a1.attrelid={{tid}}::oid
AND a1.attnum={{keypair[1]}}
AND a2.attrelid={{confrelid}}::oid
AND a2.attnum={{keypair[0]}}
{% endfor %}
{% endfor %}

Просмотреть файл

@ -5,5 +5,5 @@
# This software is released under the PostgreSQL Licence
#}
SELECT conname as name
FROM pg_constraint ct
WHERE ct.oid = {{fkid}}::oid
FROM pg_catalog.pg_constraint ct
WHERE ct.oid = {{fkid}}::oid

Просмотреть файл

@ -6,6 +6,6 @@
#}
SELECT ct.oid,
NOT convalidated as convalidated
FROM pg_constraint ct
FROM pg_catalog.pg_constraint ct
WHERE contype='f' AND
ct.conname = {{ name }};
ct.conname = {{ name|qtLiteral(conn) }};

Просмотреть файл

@ -7,6 +7,7 @@
SELECT ct.oid,
ct.conname as name,
NOT convalidated as convalidated
FROM pg_constraint ct
FROM pg_catalog.pg_constraint ct
WHERE contype='f' AND
conrelid = {{tid}}::oid LIMIT 1;
conrelid = {{tid}}::oid
ORDER BY ct.oid DESC LIMIT 1;

Просмотреть файл

@ -7,7 +7,7 @@
SELECT nsp.nspname AS schema,
rel.relname AS table
FROM
pg_class rel
JOIN pg_namespace nsp
pg_catalog.pg_class rel
JOIN pg_catalog.pg_namespace nsp
ON rel.relnamespace = nsp.oid::oid
WHERE rel.oid = {{tid}}::oid
WHERE rel.oid = {{tid}}::oid

Просмотреть файл

@ -6,8 +6,10 @@
#}
SELECT ct.oid,
conname as name,
NOT convalidated as convalidated
FROM pg_constraint ct
NOT convalidated as convalidated,
description as comment
FROM pg_catalog.pg_constraint ct
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=ct.oid AND des.classoid='pg_constraint'::regclass)
WHERE contype='f' AND
conrelid = {{parent_id}}::oid
ORDER BY conname

Просмотреть файл

@ -4,9 +4,7 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT
FALSE as convalidated,
ct.oid,
SELECT ct.oid,
conname as name,
condeferrable,
condeferred,
@ -21,18 +19,21 @@ SELECT
confrelid,
nl.nspname as fknsp,
cl.relname as fktab,
nr.oid as refnspoid,
nr.nspname as refnsp,
cr.relname as reftab,
description as comment
FROM pg_constraint ct
JOIN pg_class cl ON cl.oid=conrelid
JOIN pg_namespace nl ON nl.oid=cl.relnamespace
JOIN pg_class cr ON cr.oid=confrelid
JOIN pg_namespace nr ON nr.oid=cr.relnamespace
LEFT OUTER JOIN pg_description des ON (des.objoid=ct.oid AND des.classoid='pg_constraint'::regclass)
description as comment,
convalidated,
conislocal
FROM pg_catalog.pg_constraint ct
JOIN pg_catalog.pg_class cl ON cl.oid=conrelid
JOIN pg_catalog.pg_namespace nl ON nl.oid=cl.relnamespace
JOIN pg_catalog.pg_class cr ON cr.oid=confrelid
JOIN pg_catalog.pg_namespace nr ON nr.oid=cr.relnamespace
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=ct.oid AND des.classoid='pg_constraint'::regclass)
WHERE contype='f' AND
conrelid = {{tid}}::oid
{% if cid %}
AND ct.oid = {{cid}}::oid
{% endif %}
ORDER BY conname
ORDER BY conname

Просмотреть файл

@ -8,17 +8,19 @@
{% if data %}
{# ==== To update foreign key name ==== #}
{% if data.name != o_data.name %}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
RENAME CONSTRAINT {{ conn|qtIdent(o_data.name) }} TO {{ conn|qtIdent(data.name) }};
{% endif %}
{# ==== To update foreign key validate ==== #}
{% if 'convalidated' in data and o_data.convalidated != data.convalidated and not data.convalidated %}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
{% if 'convalidated' in data and o_data.convalidated != data.convalidated and data.convalidated %}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
VALIDATE CONSTRAINT {{ conn|qtIdent(data.name) }};
{% endif %}
{# ==== To update foreign key comments ==== #}
{% if data.comment is defined and data.comment != o_data.comment %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}
{% endif %}
{% endif %}

Просмотреть файл

@ -4,5 +4,5 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
VALIDATE CONSTRAINT {{ conn|qtIdent(data.name) }};
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
VALIDATE CONSTRAINT {{ conn|qtIdent(data.name) }};

Просмотреть файл

@ -1,38 +0,0 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT ct.oid,
conname as name,
condeferrable,
condeferred,
confupdtype,
confdeltype,
CASE confmatchtype
WHEN 's' THEN FALSE
WHEN 'f' THEN TRUE
END AS confmatchtype,
conkey,
confkey,
confrelid,
nl.nspname as fknsp,
cl.relname as fktab,
nr.nspname as refnsp,
cr.relname as reftab,
description as comment,
convalidated,
conislocal
FROM pg_catalog.pg_constraint ct
JOIN pg_catalog.pg_class cl ON cl.oid=conrelid
JOIN pg_catalog.pg_namespace nl ON nl.oid=cl.relnamespace
JOIN pg_catalog.pg_class cr ON cr.oid=confrelid
JOIN pg_catalog.pg_namespace nr ON nr.oid=cr.relnamespace
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=ct.oid AND des.classoid='pg_constraint'::regclass)
WHERE contype='f' AND
conrelid = {{tid}}::oid
{% if cid %}
AND ct.oid = {{cid}}::oid
{% endif %}
ORDER BY conname

Просмотреть файл

@ -1 +1,7 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
BEGIN;

Просмотреть файл

@ -4,7 +4,7 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} {{constraint_name}} {% if data.index %}USING INDEX {{ conn|qtIdent(data.index) }}{% else %}
({% for columnobj in data.columns %}{% if loop.index != 1 %}
, {% endif %}{{ conn|qtIdent(columnobj.column)}}{% endfor %}){% if data.fillfactor %}
@ -15,9 +15,9 @@ ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
DEFERRABLE{% if data.condeferred %}
INITIALLY DEFERRED{% endif%}
{% endif%};
{% endif -%};
{% if data.comment and data.name %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
{% endif %}
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}

Просмотреть файл

@ -5,5 +5,5 @@
# This software is released under the PostgreSQL Licence
#}
{% if data %}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }} DROP CONSTRAINT {{ conn|qtIdent(data.name) }}{% if cascade%} CASCADE{% endif %};
{% endif %}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }} DROP CONSTRAINT IF EXISTS {{ conn|qtIdent(data.name) }}{% if cascade%} CASCADE{% endif %};
{% endif %}

Просмотреть файл

@ -11,10 +11,10 @@ because we lose ordering when we use UNION
SELECT * FROM (
{% for n in range(colcnt|int) %}
{% if loop.index != 1 %}
UNION SELECT pg_get_indexdef({{ cid|string }}, {{ loop.index|string }}, true) AS column, {{ n }} AS dummy
UNION SELECT pg_catalog.pg_get_indexdef({{ cid|string }}, {{ loop.index|string }}, true) AS column, {{ n }} AS dummy
{% else %}
SELECT pg_get_indexdef({{ cid|string }} , {{ loop.index|string }} , true) AS column, {{ n }} AS dummy
SELECT pg_catalog.pg_get_indexdef({{ cid|string }} , {{ loop.index|string }} , true) AS column, {{ n }} AS dummy
{% endif %}
{% endfor %}
) tmp
ORDER BY dummy
ORDER BY dummy

Просмотреть файл

@ -4,6 +4,6 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT relname FROM pg_class, pg_index
WHERE pg_class.oid=indexrelid
AND indrelid={{ tid }}
SELECT relname FROM pg_catalog.pg_class, pg_catalog.pg_index
WHERE pg_catalog.pg_class.oid=indexrelid
AND indrelid={{ tid }}

Просмотреть файл

@ -5,17 +5,17 @@
# This software is released under the PostgreSQL Licence
#}
SELECT cls.relname as name
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND
FROM pg_catalog.pg_index idx
JOIN pg_catalog.pg_class cls ON cls.oid=indexrelid
LEFT JOIN pg_catalog.pg_depend dep ON (dep.classid = cls.tableoid AND
dep.objid = cls.oid AND
dep.refobjsubid = '0'
AND dep.refclassid=(SELECT oid
FROM pg_class
FROM pg_catalog.pg_class
WHERE relname='pg_constraint') AND
dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND
LEFT OUTER JOIN pg_catalog.pg_constraint con ON (con.tableoid = dep.refclassid AND
con.oid = dep.refobjid)
WHERE indrelid = {{tid}}::oid
AND contype='{{constraint_type}}'
AND cls.oid = {{cid}}::oid;
AND cls.oid = {{cid}}::oid;

Просмотреть файл

@ -5,6 +5,6 @@
# This software is released under the PostgreSQL Licence
#}
SELECT ct.conindid as oid
FROM pg_constraint ct
FROM pg_catalog.pg_constraint ct
WHERE contype='{{constraint_type}}' AND
ct.conname = {{ name }};
ct.conname = {{ name|qtLiteral(conn) }};

Просмотреть файл

@ -6,6 +6,7 @@
#}
SELECT ct.conindid as oid,
ct.conname as name
FROM pg_constraint ct
FROM pg_catalog.pg_constraint ct
WHERE contype='{{constraint_type}}' AND
conrelid = {{tid}}::oid LIMIT 1;
conrelid = {{tid}}::oid
ORDER BY oid DESC LIMIT 1;

Просмотреть файл

@ -1,8 +1,13 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT nsp.nspname AS schema,
rel.relname AS table
FROM
pg_class rel
JOIN pg_namespace nsp
pg_catalog.pg_class rel
JOIN pg_catalog.pg_namespace nsp
ON rel.relnamespace = nsp.oid::oid
WHERE rel.oid = {{tid}}::oid
WHERE rel.oid = {{tid}}::oid

Просмотреть файл

@ -4,20 +4,30 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT cls.oid, cls.relname as name
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND
SELECT cls.oid, cls.relname as name,
CASE contype
WHEN 'p' THEN desp.description
WHEN 'u' THEN desp.description
WHEN 'x' THEN desp.description
ELSE des.description
END AS comment
FROM pg_catalog.pg_index idx
JOIN pg_catalog.pg_class cls ON cls.oid=indexrelid
LEFT JOIN pg_catalog.pg_depend dep ON (dep.classid = cls.tableoid AND
dep.objid = cls.oid AND
dep.refobjsubid = '0' AND
dep.refclassid=(SELECT oid
FROM pg_class
FROM pg_catalog.pg_class
WHERE relname='pg_constraint') AND
dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND
LEFT OUTER JOIN pg_catalog.pg_constraint con ON (con.tableoid = dep.refclassid AND
con.oid = dep.refobjid)
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_catalog.pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
WHERE indrelid = {{parent_id}}::oid
{% if constraint_type is defined %}
AND contype='{{constraint_type}}'
{% endif %}
{% if cid %}
AND cls.oid = {{cid}}::oid
{% endif %}
{% endif %}

Просмотреть файл

@ -6,10 +6,10 @@
#}
SELECT cls.oid,
cls.relname as name,
indnatts,
CASE WHEN length(spcname) > 0 THEN spcname ELSE
(SELECT sp.spcname FROM pg_database dtb
JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid
indnatts as col_count,
CASE WHEN length(spcname::text) > 0 THEN spcname ELSE
(SELECT sp.spcname FROM pg_catalog.pg_database dtb
JOIN pg_catalog.pg_tablespace sp ON dtb.dattablespace=sp.oid
WHERE dtb.oid = {{ did }}::oid)
END as spcname,
CASE contype
@ -20,20 +20,20 @@ SELECT cls.oid,
END AS comment,
condeferrable,
condeferred,
substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace
JOIN pg_namespace n ON n.oid=tab.relnamespace
JOIN pg_am am ON am.oid=cls.relam
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
conislocal,
substring(pg_catalog.array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor
FROM pg_catalog.pg_index idx
JOIN pg_catalog.pg_class cls ON cls.oid=indexrelid
LEFT OUTER JOIN pg_catalog.pg_tablespace ta on ta.oid=cls.reltablespace
LEFT JOIN pg_catalog.pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_catalog.pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_catalog.pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_catalog.pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
WHERE indrelid = {{tid}}::oid
{% if cid %}
AND cls.oid = {{cid}}::oid
{% endif %}
{% if constraint_type is defined %}
AND contype='{{constraint_type}}'
ORDER BY cls.relname
{% endif %}
ORDER BY cls.relname

Просмотреть файл

@ -24,11 +24,11 @@ SELECT
avg_leaf_density AS {{ conn|qtIdent(_('Average leaf density')) }},
leaf_fragmentation AS {{ conn|qtIdent(_('Leaf fragmentation')) }}
FROM
pgstatindex('{{conn|qtIdent(schema)}}.{{conn|qtIdent(name)}}'), pg_stat_all_indexes stat
pgstatindex('{{conn|qtIdent(schema)}}.{{conn|qtIdent(name)}}'), pg_catalog.pg_stat_all_indexes stat
{% else %}
FROM
pg_stat_all_indexes stat
pg_catalog.pg_stat_all_indexes stat
{% endif %}
JOIN pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid
JOIN pg_class cl ON cl.oid=stat.indexrelid
JOIN pg_catalog.pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid
JOIN pg_catalog.pg_class cl ON cl.oid=stat.indexrelid
WHERE stat.indexrelid = {{ cid }}::OID

Просмотреть файл

@ -7,7 +7,7 @@
{### SQL to update constraint object ###}
{% if data %}
{# ==== To update constraint name ==== #}
{% if data.name != o_data.name %}
{% if data.name and data.name != o_data.name %}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
RENAME CONSTRAINT {{ conn|qtIdent(o_data.name) }} TO {{ conn|qtIdent(data.name) }};
{% endif %}
@ -19,10 +19,13 @@ ALTER INDEX {{ conn|qtIdent(data.schema, data.name) }}
{% if data.fillfactor and data.fillfactor != o_data.fillfactor %}
ALTER INDEX {{ conn|qtIdent(data.schema, data.name) }}
SET (FILLFACTOR={{ data.fillfactor }});
{% elif data.fillfactor is defined and data.fillfactor == '' %}
ALTER INDEX {{ conn|qtIdent(data.schema, data.name) }}
RESET (FILLFACTOR);
{% endif %}
{# ==== To update constraint comments ==== #}
{% if data.comment is defined and data.comment != o_data.comment %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}
{% endif %}
{% endif %}

Просмотреть файл

@ -4,12 +4,12 @@
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} {{constraint_name}} {% if data.index %}USING INDEX {{ conn|qtIdent(data.index) }}{% else %}
({% for columnobj in data.columns %}{% if loop.index != 1 %}
, {% endif %}{{ conn|qtIdent(columnobj.column)}}{% endfor %})
{% if data.include|length > 0 %}
INCLUDE({% for col in data.include %}{% if loop.index != 1 %}, {% endif %}{{conn|qtIdent(col)}}{% endfor %}){% endif %}
, {% endif %}{{ conn|qtIdent(columnobj.column)}}{% endfor %}){% if data.include|length > 0 %}
INCLUDE ({% for col in data.include %}{% if loop.index != 1 %}, {% endif %}{{conn|qtIdent(col)}}{% endfor %}){% endif %}
{% if data.fillfactor %}
WITH (FILLFACTOR={{data.fillfactor}}){% endif %}{% if data.spcname and data.spcname != "pg_default" %}
@ -18,9 +18,9 @@ ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }}
DEFERRABLE{% if data.condeferred %}
INITIALLY DEFERRED{% endif%}
{% endif%};
{% endif -%};
{% if data.comment and data.name %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment }};
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}

Просмотреть файл

@ -11,12 +11,12 @@ FROM (
SELECT
i.indnkeyatts,
i.indrelid,
unnest(indkey) AS table_colnum,
unnest(ARRAY(SELECT generate_series(1, i.indnatts) AS n)) attnum
pg_catalog.unnest(indkey) AS table_colnum,
pg_catalog.unnest(ARRAY(SELECT pg_catalog.generate_series(1, i.indnatts) AS n)) attnum
FROM
pg_index i
pg_catalog.pg_index i
WHERE i.indexrelid = {{cid}}::OID
) i JOIN pg_attribute a
) i JOIN pg_catalog.pg_attribute a
ON (a.attrelid = i.indrelid AND i.table_colnum = a.attnum)
WHERE i.attnum > i.indnkeyatts
ORDER BY i.attnum

Просмотреть файл

@ -7,9 +7,9 @@
SELECT cls.oid,
cls.relname as name,
indnkeyatts as col_count,
CASE WHEN length(spcname) > 0 THEN spcname ELSE
(SELECT sp.spcname FROM pg_database dtb
JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid
CASE WHEN length(spcname::text) > 0 THEN spcname ELSE
(SELECT sp.spcname FROM pg_catalog.pg_database dtb
JOIN pg_catalog.pg_tablespace sp ON dtb.dattablespace=sp.oid
WHERE dtb.oid = {{ did }}::oid)
END as spcname,
CASE contype
@ -20,20 +20,20 @@ SELECT cls.oid,
END AS comment,
condeferrable,
condeferred,
substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor
FROM pg_index idx
JOIN pg_class cls ON cls.oid=indexrelid
JOIN pg_class tab ON tab.oid=indrelid
LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace
JOIN pg_namespace n ON n.oid=tab.relnamespace
JOIN pg_am am ON am.oid=cls.relam
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
conislocal,
substring(pg_catalog.array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor
FROM pg_catalog.pg_index idx
JOIN pg_catalog.pg_class cls ON cls.oid=indexrelid
LEFT OUTER JOIN pg_catalog.pg_tablespace ta on ta.oid=cls.reltablespace
LEFT JOIN pg_catalog.pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_catalog.pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_catalog.pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_catalog.pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
WHERE indrelid = {{tid}}::oid
{% if cid %}
AND cls.oid = {{cid}}::oid
{% endif %}
{% if constraint_type is defined %}
AND contype='{{constraint_type}}'
{% endif %}
ORDER BY cls.relname

Просмотреть файл

@ -0,0 +1,26 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.table) }}
ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} {{constraint_name}}{% if data.indnullsnotdistinct %} NULLS NOT DISTINCT{% endif %} {% if data.index %}USING INDEX {{ conn|qtIdent(data.index) }}{% else %}
({% for columnobj in data.columns %}{% if loop.index != 1 %}
, {% endif %}{{ conn|qtIdent(columnobj.column)}}{% endfor %}){% if data.include|length > 0 %}
INCLUDE ({% for col in data.include %}{% if loop.index != 1 %}, {% endif %}{{conn|qtIdent(col)}}{% endfor %}){% endif %}
{% if data.fillfactor %}
WITH (FILLFACTOR={{data.fillfactor}}){% endif %}{% if data.spcname and data.spcname != "pg_default" %}
USING INDEX TABLESPACE {{ conn|qtIdent(data.spcname) }}{% endif %}{% endif %}{% if data.condeferrable %}
DEFERRABLE{% if data.condeferred %}
INITIALLY DEFERRED{% endif%}
{% endif -%};
{% if data.comment and data.name %}
COMMENT ON CONSTRAINT {{ conn|qtIdent(data.name) }} ON {{ conn|qtIdent(data.schema, data.table) }}
IS {{ data.comment|qtLiteral(conn) }};
{% endif %}

Просмотреть файл

@ -0,0 +1,40 @@
{#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#}
SELECT cls.oid,
cls.relname as name,
indnkeyatts as col_count,
indnullsnotdistinct,
CASE WHEN length(spcname::text) > 0 THEN spcname ELSE
(SELECT sp.spcname FROM pg_catalog.pg_database dtb
JOIN pg_catalog.pg_tablespace sp ON dtb.dattablespace=sp.oid
WHERE dtb.oid = {{ did }}::oid)
END as spcname,
CASE contype
WHEN 'p' THEN desp.description
WHEN 'u' THEN desp.description
WHEN 'x' THEN desp.description
ELSE des.description
END AS comment,
condeferrable,
condeferred,
conislocal,
substring(pg_catalog.array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor
FROM pg_catalog.pg_index idx
JOIN pg_catalog.pg_class cls ON cls.oid=indexrelid
LEFT OUTER JOIN pg_catalog.pg_tablespace ta on ta.oid=cls.reltablespace
LEFT JOIN pg_catalog.pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_catalog.pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
LEFT OUTER JOIN pg_catalog.pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_catalog.pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)
WHERE indrelid = {{tid}}::oid
{% if cid %}
AND cls.oid = {{cid}}::oid
{% endif %}
{% if constraint_type is defined %}
AND contype='{{constraint_type}}'
{% endif %}
ORDER BY cls.relname

Просмотреть файл

@ -29,7 +29,8 @@ class Constraint(NodeObject, ScriptableCreate, ScriptableDelete, ScriptableUpdat
"""
constraint = cls(server, parent, kwargs['name'])
constraint._oid = kwargs['oid']
constraint._convalidated = kwargs['convalidated']
if 'convalidated' in kwargs:
constraint._convalidated = kwargs['convalidated']
return constraint
@ -87,7 +88,8 @@ class CheckConstraint(Constraint):
"comment": self.comment,
"connoinherit": self.no_inherit,
"convalidated": self.convalidated
}
},
"conn": self.server.connection.connection
}
def _delete_query_data(self) -> dict:
@ -97,7 +99,8 @@ class CheckConstraint(Constraint):
"name": self.name,
"nspname": self.parent.parent.name,
"relname": self.parent.name
}
},
"conn": self.server.connection.connection
}
def _update_query_data(self) -> dict:
@ -115,7 +118,8 @@ class CheckConstraint(Constraint):
"nspname": "",
"relname": "",
"convalidated": ""
}
},
"conn": self.server.connection.connection
}
@ -175,7 +179,8 @@ class ExclusionConstraint(Constraint):
"condeferred": self.deferred,
"constraint": self.constraint,
"comment": self.comment
}
},
"conn": self.server.connection.connection
}
def _delete_query_data(self) -> dict:
@ -186,7 +191,8 @@ class ExclusionConstraint(Constraint):
"table": self.parent.name,
"name": self.name
},
"cascade": self.cascade
"cascade": self.cascade,
"conn": self.server.connection.connection
}
def _update_query_data(self) -> dict:
@ -205,7 +211,8 @@ class ExclusionConstraint(Constraint):
"spcname": "",
"fillfactor": "",
"comment": ""
}
},
"conn": self.server.connection.connection
}
@ -271,7 +278,8 @@ class ForeignKeyConstraint(Constraint):
"condeferred": self.deferred,
"convalidated": self.convalidated,
"comment": self.comment
}
},
"conn": self.server.connection.connection
}
def _delete_query_data(self) -> dict:
@ -282,7 +290,8 @@ class ForeignKeyConstraint(Constraint):
"table": self.parent.name,
"name": self.name
},
"cascade": self.cascade
"cascade": self.cascade,
"conn": self.server.connection.connection
}
def _update_query_data(self) -> dict:
@ -299,7 +308,8 @@ class ForeignKeyConstraint(Constraint):
"name": "",
"convalidated": "",
"comment": ""
}
},
"conn": self.server.connection.connection
}
@ -307,6 +317,7 @@ class IndexConstraint(Constraint):
TEMPLATE_ROOT = templating.get_template_root(__file__, 'constraint_index')
# -FULL OBJECT PROPERTIES ##############################################
@property
def index(self):
return self._full_properties["index"]
@ -350,7 +361,8 @@ class IndexConstraint(Constraint):
"condeferrable": self.deferrable,
"condeferred": self.deferred,
"comment": self.comment
}
},
"conn": self.server.connection.connection
}
def _delete_query_data(self) -> dict:
@ -361,7 +373,8 @@ class IndexConstraint(Constraint):
"table": self.parent.name,
"name": self.name
},
"cascade": self.cascade
"cascade": self.cascade,
"conn": self.server.connection.connection
}
def _update_query_data(self) -> dict:
@ -380,5 +393,38 @@ class IndexConstraint(Constraint):
"spcname": "",
"fillfactor": "",
"comment": ""
}
},
"conn": self.server.connection.connection
}
class PrimaryKeyConstraint(IndexConstraint):
@property
def constraint_type(self):
return "p"
# TEMPLATING PROPERTIES ################################################
@property
def extended_vars(self) -> dict:
return {
'cid': self.oid,
'tid': self.parent.oid, # Table/view OID
'did': self.parent.parent.oid, # Database OID
'constraint_type': self.constraint_type # Constraint type ("p" or "u" for primary or unique)
}
class UniqueKeyConstraint(IndexConstraint):
@property
def constraint_type(self):
return "u"
# TEMPLATING PROPERTIES ################################################
@property
def extended_vars(self) -> dict:
return {
'cid': self.oid,
'tid': self.parent.oid, # Table/view OID
'did': self.parent.parent.oid, # Database OID
'constraint_type': self.constraint_type # Constraint type ("p" or "u" for primary or unique)
}

Просмотреть файл

@ -125,6 +125,7 @@ class Index(NodeObject, ScriptableCreate, ScriptableDelete, ScriptableUpdate):
'tid': self.parent.oid, # Table/view OID
'did': self.parent.parent.oid # Database OID
}
# IMPLEMENTATION DETAILS ###############################################
@classmethod

Просмотреть файл

@ -22,6 +22,7 @@ class NodeObject(metaclass=ABCMeta):
Renders and executes nodes.sql for the class to generate a list of NodeObjects
:param root_server: Root node of the object model
:param parent_obj: The object that is the parent of all objects generated by this method
:param context_args: Additional dictionary of params that should be passed down to nodes.sql. Generally only parent_id should be needed
:return: A list of NodeObjects generated with _from_node_query
"""
template_root = cls._template_root(root_server)
@ -30,8 +31,9 @@ class NodeObject(metaclass=ABCMeta):
template_vars = {} # TODO: Allow configuring show/hide system objects
if parent_obj is not None:
template_vars['parent_id'] = parent_obj._oid
elif context_args:
template_vars = context_args
if context_args is not None:
template_vars.update(context_args)
# Render and execute the template
sql = utils.templating.render_template(
@ -168,14 +170,14 @@ class NodeObject(metaclass=ABCMeta):
# PROTECTED HELPERS ####################################################
TRCC = TypeVar('TRCC')
def _register_child_collection(self, class_: Type[TRCC]) -> 'NodeCollection[TRCC]':
def _register_child_collection(self, class_: Type[TRCC], context_args=None) -> 'NodeCollection[TRCC]':
"""
Creates a node collection for child objects and registers it with the list of child objects.
This is very useful for ensuring that all child collections are reset when refreshing.
:param generator: Callable for generating the list of nodes
:return: The created node collection
"""
collection = NodeCollection(lambda: class_.get_nodes_for_parent(self.server, self))
collection = NodeCollection(lambda: class_.get_nodes_for_parent(self.server, self, context_args=context_args))
self._child_collections[class_.__name__] = collection
return collection

Просмотреть файл

@ -189,7 +189,7 @@ class TestScripterOld(unittest.TestCase):
# If I try to get create script
result = mock_check_constraint.create_script()
# The result should be the correct template value
self.assertTrue('ALTER TABLE "TestSchema"."TestTable"\n ADD CONSTRAINT "TestName" CHECK (TestConsrc);' in result)
self.assertTrue('ALTER TABLE IF EXISTS "TestSchema"."TestTable"\n ADD CONSTRAINT "TestName" CHECK (TestConsrc);' in result)
def test_exclusion_constraint_scripting(self):
""" Helper function to test create script for exclusion_constraint """
@ -204,7 +204,7 @@ class TestScripterOld(unittest.TestCase):
# If I try to get create script
result = mock_exclusion_constraint.create_script()
# The result should be the correct template value
self.assertTrue('ALTER TABLE "TestSchema"."TestTable"\n ADD CONSTRAINT "TestName" EXCLUDE USING TestAmname' in result)
self.assertTrue('ALTER TABLE IF EXISTS "TestSchema"."TestTable"\n ADD CONSTRAINT "TestName" EXCLUDE USING TestAmname' in result)
def test_foreign_key_constraint_scripting(self):
""" Helper function to test create script for foreign_key_constraint """
@ -220,7 +220,7 @@ class TestScripterOld(unittest.TestCase):
# If I try to get create script
result = mock_foreign_key_constraint.create_script()
# The result should be the correct template value
self.assertTrue('ALTER TABLE "TestSchema"."TestTable"\n ADD CONSTRAINT "TestName" FOREIGN KEY '
self.assertTrue('ALTER TABLE IF EXISTS "TestSchema"."TestTable"\n ADD CONSTRAINT "TestName" FOREIGN KEY '
'(None, None, None, None, None, None, None, None, None, None, None)\n '
'REFERENCES "TestRemoteSchema"."TestRemoteTable"' in result)
@ -237,7 +237,7 @@ class TestScripterOld(unittest.TestCase):
# If I try to get create script
result = mock_index_constraint.create_script()
# The result should be the correct template value
self.assertTrue('ALTER TABLE "TestSchema"."TestTable"\n ADD CONSTRAINT "TestName" USING INDEX "TestIndex";' in result)
self.assertTrue('ALTER TABLE IF EXISTS "TestSchema"."TestTable"\n ADD CONSTRAINT "TestName" USING INDEX "TestIndex";' in result)
def test_rule_scripting(self):
""" Helper function to test create script for rule """