Forum OpenACS Q&A: upgrading to PG 7.3 on old 3.x ACS
I've recently upgraded my server to Postgres 7.3 and my (ancient) OACS 3.x some of the code seems to be breaking. So, I'd like to druge up some old code and see if you can help me :).
There are problems I figured out (for example ::datetime needs to be ::timestamptz). But there are ones I can't figure out. Especially stuff in the homepage procedures. For example, hp_get_filesystem_root_node works when changed to t he following:
create function hp_get_filesystem_root_node(integer) returns integer as '
declare
u_id alias for $1;
root_id integer;
BEGIN
select file_id into root_id from users_files
where filename = u_id::varchar
and parent_id is null
and owner_id = u_id;
return root_id;
END;
' language 'plpgsql';
But I tried doing the same fix on hp_true_filename (knocking the additional OR constraing on the "parent_id is null" line) and get this error:
denali=# select hp_true_filename(10) from dual; WARNING: plpgsql: ERROR during compile of hp_true_filename near line 3 ERROR: parser: parse error at or near ")" at character 15The function definition is
create function hp_true_filename(integer) returns varchar as '
declare
filesystem_node alias for $1;
fullname varchar;
parentid integer;
BEGIN
select into parentid parent_id from users_files
where file_id = filesystem_node;
select into fullname filename from users_files
where file_id = filesystem_node;
IF parentid is null or parentid = ''''
THEN
return fullname;
ELSE
return hp_true_filename(parentid) || ''/'' || fullname;
END IF;
END;
' language 'plpgsql';
Any ideas? Pointers to stuff that will help me out, specific help, or whatever else you think might be helpful, would be really appreciated!
Posted by
Vinod Kurup
on 09/29/03 04:33 AM
Hi Justin,
Not sure if this is the issue for you, but I think psql has become very intolerant of tabs in PG 7.3. See my post about this. Try converting all the tabs in hp_true_filename to spaces and then reloading it into psql.
Posted by
Justin Palmer
on 09/29/03 04:42 AM
Thanks, Vinod. It turns out that the issue wasn't tabs. The problem was that it didn't like some of the boolean operations. Below are functions that work. psql -f them in and it's set.
-- returned value is a filename that does not begin with a slash
create or replace function hp_true_filename(integer) returns varchar as '
declare
filesystem_node alias for $1;
fullnamevarchar;
parentidinteger;
BEGIN
select into parentid parent_id from users_files
where file_id = filesystem_node;
select into fullname filename from users_files
where file_id = filesystem_node;
IF parentid
THEN
return fullname;
ELSE
return hp_true_filename(parentid) || ''/'' || fullname;
END IF;
END;
' language 'plpgsql';
-- drop function hp_true_dirname(integer);
create or replace function hp_true_dirname(integer) returns varchar as '
declare
filesystem_node alias for $1;
fullnamevarchar;
parentidinteger;
dirp char(1);
BEGIN
select into parentid parent_id from users_files
where file_id = filesystem_node;
select into fullname filename from users_files
where file_id = filesystem_node;
select into dirp directory_p from users_files
where file_id = filesystem_node;
IF dirp = ''f'' then
fullname := '''';
END IF;
IF parentid
THEN
return fullname;
ELSE
return hp_true_dirname(parentid) || ''/'' || fullname;
END IF;
END;
' language 'plpgsql';
-- returned value is a varchar2 which is the sort key
-- Uses the fact that the full filename of each file has
-- to be unique.
-- drop function hp_filesystem_node_sortkey_gen(integer,integer);
create or replace function hp_filesystem_node_sortkey_gen(integer,integer)
returns varchar as '
declare
filesystem_node alias for $1;
start alias for $2;
fullnamevarchar;
parentidinteger;
dir_pvarchar(1);
plsql_valrecord;
discriminatorvarchar(5); -- useful for discriminating between files and directories
BEGIN
select into plsql_val
filename,
(case when directory_p = ''t'' then ''0'' else ''1'' end) as dp,
parent_id
from users_files
where file_id = filesystem_node;
dir_p := plsql_val.dp;
fullname := plsql_val.filename;
parentid := plsql_val.parent_id;
IF parentid = start or parentid
THEN
return dir_p || fullname;
ELSE
return hp_filesystem_node_sortkey_gen(parentid,start) || ''/'' || dir_p || fullname;
END IF;
END;
' language 'plpgsql';
-- select *,hp_filesystem_node_sortkey_gen(file_id) as generated_sort_key,filename
-- from users_files order by generated_sort_key asc;
-- drop function hp_filesystem_node_level_gen(integer,integer,integer);
create or replace function hp_filesystem_node_level_gen(integer,integer,integer)
returns integer as '
declare
filesystem_node alias for $1;
count alias for $2;
start alias for $3;
parentidinteger;
BEGIN
select into parentid parent_id
from users_files
where file_id = filesystem_node;
IF parentid = start or parentid
THEN
return count;
ELSE
return hp_filesystem_node_level_gen(parentid,count+1,start);
END IF;
END;
' language 'plpgsql';
-- drop function hp_id_is_subnode(integer,integer);
create or replace function hp_id_is_subnode(integer,integer)
returns varchar as '
declare
node alias for $1;
filesystem_node alias for $2;
parentidinteger;
BEGIN
select into parentid parent_id
from users_files
where file_id = node;
IF parentid is null THEN
return ''f'';
ELSE IF parentid = filesystem_node THEN
return ''t'';
ELSE
return hp_id_is_subnode(parentid,filesystem_node);
END IF;
END IF;
END;
' language 'plpgsql';
-- select *,hp_filesystem_node_sortkey_gen(file_id) as generated_sort_key,hp_filesystem_node_level_gen(file_id,0) as level
-- from users_files order by generated_sort_key asc;
-- returns a filename beginning with a slash, unless the file is user's root
-- drop function hp_user_relative_filename(integer);
create or replace function hp_user_relative_filename(integer) returns varchar as '
declare
filesystem_node alias for $1;
fullnamevarchar;
parentidinteger;
BEGIN
select into fullname filename from users_files
where file_id = filesystem_node;
select into parentid parent_id from users_files
where file_id = filesystem_node;
IF parentid
THEN
return '''';
ELSE
return hp_user_relative_filename(parentid) || ''/'' || fullname;
END IF;
END;
' language 'plpgsql';
-- drop function hp_get_filesystem_root_node(integer);
create or replace function hp_get_filesystem_root_node(integer) returns integer as '
declare
u_id alias for $1;
root_id integer;
BEGIN
select into root_id file_id from users_files
where filename = u_id::varchar
and parent_id is null
and owner_id = u_id;
return root_id;
END;
' language 'plpgsql';
select hp_get_filesystem_root_node(1);
create or replace function hp_get_filesystem_node_owner(integer) returns integer as '
declare
fsid alias for $1;
owner_idinteger;
BEGIN
select into owner_id owner_id from users_files
where file_id = fsid;
return owner_id;
END;
' language 'plpgsql';
create or replace function hp_get_filesystem_child_count(integer) returns integer as '
declare
fsid alias for $1;
counter integer;
BEGIN
select into counter count(*) from users_files
where parent_id = fsid;
return counter;
END;
' language 'plpgsql';
-- drop function hp_access_denied_p(integer,integer);
create or replace function hp_access_denied_p(integer,integer) returns integer as '
declare
fsid alias for $1;
u_id alias for $2;
o_id integer;
BEGIN
select into o_id owner_id from users_files
where file_id = fsid;
IF o_id = u_id
THEN
return 0;
ELSE
return 1;
END IF;
END;
' language 'plpgsql';
-- select hp_access_denied_p(2,1);
-- drop function hp_fs_node_from_rel_name(integer,varchar);
create or replace function hp_fs_node_from_rel_name(integer,varchar) returns integer as '
declare
rootid alias for $1;
rel_name alias for $2;
id integer;
rname varchar;
slash_location integer;
nodeid integer;
BEGIN
rname := rel_name;
id := rootid;
LOOP
IF rname = '''' THEN
return id;
END IF;
slash_location := position(''/'' in rname);
IF slash_location = 0 THEN
select into nodeid file_id
from users_files
where parent_id = id
and filename = rname;
return nodeid;
ELSE IF slash_location = 1 THEN
rname := substr(rname,2);
ELSE
select into nodeid file_id
from users_files
where parent_id = id
and filename = SUBSTR(rname,1,slash_location - 1);
id := nodeid;
rname := substr(rname,slash_location);
END IF;
END IF;
END LOOP;
END;
' language 'plpgsql';
------------------------------------------
-- ENDOF fileSystemManagement codeBlock --
------------------------------------------
---------------------------------------------
-- BEGINNINGOF contentManagement codeBlock --
---------------------------------------------
create or replace function hp_top_level_content_title(integer) returns varchar as '
declare
filesystem_node alias for $1;
managedp varchar(1);
fullnamevarchar;
parentidinteger;
parent_managedpvarchar(1);
BEGIN
select into fullname file_pretty_name from users_files
where file_id = filesystem_node;
select into parentid parent_id from users_files
where file_id = filesystem_node;
select into managedp managed_p from users_files
where file_id = filesystem_node;
IF parentid
THEN
return fullname;
END IF;
IF managedp = ''t''
THEN
select into parent_managedp managed_p
from users_files
where file_id = parentid;
IF parent_managedp = ''f''
THEN
return fullname;
ELSE
return hp_top_level_content_title(parentid);
END IF;
ELSE
return fullname;
END IF;
END;
' language 'plpgsql';
create or replace function hp_top_level_content_node(integer) returns varchar as '
declare
filesystem_node alias for $1;
managedp varchar(1);
parentidinteger;
parent_managedpvarchar(1);
BEGIN
select into parentid parent_id from users_files
where file_id = filesystem_node;
select into managedp managed_p from users_files
where file_id = filesystem_node;
IF parentid
THEN
return filesystem_node;
END IF;
IF managedp = ''t''
THEN
select managed_p into parent_managedp
from users_files
where file_id = parentid;
IF parent_managedp = ''f''
THEN
return filesystem_node;
ELSE
return hp_top_level_content_node(parentid);
END IF;
ELSE
return filesystem_node;
END IF;
END;
' language 'plpgsql';
create or replace function hp_onelevelup_content_title(integer) returns varchar as '
declare
filesystem_node alias for $1;
managedp varchar(1);
dirpvarchar(1);
parentidinteger;
fullnamevarchar;
BEGIN
select into fullname file_pretty_name from users_files
where file_id = filesystem_node;
select into parentid parent_id from users_files
where file_id = filesystem_node;
select into managedp managed_p from users_files
where file_id = filesystem_node;
select into dirp directory_p from users_files
where file_id = filesystem_node;
IF parentid
THEN
return fullname;
END IF;
IF managedp = ''t''
THEN
IF dirp = ''t''
THEN
return fullname;
ELSE
return hp_onelevelup_content_title(parentid);
END IF;
ELSE
return fullname;
END IF;
END;
' language 'plpgsql';
create or replace function hp_onelevelup_content_node(integer) returns varchar as '
declare
filesystem_node alias for $1;
managedp varchar(1);
dirpvarchar(1);
parentidinteger;
BEGIN
select into parentid parent_id from users_files
where file_id = filesystem_node;
select into managedp managed_p from users_files
where file_id = filesystem_node;
select into dirp directory_p from users_files
where file_id = filesystem_node;
IF parentid
THEN
return filesystem_node;
END IF;
IF managedp = ''t''
THEN
IF dirp = ''t''
THEN
return filesystem_node;
ELSE
return hp_onelevelup_content_node(parentid);
END IF;
ELSE
return filesystem_node;
END IF;
END;
' language 'plpgsql';
---------------------------------------
-- ENDOF contentManagement codeBlock --
---------------------------------------
---------------------------------------------------
-- BEGINNINGOF neighbourhoodManagement codeBlock --
---------------------------------------------------
create or replace function hp_true_neighborhood_name(integer) returns varchar as '
declare
neighborhood_node alias for $1;
fullname varchar;
parentid integer;
BEGIN
select into fullname neighborhood_name from users_neighborhoods
where neighborhood_id = neighborhood_node;
select into parentid parent_id from users_neighborhoods
where neighborhood_id = neighborhood_node;
IF parentid
THEN
return fullname;
ELSE
return hp_true_neighborhood_name(parentid) || '' : '' || fullname;
END IF;
END;
' language 'plpgsql';
create or replace function hp_get_neighborhood_root_node() returns integer as '
declare
root_idinteger;
BEGIN
select into root_id neighborhood_id
from users_neighborhoods
where parent_id is null
return root_id;
END;
' language 'plpgsql';
create or replace function hp_relative_neighborhood_name(integer) returns varchar as '
declare
neighborhood_node alias for $1;
fullname varchar;
parentid integer;
root_node integer;
BEGIN
select into fullname neighborhood_name from users_neighborhoods
where neighborhood_id = neighborhood_node;
select into parentid parent_id from users_neighborhoods
where neighborhood_id = neighborhood_node;
select hp_get_neighborhood_root_node()
into root_node;
IF neighborhood_node = root_node
THEN
return '''';
END IF;
IF parentid
THEN
return '''';
END IF;
IF parentid = root_node
THEN
return fullname;
ELSE
return hp_relative_neighborhood_name(parentid) || '' : '' || fullname;
END IF;
END;
' language 'plpgsql';
-- generates a sort key for this neighbourhood. Can be used in 'connect by'
-- with 'order by'.
-- drop function hp_neighborhood_sortkey_gen(integer,integer);
create or replace function hp_neighborhood_sortkey_gen(integer,integer)
returns varchar as '
declare
neighborhood_node alias for $1;
start alias for $2;
fullname varchar;
parentid integer;
BEGIN
select into fullname neighborhood_name from users_neighborhoods
where neighborhood_id = neighborhood_node;
select into parentid parent_id from users_neighborhoods
where neighborhood_id = neighborhood_node;
IF parentid = start or parentid
THEN
return ''/'';
ELSE
return hp_neighborhood_sortkey_gen(parentid,start) || ''/'' || fullname;
END IF;
END;
' language 'plpgsql';
-- drop function hp_neighborhood_level_gen(integer,integer,integer);
create or replace function hp_neighborhood_level_gen(integer,integer,integer)
returns integer as '
declare
neighborhood_node alias for $1;
count alias for $2;
start alias for $3;
parentid integer;
BEGIN
select into parentid parent_id from users_neighborhoods
where neighborhood_id = neighborhood_node;
IF parentid = start or parentid
THEN
return count;
ELSE
return hp_neighborhood_level_gen(parentid,count+1,start);
END IF;
END;
' language 'plpgsql';
-- drop function hp_neighborid_is_subnode(integer,integer);
create or replace function hp_neighborid_is_subnode(integer,integer)
returns varchar as '
declare
node alias for $1;
neighborhood_node alias for $2;
parentid integer;
BEGIN
select into parentid parent_id
from users_neighborhoods
where neighborhood_id = node;
IF parentid is null THEN
return ''f'';
ELSE IF parentid = neighborhood_node THEN
return ''t'';
ELSE
return hp_neighborid_is_subnode(parentid,neighborhood_node);
END IF;
END IF;
END;
' language 'plpgsql';
create or replace function hp_get_nh_child_count(integer) returns integer as '
declare
neighborhoodid alias for $1;
counter integer;
BEGIN
select into counter count(*) from users_neighborhoods
where parent_id = neighborhoodid;
return counter;
END;
' language 'plpgsql';
create or replace function hp_neighborhood_in_subtree_p(integer,integer) returns varchar as '
declare
source_node alias for $1;
target_node alias for $2;
parentid integer;
BEGIN
select into parentid parent_id from users_neighborhoods
where neighborhood_id = target_node;
IF source_node = target_node
THEN
return ''t'';
END IF;
IF parentid
THEN
return ''f'';
ELSE
IF parentid = source_node
THEN
return ''t'';
ELSE
return hp_neighborhood_in_subtree_p(source_node, parentid);
END IF;
END IF;
END;
' language 'plpgsql';
---------------------------------------------
-- ENDOF neighbourhoodManagement codeBlock --
---------------------------------------------
-- drop function mobin_function_definition2(integer);
create or replace function mobin_function_definition2(integer) returns integer as '
declare
max_id alias for $1;
total integer;
id_rec record;
BEGIN
total := 0;
FOR id_rec IN select * from users
where user_id < max_id
LOOP
EXIT WHEN not found;
total := total + id_rec.user_id;
END LOOP;
return total;
END;
' language 'plpgsql';
select mobin_function_definition2(5);
-----------------------------------
-- BEGINNINGOF useless codeBlock --
-----------------------------------
-- This is a function that I have hath use for ofttimes.
create or replace function mobin_function_definition(varchar) returns varchar as '
declare
function_name alias for $1;
fn_rec record;
fn_totalvarchar(4000);
BEGIN
fn_total := '''';
FOR fn_rec IN select * from USER_SOURCE
where Name = upper(function_name)
and Type = ''FUNCTION''
order by Line
LOOP
EXIT WHEN not found;
fn_total := fn_total || fn_rec.Text;
END LOOP;
return fn_total;
END;
' language 'plpgsql';
-- A view I find rather useful
-- create view hp_functions as
-- select lower(Name) as function_name, count(*) as line_count
-- from USER_SOURCE
-- where Type = 'FUNCTION'
-- and Name like 'HP_%'
-- and Name != 'HP_FUNCTIONS'
-- group by Name;
-----------------------------
-- ENDOF useless codeBlock --
-----------------------------
----------------------------------
-- BEGINNINGOF useful codeBlock --
----------------------------------
-- this function is so useful that I can't tell you!
-- create or replace function mobin_number_to_letter(integer) returns varchar as '
-- set letter_no $1
-- set decode_tbl [list null A B C D E F G H I J K L M N O P Q R S T U V W X Y Z]
-- if { $letter_no < 1 || $letter_no > 26 } { return Z }
-- return [lindex $decode_tbl $letter_no]
-- ' language 'pltcl';
----------------------------
-- ENDOF useful codeBlock --
----------------------------
-----------------------------------------------
-- BEGINNINGOF userQuotaManagement codeBlock --
-----------------------------------------------
create or replace function hp_user_quota_max(integer,integer,integer,integer)
returns integer as '
declare
userid alias for $1;
lesser_mortal_quota alias for $2;
higher_mortal_quota alias for $3;
higher_mortal_p alias for $4;
quota_max integer;
special_countinteger;
return_valueinteger;
BEGIN
select count(*) into special_count
from users_special_quotas
where user_id = userid;
IF special_count = 0
THEN
IF higher_mortal_p = 0
THEN
select trunc(lesser_mortal_quota * pow(2.0,20.0))
into return_value;
return return_value;
ELSE
select trunc(higher_mortal_quota * pow(2.0,20.0))
into return_value;
return return_value;
END IF;
ELSE
select max_quota into quota_max
from users_special_quotas
where user_id = userid;
select trunc(quota_max * pow(2.0,20.0))
into return_value;
return return_value;
END IF;
END;
' language 'plpgsql';
-- drop function hp_user_quota_max_check_admin(integer,integer,integer);
create or replace function hp_user_quota_max_check_admin(integer,integer,integer)
returns integer as '
declare
userid alias for $1;
lesser_mortal_quota alias for $2;
higher_mortal_quota alias for $3;
quota_max integer;
special_countinteger;
return_valueinteger;
higher_mortal_pinteger;
BEGIN
select count(*) into special_count
from users_special_quotas
where user_id = userid;
select count(*) into higher_mortal_p
from user_group_map ugm
where ugm.user_id = userid
and ugm.group_id = system_administrator_group_id();
IF special_count = 0
THEN
IF higher_mortal_p = 0
THEN
select trunc(lesser_mortal_quota * pow(2.0,20.0))
into return_value;
return return_value;
ELSE
select trunc(higher_mortal_quota * pow(2.0,20.0))
into return_value;
return return_value;
END IF;
ELSE
select max_quota into quota_max
from users_special_quotas
where user_id = userid;
select trunc(quota_max * pow(2.0,20.0))
into return_value;
return return_value;
END IF;
END;
' language 'plpgsql';
create or replace function hp_user_quota_used(integer,integer) returns integer as '
declare
userid alias for $1;
dir_requirement alias for $2;
return_value integer;
file_spaceinteger;
dir_spaceinteger;
BEGIN
select (count(*) * dir_requirement) into dir_space
from users_files
where directory_p = ''t''
and owner_id = userid;
select coalesce(sum(file_size),0) into file_space
from users_files
where directory_p = ''f''
and owner_id = userid;
return_value := dir_space + file_space;
return return_value;
END;
' language 'plpgsql';
create or replace function hp_user_quota_left(integer,integer,integer,integer,integer)
returns integer as '
declare
userid alias for $1;
lesser_mortal_quota alias for $2;
higher_mortal_quota alias for $3;
higher_mortal_p alias for $4;
dir_requirement alias for $5;
return_value integer;
BEGIN
select (hp_user_quota_max(userid, lesser_mortal_quota, higher_mortal_quota, higher_mortal_p) - hp_user_quota_used(userid, dir_requirement))
into return_value;
return return_value;
END;
' language 'plpgsql';
create or replace function hp_user_quota_left_check_admin(integer,integer,integer,integer) returns integer as '
declare
userid alias for $1;
lesser_mortal_quota alias for $2;
higher_mortal_quota alias for $3;
dir_requirement alias for $4;
return_value integer;
BEGIN
select (hp_user_quota_max_check_admin(userid, lesser_mortal_quota, higher_mortal_quota) - hp_user_quota_used(userid, dir_requirement))
into return_value;
return return_value;
END;
' language 'plpgsql';
-----------------------------------------
-- ENDOF userQuotaManagement codeBlock --
-----------------------------------------
create or replace function hp_screen_name(integer) returns varchar as '
declare
id alias for $1;
namein varchar;
begin
select into namein screen_name from users where user_id = id;
return namein;
end;
' language 'plpgsql';
create or replace function hp_users_files(integer) returns integer as '
declare
id alias for $1;
cnt integer;
begin
select into cnt count(*)
from users_files
where filename = id::varchar
and parent_id is null
and owner_id = id;
return cnt;
end;
' language 'plpgsql';
create or replace function hp_dir_exists(varchar,integer) returns integer as '
declare
dir_name alias for $1;
node alias for $2;
cnt integer;
begin
select into cnt count(*)
from users_files
where filename = dir_name
and parent_id = node;
return cnt;
end;
' language 'plpgsql';
create or replace function hp_quota_used(integer,integer) returns integer as '
declare
id alias for $1;
dir_space alias for $2;
file_q integer;
dir_q integer;
begin
select into dir_q count(*) * dir_space
from users_files
where directory_p = ''t''
and owner_id = id;
select into file_q coalesce(sum(file_size),0)
from users_files
where directory_p = ''f''
and owner_id = id;
return file_q + dir_q;
end;
' language 'plpgsql';
create or replace function hp_quota_max(integer,integer) returns integer as '
declare
id alias for $1;
max_quota alias for $2;
cnt_q integer;
max_q integer;
begin
select into cnt_q count(*) from
users_special_quotas
where user_id = id;
select into max_q max_quota from
users_special_quotas
where user_id = id;
if not found then
max_q := 0;
end if;
return (case when cnt_q = 0 then max_quota else max_q end);
end;
' language 'plpgsql';
-- drop function hp_directory_exists(varchar,integer);
create or replace function hp_directory_exists(varchar,integer) returns integer as '
declare
short_name alias for $1;
node alias for $2;
cnt integer;
begin
select into cnt count(*)
from users_files
where filename = short_name
and parent_id = node;
return cnt;
end;
' language 'plpgsql';
-- drop function hp_content_name_from_type(integer);
create or replace function hp_content_name_from_type(integer) returns varchar as '
declare
c_type alias for $1;
t_name varchar;
begin
select into t_name type_name
from users_content_types
where type_id = c_type;
return t_name;
end;
' language 'plpgsql';
-- drop function hp_content_type(integer);
create or replace function hp_content_type(integer) returns varchar as '
declare
node alias for $1;
t_name varchar;
begin
select into t_name type_name
from users_content_types
where type_id = (select content_type
from users_files
where file_id = node);
return t_name;
end;
' language 'plpgsql';
-- drop function hp_content_subtype(integer);
create or replace function hp_content_subtype(integer) returns varchar as '
declare
node alias for $1;
t_name varchar;
begin
select into t_name sub_type_name
from users_content_types
where type_id = (select content_type
from users_files
where file_id = node);
return t_name;
end;
' language 'plpgsql';
-- drop function power(integer,integer);
create or replace function power(integer,integer) returns float8 as '
declare
base alias for $1;
exp alias for $2;
begin
return pow(float8(base),float8(exp));
end;
' language 'plpgsql';