I've created a new wiki page to track the procedures/functions migration: https://fedorahosted.org/spacewalk/wiki/PgportProcedures
Please update the wiki page if you have worked or are working on any. Regards, Farrukh On Tue, Feb 17, 2009 at 3:26 PM, Muhammad Farrukh < muhammad.farr...@enterprisedb.com> wrote: > > > On Thu, Feb 12, 2009 at 4:26 PM, Gurjeet Singh < > gurjeet.si...@enterprisedb.com> wrote: > >> I am using upper case to highlight the usage of keywords. We otherwise >> should not be using uppercase in this porting effort. >> >> .) Datatypes: >> >> We follow the same rules for converting datatypes that we followed in >> porting tables. >> number => numeric (for now, until we convert tables' number columns to >> bigints as agreed) >> varchar2 => varchar >> date => timestamp >> blob, long, long raw, ... => bytea >> clob, long varchar, ... => text >> >> .) PROCEDURE >> >> Procedure keyword is not supprted in Postgres. So we should convert >> all PROCEDUREs to FUNCTIONs with RETURNS VOID, like so: >> >> create or replace function procedure_example(arg1 datatype, ...) >> RETURNS VOID as $$ ... $$ language plpgsql; >> >> .) Function without parameters >> >> Oracle does not require the pair of parantheses if there's no >> parameter to the procedure/function. But Postgres requires them, so do it >> like so: >> >> create function f return int as begin return 10; end; >> >> TO >> >> create function f() returns int as $$ begin return 10; end; $$ >> language plpgsql; >> >> .) RETURN clause >> >> As you must have noticed in the above example, Postgres uses RETURNS >> keyword to designate the return datatype of a function as opposed to RETURN >> keyword used by Oracle. >> >> .) IS vs. AS >> >> In Oracle, AS and IS keywords can be used interchangeably to denote >> the satrt of the function/procedure code. But in Postgres, only AS keyword >> should be used. >> >> .) DECLARE section >> >> In Oracle, the first DECLARE section can be started without the >> DECLARE keyword, since the block between AS and the BEGIN keywords is >> treadted so. In plpgsql, the first DECLARE section must be introduced >> explicitly. >> >> $$ >> DECLARE >> a int; >> BEGIN >> return a := 10; >> end; >> $$ >> >> .) EXECUTE IMMEDIATE >> >> For the cases where the plsql code is just executing command embedded >> in a string, simply drop the IMMEDIATE keyword. >> >> EXECUTE IMMEDIATE 'Truncate Table rhnOrgErrataCacheQueue'; >> >> TO >> >> execute 'Truncate Table rhnOrgErrataCacheQueue'; >> >> .) EXCEPTIONS >> >> There are direct mappings for most of the PLSQL named exceptions. >> Please refer to >> http://www.postgresql.org/docs/8.1/static/errcodes-appendix.html >> >> DUP_VAL_ON_INDEX => UNIQUE_VIOLATION >> >> .) WHEN_NO_DATA_FOUND >> >> In Oracle, this exception is used to detect if a SELECT failed to >> fetch any data. It is not possible in Postgres 8.1 (it has been remedied >> since version 8.2). >> >> In Postgres 8.1, we have to check the FOUND variable instead. >> <Oracle code> >> declare >> arch_type_id number; >> begin >> select id into arch_type_id from rhnArchType where label = >> label_in; >> return arch_type_id; >> exception >> when no_data_found then >> rhn_exception.raise_exception('arch_type_not_found'); >> end; >> </Oracle code> >> TO >> <Postgres code> >> declare >> arch_type_id numeric; >> begin >> select id into arch_type_id from rhnArchType where label = >> label_in; >> >> if not FOUND then >> perform rhn_exception.raise_exception('arch_type_not_found'); >> end if; >> >> return arch_type_id; >> end; >> </Postgres code> >> >> .) CURSORs >> >> Please see >> http://www.postgresql.org/docs/8.1/static/plpgsql-cursors.html for >> detailed cursor usage description. >> >> In short, convert cursors as follows: >> >> <Oracle code> >> cursor systems is >> select s.element id >> from rhnSet s >> where s.user_id = user_id_in >> and s.label = 'system_list'; >> </Oracle code> >> <Postgres code> >> systems cursor for >> select s.element id >> from rhnSet s >> where s.user_id = user_id_in >> and s.label = 'system_list'; >> </Postgres code> >> >> .) DETRMINISTIC keyword should be converted to STABLE like so: >> >> create function.... $$ begin ... 4nd; $$ language plpgsql STABLE; >> >> .) Executing procedures >> >> When executing a procedure (a function without a return datatype) or >> when performing a SELECT without INTO clause or whose result is not being >> captured into a local variable, use the PERFORM keyword. >> >> <Oracle code> >> exception >> when no_data_found then >> rhn_exception.raise_exception('arch_type_not_found'); >> >> </Oracle code> >> <Postgres code> >> exception >> when no_data_found then >> PERFORM >> rhn_exception.raise_exception('arch_type_not_found'); >> </Postgres code> >> >> .) SHOW ERROR and / >> In Postgres the ERRORs encountered in creating a plpgsql using are >> shown immediately; so we don't need to port SHOW ERROR. Just get rid of it. >> Also, psql (postgres CLI client) automatically detects end of function >> code, so the / (slash) after each function/procedure is not needed either. >> >> .) AUTONOMOUS TRANSACTIONS >> Remove the COMMIT staments; Oracle requires that an AUTONOMOUS_TRANSACTION >> be explicitly COMMITted, else it will be rolled back. This does not apply to >> Postgres. >> >> And example of porting fllows: >> Oracle version: >> =============== >> create or replace function del( a int, b char, c varchar ) return int as >> pragma autonomous_transaction; >> begin >> return 10; >> commit; >> end; >> / >> >> Postgres version: >> ================= >> >> /* the actual function should be renamed */ >> create or replace function >> del_autonomous( a int, b char, c varchar) >> returns int as $$ >> begin >> return 10; >> end; >> $$ language plpgsql; >> >> /* now create a wrapper for the autonomous version */ >> create or replace function >> del( a int, b char, c varchar ) >> returns int as $$ >> declare >> ret int; >> begin >> select retcode >> into ret >> from dblink( 'dbname='||current_database(), >> 'select del_autonomous( ' >> || coalesce( a::varchar, 'null' ) || ', ' >> || coalesce( quote_literal( b ), 'null' ) || ', ' >> || coalesce( quote_literal( c ), 'null' ) || >> ' )' ) >> as f( retcode int ); >> >> return ret; >> end; >> $$ language plpgsql; >> >> >> .) OUT parameters >> >> (no concrete/clear implementation details yet; am in consultation with PG >> community) > > > For tackling OUT parameters we can go with one of the below possibilities: > > 1. Use functions for postgres and use RETURN keyword instead of OUT to > obtain the desired results. This would require changes in application and > every procedure call (with OUT parameters) would have two code paths; one > for Oracle and One for Postgres in a fashion similar to below: > > if Oracle then > Oracle procedure call statement > else if postgres > Postgres function call statement > end if; > > And more changes might also be required to handle/take care of the function > return value. > > > 2. As mentioned above there is only one OUT parameter in all the procedures > and they can easily be converted to functions with return values to get the > results of OUT parameter. We can change those procedures for both Oracle and > Postgres to behave the same way i.e. using RETURN values. This would provide > similar calling code from application for both Oracle and Postgres. This > would/might also require changes in the application but according to my > understanding the changes would be minimal as compared to CASE1 and the > application won't require separate codes for calling Oracle and Postgers > functions. > > > The second approach seems more reasonable and the procedures would be > converted using this approach; this would apply to only the procedures with > OUT parameters and the number of procedures being affected is around 15. > > Regards, > Farrukh > > > > >> >> >> >> -- >> gurjeet[.sin...@enterprisedb.com >> EnterpriseDB http://www.enterprisedb.com >> >> singh.gurj...@{ gmail | hotmail | indiatimes | yahoo }.com >> >> >> _______________________________________________ >> Spacewalk-devel mailing list >> Spacewalk-devel@redhat.com >> https://www.redhat.com/mailman/listinfo/spacewalk-devel >> > >
_______________________________________________ Spacewalk-devel mailing list Spacewalk-devel@redhat.com https://www.redhat.com/mailman/listinfo/spacewalk-devel