1
declare
2
command text;
3
viewtext text[];
4
viewname name[];
5
dropviews name[];
6
i int;
7
j int;
8
v record;
9
sqltype text;
10
sqltype_short text;
11
typename name;
12
begin
13
if datatype is not null then
14
select pg_type.typname, format_type(pg_type.oid, pg_attribute.atttypmod)
15
into typename, sqltype
16
from pg_class, pg_attribute, pg_type
17
where relname = lower(tablename)
18
and relkind = 'r'
19
and pg_class.oid = pg_attribute.attrelid
20
and attname = lower(columnname)
21
and atttypid = pg_type.oid;
22
sqltype_short := sqltype;
23
if typename = 'numeric' then
24
sqltype_short := replace(sqltype, ',0', '');
25
elsif strpos(sqltype,'character varying') = 1 then
26
sqltype_short := replace(sqltype, 'character varying', 'varchar');
27
elsif sqltype = 'timestamp without time zone' then
28
sqltype_short := 'timestamp';
29
end if;
30
if lower(datatype) <> sqltype and lower(datatype) <> sqltype_short then
31
i := 0;
32
for v in
33
with recursive depv(relname, viewoid, depth) as (
34
select distinct a.relname, a.oid, 1
35
from pg_class a, pg_depend b, pg_depend c, pg_class d, pg_attribute e
36
where a.oid = b.refobjid
37
and b.objid = c.objid
38
and b.refobjid <> c.refobjid
39
and b.deptype = 'n'
40
and c.refobjid = d.oid
41
and d.relname = lower(tablename)
42
and d.relkind = 'r'
43
and d.oid = e.attrelid
44
and e.attname = lower(columnname)
45
and c.refobjsubid = e.attnum
46
and a.relkind = 'v'
47
union all
48
select distinct dependee.relname, dependee.oid, depv.depth+1
49
from pg_depend
50
join pg_rewrite on pg_depend.objid = pg_rewrite.oid
51
join pg_class as dependee on pg_rewrite.ev_class = dependee.oid
52
join pg_class as dependent on pg_depend.refobjid = dependent.oid
53
join pg_attribute ON pg_depend.refobjid = pg_attribute.attrelid and pg_depend.refobjsubid = pg_attribute.attnum and pg_attribute.attnum > 0
54
join depv on dependent.relname = depv.relname
55
)
56
select relname, viewoid, max(depth) from depv group by relname, viewoid order by 3 desc
57
loop
58
i := i + 1;
59
viewtext[i] := pg_get_viewdef(v.viewoid);
60
viewname[i] := v.relname;
61
end loop;
62
if i > 0 then
63
begin
64
for j in 1 .. i loop
65
command := 'drop view ' || viewname[j];
66
raise notice 'executing -> %', command;
67
execute command;
68
dropviews[j] := viewname[j];
69
end loop;
70
exception
71
when others then
72
i := array_upper(dropviews, 1);
73
if i > 0 then
74
for j in reverse i .. 1 loop
75
command := 'create or replace view ' || dropviews[j] || ' as ' || viewtext[j];
76
raise notice 'executing -> %', 'create view ' || dropviews[j];
77
execute command;
78
end loop;
79
end if;
80
raise exception 'Failed to recreate dependent view. SQLERRM=%', SQLERRM;
81
end;
82
end if;
83
command := 'alter table ' || lower(tablename) || ' alter column ' || lower(columnname) || ' type ' || lower(datatype);
84
raise notice 'executing -> %', command;
85
execute command;
86
i := array_upper(dropviews, 1);
87
if i > 0 then
88
for j in reverse i .. 1 loop
89
command := 'create or replace view ' || dropviews[j] || ' as ' || viewtext[j];
90
raise notice 'executing -> %', 'create view ' || dropviews[j];
91
execute command;
92
end loop;
93
end if;
94
end if;
95
end if;
96
97
if defaultclause is not null then
98
if lower(defaultclause) = 'null' then
99
command := 'alter table ' || lower(tablename) || ' alter column ' || lower(columnname) || ' drop default ';
100
else
101
if defaultclause ~ '.*[(].*[)].*' or lower(defaultclause) = 'current_timestamp' then
102
command := 'alter table ' || lower(tablename) || ' alter column ' || lower(columnname) || ' set default ' || defaultclause;
103
else
104
command := 'alter table ' || lower(tablename) || ' alter column ' || lower(columnname) || ' set default ''' || defaultclause || '''';
105
end if;
106
end if;
107
raise notice 'executing -> %', command;
108
execute command;
109
end if;
110
111
if nullclause is not null then
112
if lower(nullclause) = 'not null' then
113
command := 'alter table ' || lower(tablename) || ' alter column ' || lower(columnname) || ' set not null';
114
raise notice 'executing -> %', command;
115
execute command;
116
elsif lower(nullclause) = 'null' then
117
command := 'alter table ' || lower(tablename) || ' alter column ' || lower(columnname) || ' drop not null';
118
raise notice 'executing -> %', command;
119
execute command;
120
end if;
121
end if;
122
end;