proposal for PL packages for 8.3.

From: "Pavel Stehule" <pavel(dot)stehule(at)hotmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: proposal for PL packages for 8.3.
Date: 2006-08-07 09:44:42
Message-ID: BAY20-F217777BA7A338A33A71881F9570@phx.gbl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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/

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Markus Schiltknecht 2006-08-07 09:58:50 Re: standard interfaces for replication providers
Previous Message stark 2006-08-07 09:26:27 Re: "Constraint exclusion" is not general enough