proposal for PL packages for 8.3.
От | Pavel Stehule |
---|---|
Тема | proposal for PL packages for 8.3. |
Дата | |
Msg-id | BAY20-F217777BA7A338A33A71881F9570@phx.gbl обсуждение исходный текст |
Ответы |
Re: proposal for PL packages for 8.3.
|
Список | pgsql-hackers |
Hello Package contains package's variables, shared protected functions and initialisation part, which is executed when any public function attached to package is called. Every package has defined only one language. The reason for this is binary compatibility of package's variables. Private functions aren't SQL functions and it isn't possible to call them via SPI. Because PL/pgSQL can't call functions via different interface than SPI, PL/pgSQL won't support private functions. Package owner can attach any SQL funtions to package, even those written in different language, but only functions in same language as package can access package variables and protect functions. Package is similar to schema. Public package function can access package variables or private functions only if it has same language as package. Every function can be attached to just one package. Only owner can modify package (ALTER OR ATTACH functions). Samples: CREATE OR REPLACE PACKAGE foo_package AS $$ DECLARE my_var integer; BEGIN my_var := 0; END; $$ LANGUAGE plpgsql IMMUTABLE; CREATE OR REPLACE FUNCTION foo_package.counter() RETURNS integer AS $$ BEGIN my_var := my_var + 1; RETURN foo_package.my_var; -- explicit namespace END; $$ LANGUAGE plpgsql IMMUTABLE; SELECT foo_package.counter(); This proposal for package has minimal impact on current implementation of PL languages. CREATE OR REPLACE PACKAGE xml_parser AS $$ USE XML::LibXML; my $parser = XML::LibXML->new; my $schema_file = '/home/postgres/comm.xsd'; my $schema = XML::LibXML::Schema->new(location=> $schema_file); sub get_data {my ($root, $tag, $optional) = @_;my $aux = $root->getElementsByTag($tag);if (@aux eq 0){ elog(ERROR, "Missing value")if ! $optional; return undef;}return @aux[0]->getFirstChild->getData; } $$ LANGUAGE plperlu; CREATE OR REPLACE FUNCTION xml_parser.parse_document ( IN body varchar, OUT name varchar, OUT document_type varchar) AS $$my $body = $_[0]; my $doc = $parser->parse_string($body);$schema->validate($doc);$root = $doc->getDocumentElement();return { name => $root->nodeName; document_type => get_data($root, 'type') }; $$ LANGUAGE plperlu; - using different language, can access only public functions CREATE OR REPLACE FUNCTION xml_parser.validate_all_doc( OUT _name varchar, OUT _state boolean) RETURNS SETOF RECORD AS $$ DECLARE _body varchar; BEGIN FOR _body, _name IN SELECT body, path FROM xml_repository LOOP BEGIN -- use implicit search_path containing package_name _state := true; PERFORM parse_document(_r.body); EXCEPTION WHEN OTHERS THEN _state := false; END; RETURN NEXT; END LOOP; RETURN; END; $$ LANGUAGE plpgsql VOLATILE; SELECT xml_parser.validate_all_doc(); This system is simple and minimalistic and doesn't copy package system from ADA or Oracle which are more complicated and don't allow multiple PL. Any comments are welcome Regards Pavel Stehule p.s. I'll have free time on sept. and can work on it. _________________________________________________________________ Emotikony a pozadi programu MSN Messenger ozivi vasi konverzaci. http://messenger.msn.cz/
В списке pgsql-hackers по дате отправления:
Следующее
От: Markus SchiltknechtДата:
Сообщение: Re: standard interfaces for replication providers