Forum OpenACS Development: Differences between Oracle and PostgreSQL on db_exec_plsql function

I open this post to comment one error I found on fs::get_root_folder function when I tried to mount xowiki outside of dotlrn on oracle. Thanks to Gustaf I can do it but He said me that the return value is different between PostgreSQL and oracle on this function.

I'm searched this and I found that:

- PostgreSQL return empty string when no rows are found and call to db_exec_plsql works correctly, but Oracle return one error if no rows are found.

create function inline_0() returns integer as '
declare
v_folder_id integer;
begin
        select folder_id into v_folder_id
        from fs_root_folders
        where package_id = 123;
        return v_folder_id;
end;
' language 'plpgsql';
select inline_0();

Function on oracle and error.

declare
  2  v_folder_id integer;
  3  begin
  4  select folder_id into v_folder_id
  5  from fs_root_folders
  6  where package_id = 123;
  7  end;
  8  /
declare
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 4

If I'm coding

return [db_exec_plsql sql_function {}]
then I get empty string for PostgreSQL and I get a error for Oracle.

I want fix this error but I think that the solution isn't trivial. Maybe it should fixed on openacs because I think that it's no only for fs::get_root_folder function.

The bug is in the function itself not db_exec_plsql.

Select into returns an exception if not rows are returned.

So in this case the function must only be passed a valid package_id or you should catch the call to db_exec_plsql i guess.

I have never seen this come up in use as an error.

Thanks Dave,

I agree with you. The function can catch error and return some value but PL/SQL only can return integer an PGSQL could return empty string or integer.

When I call to db_exec_plsql on oracle and get error should be catch inside and return some code (0,-1,...). One problem is PostgreSQL could return "".

If i call to the tcl function I can receive one integer or empty string for PostgreSQL, and integer (or error) for Oracle and no is the same behavior Ej

If { [fs::get_root_folder -package_id 123] eq "" } {
#package_id isn't exist but it work for PG and not for Oracle.
}

Maybe, It's posible to normalize calls to Oracle PL/SQL and return empty string if it get errors.

I hope, you can understand my special english 😟.

I am not sure why xowiki is calling file storage apis here. Since file storage package works fine in Oracle for years now, this is a bug in how that tcl procedure is being called.

You are correct, but in practice I haven't seen any issue with this difference in oracle and postgresql. Again it has nothing to do with calling a pl/sql function since we can't know what code is run in that function. I suppose there might be a way to rewrite the oracle function to return an NULL response if there are no rows but it seems problematic. It definitely would have to be fixed within the function that calls select into. I can't see any way you'd want to catch all errors in pl/sql on oracle and return an empty string. That would definitely lead to more problems than it would solve.

The problem here is that there is no file storage root folder when one is expected. If you returned an empty stirng the underlying bug would be hidden.

Well, xowiki does not call fs::get_root_folder, but dotlrn does it. xowiki calls - in case dotlrn is installed - dotlrn_fs::get_community_shared_folder to determine the folder where the xinha plugin should add uploaded files. Since version 0.91 (August this year), xowiki programs around this problem with oracle.

Nevertheless, the behavior of an API call should be identical for PostgreSQL and Oracle. Since the API has no fs::exists_root_folder returning empty sounds ok to me in case the package has no root folder. Otherwise, the API documentation should mention a word about this. The argument, that the "file storage package works fine in Oracle for years now" cannot certainly mean that the fs::*-api is free of bugs.

Ignoring all errors in db_exec_plsql is certainly no good idea. For get_root_folder, adding an exception handler for "No data found" in file-storage-procs-oracle.xql seems like a good option to me (see for example
http://www.oracle.com/technology/oramag/oracle/03-jul/o43plsql.html).

By looking at the file-storage code: the procs fs_get_root_folder (and friends) should be replaced by fs::get_root_folder (and friends) (or marked as deprecated for the short range). Additionally, the code with the Oracle notation in fs_get_folder_name in file-storage-procs.tcl is at least misleading. So getting rid of fs_* should be on our todo list for the mid range.

-gustaf neumann