Support Properties on Greenplum databases. Fixes #3015

This commit is contained in:
Joao Pedro De Almeida Pereira 2018-01-15 14:44:40 +05:30 committed by Dave Page
parent 6f8066d261
commit 56e922f5ab
13 changed files with 201 additions and 73 deletions

View File

@ -0,0 +1,35 @@
SELECT
'datacl' AS deftype, COALESCE(gt.rolname, 'PUBLIC') AS grantee,
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
array_agg(is_grantable) AS grantable
FROM
(SELECT
d.grantee, d.grantor, d.is_grantable,
CASE d.privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type
FROM
(SELECT
(d).grantee AS grantee, (d).grantor AS grantor,
(d).is_grantable AS is_grantable,
(d).privilege_type AS privilege_type
FROM
(SELECT aclexplode(db.datacl) AS d FROM pg_database db
WHERE db.oid = {{ did|qtLiteral }}::OID) a
) d
) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname;

View File

@ -0,0 +1,34 @@
SELECT
CASE (a.deftype)
WHEN 'r' THEN 'deftblacl'
WHEN 'S' THEN 'defseqacl'
WHEN 'f' THEN 'deffuncacl'
WHEN 'T' THEN 'deftypeacl'
END AS deftype,
COALESCE(gt.rolname, 'PUBLIC') grantee, g.rolname grantor, array_agg(a.privilege_type) as privileges, array_agg(a.is_grantable) as grantable
FROM
(SELECT
(acl).grantee as grantee, (acl).grantor AS grantor, (acl).is_grantable AS is_grantable,
CASE (acl).privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type,
defaclobjtype as deftype
FROM
(SELECT defaclobjtype, aclexplode(defaclacl) as acl FROM pg_catalog.pg_default_acl dacl
WHERE dacl.defaclnamespace = 0::OID) d) a
LEFT JOIN pg_catalog.pg_roles g ON (a.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (a.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname, a.deftype
ORDER BY a.deftype

View File

@ -0,0 +1,5 @@
SELECT DISTINCT(datctype) AS cname
FROM pg_database
UNION
SELECT DISTINCT(datcollate) AS cname
FROM pg_database

View File

@ -0,0 +1,5 @@
SELECT rl.*, r.rolname AS user_name, db.datname as db_name
FROM pg_db_role_setting AS rl
LEFT JOIN pg_roles AS r ON rl.setrole = r.oid
LEFT JOIN pg_database AS db ON rl.setdatabase = db.oid
WHERE setdatabase = {{did}}

View File

@ -0,0 +1,43 @@
SELECT
db.oid AS did, db.datname AS name, db.dattablespace AS spcoid,
spcname, datallowconn, pg_encoding_to_char(encoding) AS encoding,
pg_get_userbyid(datdba) AS datowner, datcollate, datctype, datconnlimit,
has_database_privilege(db.oid, 'CREATE') AS cancreate,
current_setting('default_tablespace') AS default_tablespace,
descr.description AS comments, db.datistemplate AS is_template,
{### Default ACL for Tables ###}
(SELECT array_to_string(ARRAY(
SELECT array_to_string(defaclacl::text[], ', ')
FROM pg_default_acl
WHERE defaclobjtype = 'r' AND defaclnamespace = 0::OID
), ', ')) AS tblacl,
{### Default ACL for Sequnces ###}
(SELECT array_to_string(ARRAY(
SELECT array_to_string(defaclacl::text[], ', ')
FROM pg_default_acl
WHERE defaclobjtype = 'S' AND defaclnamespace = 0::OID
), ', ')) AS seqacl,
{### Default ACL for Functions ###}
(SELECT array_to_string(ARRAY(
SELECT array_to_string(defaclacl::text[], ', ')
FROM pg_default_acl
WHERE defaclobjtype = 'f' AND defaclnamespace = 0::OID
), ', ')) AS funcacl,
array_to_string(datacl::text[], ', ') AS acl
FROM pg_database db
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID
LEFT OUTER JOIN pg_shdescription descr ON (
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
)
WHERE {% if did %}
db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %}
db.datname = {{ name|qtLiteral }}::text{% else %}
db.oid > {{ last_system_oid|qtLiteral }}::OID
{% endif %}{% endif %}
{% if db_restrictions %}
AND
db.datname in ({{db_restrictions}})
{% endif %}
ORDER BY datname;

View File

@ -4,7 +4,9 @@ SELECT
array_agg(is_grantable) AS grantable array_agg(is_grantable) AS grantable
FROM FROM
(SELECT (SELECT
d.grantee, d.grantor, d.is_grantable, d.grantee,
d.grantor,
d.is_grantable,
CASE d.privilege_type CASE d.privilege_type
WHEN 'CONNECT' THEN 'c' WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C' WHEN 'CREATE' THEN 'C'
@ -22,14 +24,36 @@ FROM
END AS privilege_type END AS privilege_type
FROM FROM
(SELECT (SELECT
(d).grantee AS grantee, (d).grantor AS grantor, u_grantor.oid AS grantor,
(d).is_grantable AS is_grantable, grantee.oid AS grantee,
(d).privilege_type AS privilege_type pr.type AS privilege_type,
FROM aclcontains(c.datacl, makeaclitem(grantee.oid, u_grantor.oid, pr.type, true)) AS is_grantable
(SELECT aclexplode(db.datacl) AS d FROM pg_database db FROM pg_database c, pg_authid u_grantor, (
WHERE db.oid = {{ did|qtLiteral }}::OID) a SELECT pg_authid.oid, pg_authid.rolname
FROM pg_authid
UNION ALL
SELECT 0::oid AS oid, 'PUBLIC') grantee(oid, rolname),
( SELECT 'SELECT'
UNION ALL
SELECT 'INSERT'
UNION ALL
SELECT 'UPDATE'
UNION ALL
SELECT 'DELETE'
UNION ALL
SELECT 'TRUNCATE'
UNION ALL
SELECT 'REFERENCES'
UNION ALL
SELECT 'TRIGGER') pr(type)
WHERE aclcontains(c.datacl, makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
AND (pg_has_role(u_grantor.oid, 'USAGE'::text) OR pg_has_role(grantee.oid, 'USAGE'::text)
OR grantee.rolname = 'PUBLIC'::name)
AND c.oid = {{ did|qtLiteral }}::OID
) d ) d
) d ) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid) LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid) LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname; GROUP BY g.rolname, gt.rolname;

View File

@ -1,34 +1,7 @@
SELECT SELECT
CASE (a.deftype) '' AS deftype,
WHEN 'r' THEN 'deftblacl' '' AS grantee,
WHEN 'S' THEN 'defseqacl' '' AS grantor,
WHEN 'f' THEN 'deffuncacl' '' AS grantor,
WHEN 'T' THEN 'deftypeacl' '' AS privileges,
END AS deftype, '' AS grantable
COALESCE(gt.rolname, 'PUBLIC') grantee, g.rolname grantor, array_agg(a.privilege_type) as privileges, array_agg(a.is_grantable) as grantable
FROM
(SELECT
(acl).grantee as grantee, (acl).grantor AS grantor, (acl).is_grantable AS is_grantable,
CASE (acl).privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type,
defaclobjtype as deftype
FROM
(SELECT defaclobjtype, aclexplode(defaclacl) as acl FROM pg_catalog.pg_default_acl dacl
WHERE dacl.defaclnamespace = 0::OID) d) a
LEFT JOIN pg_catalog.pg_roles g ON (a.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (a.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname, a.deftype
ORDER BY a.deftype

View File

@ -1,5 +1,3 @@
SELECT DISTINCT(datctype) AS cname SELECT current_setting('lc_ctype') as cname
FROM pg_database
UNION UNION
SELECT DISTINCT(datcollate) AS cname SELECT current_setting('lc_collate') as cname
FROM pg_database

View File

@ -1,5 +1,2 @@
SELECT rl.*, r.rolname AS user_name, db.datname as db_name SELECT NULL
FROM pg_db_role_setting AS rl WHERE false
LEFT JOIN pg_roles AS r ON rl.setrole = r.oid
LEFT JOIN pg_database AS db ON rl.setdatabase = db.oid
WHERE setdatabase = {{did}}

View File

@ -1,28 +1,19 @@
SELECT SELECT
db.oid AS did, db.datname AS name, db.dattablespace AS spcoid, db.oid AS did, db.datname AS name, db.dattablespace AS spcoid,
spcname, datallowconn, pg_encoding_to_char(encoding) AS encoding, spcname, datallowconn, pg_encoding_to_char(encoding) AS encoding,
pg_get_userbyid(datdba) AS datowner, datcollate, datctype, datconnlimit, pg_get_userbyid(datdba) AS datowner,
(select current_setting('lc_collate')) as datcollate,
(select current_setting('lc_ctype')) as datctype,
datconnlimit,
has_database_privilege(db.oid, 'CREATE') AS cancreate, has_database_privilege(db.oid, 'CREATE') AS cancreate,
current_setting('default_tablespace') AS default_tablespace, current_setting('default_tablespace') AS default_tablespace,
descr.description AS comments, db.datistemplate AS is_template, descr.description AS comments, db.datistemplate AS is_template,
{### Default ACL for Tables ###} {### Default ACL for Tables ###}
(SELECT array_to_string(ARRAY( '' AS tblacl,
SELECT array_to_string(defaclacl::text[], ', ')
FROM pg_default_acl
WHERE defaclobjtype = 'r' AND defaclnamespace = 0::OID
), ', ')) AS tblacl,
{### Default ACL for Sequnces ###} {### Default ACL for Sequnces ###}
(SELECT array_to_string(ARRAY( '' AS seqacl,
SELECT array_to_string(defaclacl::text[], ', ')
FROM pg_default_acl
WHERE defaclobjtype = 'S' AND defaclnamespace = 0::OID
), ', ')) AS seqacl,
{### Default ACL for Functions ###} {### Default ACL for Functions ###}
(SELECT array_to_string(ARRAY( '' AS funcacl,
SELECT array_to_string(defaclacl::text[], ', ')
FROM pg_default_acl
WHERE defaclobjtype = 'f' AND defaclnamespace = 0::OID
), ', ')) AS funcacl,
array_to_string(datacl::text[], ', ') AS acl array_to_string(datacl::text[], ', ') AS acl
FROM pg_database db FROM pg_database db
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID

View File

@ -53,16 +53,22 @@ class QueryToolFeatureTest(BaseFeatureTest):
# explain query with verbose and cost # explain query with verbose and cost
print("Explain query with verbose and cost... ", print("Explain query with verbose and cost... ",
file=sys.stderr, end="") file=sys.stderr, end="")
self._query_tool_explain_with_verbose_and_cost() if self._test_explain_plan_feature():
print("OK.", file=sys.stderr) self._query_tool_explain_with_verbose_and_cost()
self._clear_query_tool() print("OK.", file=sys.stderr)
self._clear_query_tool()
else:
print("Skipped.", file=sys.stderr)
# explain analyze query with buffers and timing # explain analyze query with buffers and timing
print("Explain analyze query with buffers and timing... ", print("Explain analyze query with buffers and timing... ",
file=sys.stderr, end="") file=sys.stderr, end="")
self._query_tool_explain_analyze_with_buffers_and_timing() if self._test_explain_plan_feature():
print("OK.", file=sys.stderr) self._query_tool_explain_analyze_with_buffers_and_timing()
self._clear_query_tool() print("OK.", file=sys.stderr)
self._clear_query_tool()
else:
print("Skipped.", file=sys.stderr)
# auto commit disabled. # auto commit disabled.
print("Auto commit disabled... ", file=sys.stderr, end="") print("Auto commit disabled... ", file=sys.stderr, end="")
@ -567,3 +573,12 @@ SELECT 1, pg_sleep(300)"""
self.page.find_by_xpath( self.page.find_by_xpath(
'//div[contains(@class, "sql-editor-message") and contains(string(), "canceling statement due to user request")]' '//div[contains(@class, "sql-editor-message") and contains(string(), "canceling statement due to user request")]'
) )
def _test_explain_plan_feature(self):
connection = test_utils.get_db_connection(self.server['db'],
self.server['username'],
self.server['db_password'],
self.server['host'],
self.server['port'],
self.server['sslmode'])
return connection.server_version > 90100

View File

@ -21,6 +21,10 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
] ]
def before(self): def before(self):
with test_utils.Database(self.server) as (connection, _):
if connection.server_version < 90100:
self.skipTest("Membership is not present in Postgres below PG v9.1")
# Some test function is needed for debugger # Some test function is needed for debugger
test_utils.create_role(self.server, "postgres", test_utils.create_role(self.server, "postgres",
"test_role") "test_role")

View File

@ -302,15 +302,19 @@ def create_role(server, db_name, role_name="test_role"):
old_isolation_level = connection.isolation_level old_isolation_level = connection.isolation_level
connection.set_isolation_level(0) connection.set_isolation_level(0)
pg_cursor = connection.cursor() pg_cursor = connection.cursor()
pg_cursor.execute(''' sql_query = '''
CREATE USER "%s" WITH CREATE USER "%s" WITH
LOGIN LOGIN
NOSUPERUSER NOSUPERUSER
INHERIT INHERIT
CREATEDB CREATEDB
NOCREATEROLE NOCREATEROLE
NOREPLICATION
''' % (role_name) ''' % (role_name)
if connection.server_version > 90100:
sql_query += '\nNOREPLICATION'
pg_cursor.execute(
sql_query
) )
connection.set_isolation_level(old_isolation_level) connection.set_isolation_level(old_isolation_level)
connection.commit() connection.commit()