Changeset: 183e9e27b7f2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/183e9e27b7f2
Modified Files:
sql/scripts/52_describe.sql
sql/scripts/76_dump.sql
Branch: default
Log Message:
Various improvements to the dump code.
Add columns to helper views so that they can be selected on;
fix dumping of functions, especially in languages other than SQL;
fix dumping of grants by issuing GRANT statements.
We're not there yet...
diffs (truncated from 647 to 300 lines):
diff --git a/sql/scripts/52_describe.sql b/sql/scripts/52_describe.sql
--- a/sql/scripts/52_describe.sql
+++ b/sql/scripts/52_describe.sql
@@ -145,7 +145,7 @@ BEGIN
END;
END;
-CREATE FUNCTION sys.SQ (s STRING) RETURNS STRING BEGIN RETURN ' ''' ||
sys.replace(s,'''','''''') || ''' '; END;
+CREATE FUNCTION sys.SQ (s STRING) RETURNS STRING BEGIN RETURN '''' ||
sys.replace(s,'''','''''') || ''''; END;
CREATE FUNCTION sys.DQ (s STRING) RETURNS STRING BEGIN RETURN '"' ||
sys.replace(s,'"','""') || '"'; END; --TODO: Figure out why this breaks with
the space
CREATE FUNCTION sys.FQN(s STRING, t STRING) RETURNS STRING BEGIN RETURN
sys.DQ(s) || '.' || sys.DQ(t); END;
CREATE FUNCTION sys.ALTER_TABLE(s STRING, t STRING) RETURNS STRING BEGIN
RETURN 'ALTER TABLE ' || sys.FQN(s, t) || ' '; END;
@@ -514,12 +514,54 @@ CREATE VIEW sys.describe_sequences AS
ORDER BY s.name, seq.name;
CREATE VIEW sys.describe_functions AS
+ WITH func_args_all(func_id, number, max_number, func_arg) AS
+ (
+ SELECT
+ func_id,
+ number,
+ max(number) OVER (PARTITION BY func_id ORDER BY number
DESC),
+ group_concat(sys.dq(name) || ' ' ||
sys.describe_type(type, type_digits, type_scale),', ') OVER (PARTITION BY
func_id ORDER BY number)
+ FROM sys.args
+ WHERE inout = 1
+ ),
+ func_args(func_id, func_arg) AS
+ (
+ SELECT func_id, func_arg
+ FROM func_args_all
+ WHERE number = max_number
+ ),
+ func_rets_all(func_id, number, max_number, func_ret, func_ret_type) AS
+ (
+ SELECT
+ func_id,
+ number,
+ max(number) OVER (PARTITION BY func_id ORDER BY number
DESC),
+ group_concat(sys.dq(name) || ' ' ||
sys.describe_type(type, type_digits, type_scale),', ') OVER (PARTITION BY
func_id ORDER BY number),
+ group_concat(sys.describe_type(type, type_digits,
type_scale),', ') OVER (PARTITION BY func_id ORDER BY number)
+ FROM sys.args
+ WHERE inout = 0
+ ),
+ func_rets(func_id, func_ret, func_ret_type) AS
+ (
+ SELECT
+ func_id,
+ func_ret,
+ func_ret_type
+ FROM func_rets_all
+ WHERE number = max_number
+ )
SELECT
f.id o,
s.name sch,
f.name fun,
- f.func def
- FROM sys.functions f JOIN sys.schemas s ON f.schema_id = s.id WHERE
s.name <> 'tmp' AND NOT f.system;
+ CASE WHEN f.language IN (1, 2) THEN f.func ELSE 'CREATE ' ||
ft.function_type_keyword || ' ' || sys.FQN(s.name, f.name) || '(' ||
coalesce(fa.func_arg, '') || ')' || CASE WHEN f.type = 5 THEN ' RETURNS TABLE
(' || coalesce(fr.func_ret, '') || ')' WHEN f.type IN (1,3) THEN ' RETURNS ' ||
fr.func_ret_type ELSE '' END || CASE WHEN fl.language_keyword IS NULL THEN ''
ELSE ' LANGUAGE ' || fl.language_keyword END || ' ' || f.func END def
+ FROM sys.functions f
+ LEFT OUTER JOIN func_args fa ON fa.func_id = f.id
+ LEFT OUTER JOIN func_rets fr ON fr.func_id = f.id
+ JOIN sys.schemas s ON f.schema_id = s.id
+ JOIN sys.function_types ft ON f.type = ft.function_type_id
+ LEFT OUTER JOIN sys.function_languages fl ON f.language =
fl.language_id
+ WHERE s.name <> 'tmp' AND NOT f.system;
CREATE FUNCTION sys.describe_columns(schemaName string, tableName string)
RETURNS TABLE(name string, type string, digits integer, scale integer,
Nulls boolean, cDefault string, number integer, sqltype string, remark string)
diff --git a/sql/scripts/76_dump.sql b/sql/scripts/76_dump.sql
--- a/sql/scripts/76_dump.sql
+++ b/sql/scripts/76_dump.sql
@@ -5,145 +5,239 @@
-- Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
CREATE VIEW sys.dump_create_roles AS
- SELECT
- 'CREATE ROLE ' || sys.dq(name) || ';' stmt FROM sys.auths
- WHERE name NOT IN (SELECT name FROM sys.db_user_info)
- AND grantor <> 0;
+ SELECT
+ 'CREATE ROLE ' || sys.dq(name) || ';' stmt,
+ name user_name
+ FROM sys.auths
+ WHERE name NOT IN (SELECT name FROM sys.db_user_info)
+ AND grantor <> 0;
CREATE VIEW sys.dump_create_users AS
- SELECT
- 'CREATE USER ' || sys.dq(ui.name) || ' WITH ENCRYPTED
PASSWORD ' ||
- sys.sq(sys.password_hash(ui.name)) ||
- ' NAME ' || sys.sq(ui.fullname) || ' SCHEMA sys;' stmt
- FROM sys.db_user_info ui, sys.schemas s
- WHERE ui.default_schema = s.id
- AND ui.name <> 'monetdb'
- AND ui.name <> '.snapshot';
+ SELECT
+ 'CREATE USER ' || sys.dq(ui.name) || ' WITH ENCRYPTED PASSWORD ' ||
+ sys.sq(sys.password_hash(ui.name)) ||
+ ' NAME ' || sys.sq(ui.fullname) || ' SCHEMA sys;' stmt,
+ ui.name user_name
+ FROM sys.db_user_info ui, sys.schemas s
+ WHERE ui.default_schema = s.id
+ AND ui.name <> 'monetdb'
+ AND ui.name <> '.snapshot';
CREATE VIEW sys.dump_create_schemas AS
- SELECT
- 'CREATE SCHEMA ' || sys.dq(s.name) || ifthenelse(a.name <>
'sysadmin', ' AUTHORIZATION ' || a.name, ' ') || ';' stmt
- FROM sys.schemas s, sys.auths a
- WHERE s.authorization = a.id AND s.system = FALSE;
+ SELECT
+ 'CREATE SCHEMA ' || sys.dq(s.name) || ifthenelse(a.name <> 'sysadmin', '
AUTHORIZATION ' || sys.dq(a.name), ' ') || ';' stmt,
+ s.name schema_name
+ FROM sys.schemas s, sys.auths a
+ WHERE s.authorization = a.id AND s.system = FALSE;
CREATE VIEW sys.dump_add_schemas_to_users AS
- SELECT
- 'ALTER USER ' || sys.dq(ui.name) || ' SET SCHEMA ' ||
sys.dq(s.name) || ';' stmt
- FROM sys.db_user_info ui, sys.schemas s
- WHERE ui.default_schema = s.id
- AND ui.name <> 'monetdb'
- AND ui.name <> '.snapshot'
- AND s.name <> 'sys';
+ SELECT
+ 'ALTER USER ' || sys.dq(ui.name) || ' SET SCHEMA ' || sys.dq(s.name) ||
';' stmt,
+ s.name schema_name,
+ ui.name user_name
+ FROM sys.db_user_info ui, sys.schemas s
+ WHERE ui.default_schema = s.id
+ AND ui.name <> 'monetdb'
+ AND ui.name <> '.snapshot'
+ AND s.name <> 'sys';
CREATE VIEW sys.dump_grant_user_privileges AS
- SELECT
- 'GRANT ' || sys.dq(a2.name) || ' ' || ifthenelse(a1.name =
'public', 'PUBLIC', sys.dq(a1.name)) || ';' stmt
- FROM sys.auths a1, sys.auths a2, sys.user_role ur
- WHERE a1.id = ur.login_id AND a2.id = ur.role_id;
+ SELECT
+ 'GRANT ' || sys.dq(a2.name) || ' ' || ifthenelse(a1.name = 'public',
'PUBLIC', sys.dq(a1.name)) || ';' stmt,
+ a2.name grantee,
+ a1.name grantor
+ FROM sys.auths a1, sys.auths a2, sys.user_role ur
+ WHERE a1.id = ur.login_id AND a2.id = ur.role_id;
CREATE VIEW sys.dump_table_constraint_type AS
- SELECT
- 'ALTER TABLE ' || sys.DQ(sch) || '.' || sys.DQ(tbl) ||
- ' ADD CONSTRAINT ' || sys.DQ(con) || ' '||
- tpe || ' (' || GROUP_CONCAT(sys.DQ(col), ', ') || ');' stmt
- FROM sys.describe_constraints GROUP BY sch, tbl, con, tpe;
+ SELECT
+ 'ALTER TABLE ' || sys.DQ(sch) || '.' || sys.DQ(tbl) ||
+ ' ADD CONSTRAINT ' || sys.DQ(con) || ' '||
+ tpe || ' (' || GROUP_CONCAT(sys.DQ(col), ', ') || ');' stmt,
+ sch schema_name,
+ tbl table_name,
+ con constraint_name
+ FROM sys.describe_constraints GROUP BY sch, tbl, con, tpe;
+
+CREATE VIEW sys.dump_table_grants AS
+ WITH table_grants (sname, tname, grantee, grants, grantor, grantable)
+ AS (SELECT s.name, t.name, a.name, sum(p.privileges), g.name, p.grantable
+ FROM sys.schemas s, sys.tables t, sys.auths a, sys.privileges p,
sys.auths g
+ WHERE p.obj_id = t.id AND p.auth_id = a.id AND t.schema_id = s.id AND
t.system = FALSE AND p.grantor = g.id GROUP BY s.name, t.name, a.name, g.name,
p.grantable
+ ORDER BY s.name, t.name, a.name, g.name, p.grantable)
+ SELECT
+ 'GRANT ' || pc.privilege_code_name || ' ON TABLE ' || sys.dq(sname)
+ || '.' || sys.dq(tname) || ' TO ' || ifthenelse(grantee = 'public',
'PUBLIC', sys.dq(grantee))
+ || CASE WHEN grantable = 1 THEN ' WITH GRANT OPTION' ELSE '' END || ';'
stmt,
+ sname schema_name,
+ tname table_name,
+ grantee
+ FROM table_grants LEFT OUTER JOIN sys.privilege_codes pc ON grants =
pc.privilege_code_id;
+
+CREATE VIEW sys.dump_column_grants AS
+ SELECT
+ 'GRANT ' || pc.privilege_code_name || '(' || sys.dq(c.name) || ') ON '
+ || sys.dq(s.name) || '.' || sys.dq(t.name) || ' TO ' ||
ifthenelse(a.name = 'public', 'PUBLIC', sys.dq(a.name))
+ || CASE WHEN p.grantable = 1 THEN ' WITH GRANT OPTION' ELSE '' END ||
';' stmt,
+ s.name schema_name,
+ t.name table_name,
+ c.name column_name,
+ a.name grantee
+ FROM sys.schemas s,
+ sys.tables t,
+ sys.columns c,
+ sys.auths a,
+ sys.privileges p,
+ sys.auths g,
+ sys.privilege_codes pc
+ WHERE p.obj_id = c.id
+ AND c.table_id = t.id
+ AND p.auth_id = a.id
+ AND t.schema_id = s.id
+ AND NOT t.system
+ AND p.grantor = g.id
+ AND p.privileges = pc.privilege_code_id
+ ORDER BY s.name, t.name, c.name, a.name, g.name, p.grantable;
+
+CREATE VIEW sys.dump_function_grants AS
+ WITH func_args_all(func_id, number, max_number, func_arg) AS
+ (SELECT a.func_id,
+ a.number,
+ max(a.number) OVER (PARTITION BY a.func_id ORDER BY a.number DESC),
+ group_concat(sys.describe_type(a.type, a.type_digits, a.type_scale),
', ') OVER (PARTITION BY a.func_id ORDER BY a.number)
+ FROM sys.args a
+ WHERE a.inout = 1),
+ func_args(func_id, func_arg) AS
+ (SELECT func_id, func_arg FROM func_args_all WHERE number = max_number)
+ SELECT
+ 'GRANT ' || pc.privilege_code_name || ' ON '
+ || ft.function_type_keyword || ' '
+ || sys.dq(s.name) || '.' || sys.dq(f.name) || '(' ||
coalesce(fa.func_arg, '') || ') TO '
+ || ifthenelse(a.name = 'public', 'PUBLIC', sys.dq(a.name))
+ || CASE WHEN p.grantable = 1 THEN ' WITH GRANT OPTION' ELSE '' END ||
';' stmt,
+ s.name schema_name,
+ f.name function_name,
+ a.name grantee
+ FROM sys.schemas s,
+ sys.functions f LEFT OUTER JOIN func_args fa ON f.id = fa.func_id,
+ sys.auths a,
+ sys.privileges p,
+ sys.auths g,
+ sys.function_types ft,
+ sys.privilege_codes pc
+ WHERE s.id = f.schema_id
+ AND f.id = p.obj_id
+ AND p.auth_id = a.id
+ AND p.grantor = g.id
+ AND p.privileges = pc.privilege_code_id
+ AND f.type = ft.function_type_id
+ AND NOT f.system
+ ORDER BY s.name, f.name, a.name, g.name, p.grantable;
CREATE VIEW sys.dump_indices AS
- SELECT
- 'CREATE ' || tpe || ' ' ||
- sys.DQ(ind) || ' ON ' || sys.DQ(sch) || '.' || sys.DQ(tbl) ||
- '(' || GROUP_CONCAT(col) || ');' stmt
- FROM sys.describe_indices GROUP BY ind, tpe, sch, tbl;
+ SELECT
+ 'CREATE ' || tpe || ' ' ||
+ sys.DQ(ind) || ' ON ' || sys.DQ(sch) || '.' || sys.DQ(tbl) ||
+ '(' || GROUP_CONCAT(col) || ');' stmt,
+ sch schema_name,
+ tbl table_name,
+ ind index_name
+ FROM sys.describe_indices GROUP BY ind, tpe, sch, tbl;
CREATE VIEW sys.dump_column_defaults AS
- SELECT 'ALTER TABLE ' || sys.FQN(sch, tbl) || ' ALTER COLUMN ' ||
sys.DQ(col) || ' SET DEFAULT ' || def || ';' stmt
- FROM sys.describe_column_defaults;
+ SELECT 'ALTER TABLE ' || sys.FQN(sch, tbl) || ' ALTER COLUMN ' ||
sys.DQ(col) || ' SET DEFAULT ' || def || ';' stmt,
+ sch schema_name,
+ tbl table_name,
+ col column_name
+ FROM sys.describe_column_defaults;
CREATE VIEW sys.dump_foreign_keys AS
- SELECT
- 'ALTER TABLE ' || sys.DQ(fk_s) || '.'|| sys.DQ(fk_t) || ' ADD
CONSTRAINT ' || sys.DQ(fk) || ' ' ||
- 'FOREIGN KEY(' || GROUP_CONCAT(sys.DQ(fk_c), ',') ||') ' ||
- 'REFERENCES ' || sys.DQ(pk_s) || '.' || sys.DQ(pk_t) || '(' ||
GROUP_CONCAT(sys.DQ(pk_c), ',') || ') ' ||
- 'ON DELETE ' || on_delete || ' ON UPDATE ' || on_update ||
- ';' stmt
- FROM sys.describe_foreign_keys GROUP BY fk_s, fk_t, pk_s, pk_t, fk,
on_delete, on_update;
+ SELECT
+ 'ALTER TABLE ' || sys.DQ(fk_s) || '.'|| sys.DQ(fk_t) || ' ADD CONSTRAINT '
|| sys.DQ(fk) || ' ' ||
+ 'FOREIGN KEY(' || GROUP_CONCAT(sys.DQ(fk_c), ',') ||') ' ||
+ 'REFERENCES ' || sys.DQ(pk_s) || '.' || sys.DQ(pk_t) || '(' ||
GROUP_CONCAT(sys.DQ(pk_c), ',') || ') ' ||
+ 'ON DELETE ' || on_delete || ' ON UPDATE ' || on_update ||
+ ';' stmt,
+ fk_s foreign_schema_name,
+ fk_t foreign_table_name,
+ pk_s primary_schema_name,
+ pk_t primary_table_name,
+ fk key_name
+ FROM sys.describe_foreign_keys GROUP BY fk_s, fk_t, pk_s, pk_t, fk,
on_delete, on_update;
CREATE VIEW sys.dump_partition_tables AS
- SELECT
- sys.ALTER_TABLE(m_sch, m_tbl) || ' ADD TABLE ' ||
sys.FQN(p_sch, p_tbl) ||
- CASE
- WHEN tpe = 'VALUES' THEN ' AS PARTITION IN (' ||
pvalues || ')'
- WHEN tpe = 'RANGE' THEN ' AS PARTITION FROM ' ||
ifthenelse(minimum IS NOT NULL, sys.SQ(minimum), 'RANGE MINVALUE') || ' TO ' ||
ifthenelse(maximum IS NOT NULL, sys.SQ(maximum), 'RANGE MAXVALUE')
- WHEN tpe = 'FOR NULLS' THEN ' AS PARTITION FOR NULL
VALUES'
- ELSE '' --'READ ONLY'
- END ||
- CASE WHEN tpe in ('VALUES', 'RANGE') AND with_nulls THEN ' WITH
NULL VALUES' ELSE '' END ||
- ';' stmt
- FROM sys.describe_partition_tables;
+ SELECT
+ sys.ALTER_TABLE(m_sch, m_tbl) || ' ADD TABLE ' || sys.FQN(p_sch, p_tbl) ||
+ CASE
+ WHEN tpe = 'VALUES' THEN ' AS PARTITION IN (' || pvalues || ')'
+ WHEN tpe = 'RANGE' THEN ' AS PARTITION FROM ' || ifthenelse(minimum IS
NOT NULL, sys.SQ(minimum), 'RANGE MINVALUE') || ' TO ' || ifthenelse(maximum IS
NOT NULL, sys.SQ(maximum), 'RANGE MAXVALUE')
+ WHEN tpe = 'FOR NULLS' THEN ' AS PARTITION FOR NULL VALUES'
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list