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
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to