Package support for Postgres
Zembu has decided to release the result of a recent Postgres developement
project to the Postgres project. This project (for which I was the lead
developer) adds Oracle-like package support to Postgres. I'm in the
process of making a version of the patch which is relative to the current
cvs tree. The change is fairly encompasing, weighing in at around
800k of unified diffs, of which about 200k are the real meat. Before I
send it in, though, I thought I'd see what people think of the idea. Oh,
this feature would definitly be a 7.3 feature, 7.2 is too close to the
door for this to go in. :-)
This message is rather long. I've divided it into sections which start
with "**".
** What are Packages
So what are packages? In Oracle, they are a feature which helps developers
make stored procedures and functions. They provide a name space for
functions local to the package, session-specific package variables, and
initialization routines which are run before any other routine in the
package. Also, all parts of a package are loaded and unloaded at once -
you can't have it partially installed.
All of these features make life much easier for stored-procedure
developers. The name space feature means that you can name the routines in
your package whatever you want, and they won't conflict with the names
either in other packages or with functions not in a package. All you need
to do is ensure that no other package has the same name as yours.
** What did I do, and what does a package declaration look like?
What I've done is impliment Oracle packages with a Postgres flair. There
is a new command, CREATE PACKAGE <name> AS which defines a package. For
those of you up on Oracle packages, this command duplicates the Oracle
CREATE PACKAGE BODY command - there is no Postgres equivalent of the
Oracle CREATE PACKAGE command.
Packages are listed in a new system table, pg_package, and are referenced
in other tables by the oid of the row in pg_package.
There are seven different components which can be present in a package,
and so a CREATE PACKAGE command contains seven stanza types. A package can
be made up of functions, types, operators, aggregates, package-global
variables, initialization routines, and functions usable for type
declarations. Four of the stanzas are easy to understand; to create a
function, a type, an aggregate, or an operator, you include a stanza which
is the relevant CREATE command without the CREATE keyword. Thus the
FUNCTION stanza creates a function, the TYPE stanza creates a type,
AGGREGATE => an aggregate, and OPERATOR => an operator.
The initializer routines and package-global variables are done a bit
differently than in Oracle, reflecting Postgres's strength at adding
languages. Postgres supports six procedural languages (plpgsql, pltcl,
pltclu, plperl, plperlu, and plpython) whereas I think Oracle only
supports two (PL/SQL and I herad they added a java PL). The main
difference is that the variables and the initializer routines are language
specific. So you can have different variables for plpgsql than for pltcl.
Likewise for initializers.
Package-global variables are defined as:
DECLARE <variable name> '<variable type>' [, <next name> '<next type>' ]
LANGUAGE 'langname'
The type is delimited by single quotes so that the postgres parser didn't
have to learn the syntax of each procedural language's variable types.
Initializer routines are declared like normal functions, except the
function name and signature (number & type of arguements and return type)
are not given. The name is automatically generated (it is __packinit_
followed by the language name) and the function signature should not be
depended on. It is to take no parameters and return an int4 for now, but
that should probably change whenever PG supports true procedures.
Initializer routines are declared as:
BODY AS 'function body' LANGUAGE 'lanname' [with <with options>]
I'm attaching a sample showing a package initialization routine and global
variable declaration. There's a syntax error in it, which I asked about in
another EMail.
The last component of a package are the functions usable for type
declarations. They are declared as:
BEFORE TYPE FUNCTION <standard package function declaration>
They are useful as the normal functions in a package are declared after
the types are declared, so that they can use a type newly-defined in a
package. Which is fine, except that to define a type, you have to give an
input and an output function. BEFORE TYPE FUNCTIONs are used to define
those functions. Other than exactly when they are created in package
loading, they are just like other functions in the package.
I'm attaching an example which defines the type 'myint4' (using the
internal int4 routines) and proceeds to declare routines using the new
type.
** So how do I use things in a package?
You don't have to do anything special to use a type or an operator defined
in a package - you just use it. Getting technical, operators and types in
packages are in the same name space as are types and operators not in
packages. To follow along with the example I attached above, the 'myint4'
type is usable in the typetest package, in tables, in other packages, and
in "normal" functions.
For functions and aggregates, things are a little more complicated. First
off, there is a package called "standard" which contains all types,
aggregates, operators, and functions which aren't in a specific package.
This includes all of the standard Postgres routines, and anything created
with CREATE FUNCTION, CREATE AGGREGATE, CREATE OPERATOR, and CREATE TYPE.
Secondly, parsing is always done in terms of a specified package context.
If we are parsing an equation in a routine inside of a package, then the
package context is that package. If we are just typing along in psql, then
the package context is "standard".
When you specify a function or aggregate, you have two choices. One is to
specify a package, and a function in that package, like
"nametest.process" to specify the "process" function in the "nametest"
package.
The other choice is to just give the function's name. The first place
Postgres will look is in the package context used for parsing. If it's not
there (and that context wasn't "standard"), then it will look in
"standard". So for example in the type declaration example attached, the
type stanza uses "myint4in" and "myint4out" as the input and output
routines, and finds the ones declared as part of the package.
I've attached a sample showing off namespaces. It has two non-package
routines, and one package named "nametest".
Here's a sample session:
testing=# select standard.process(4);
process
------------------
I am in standard
(1 row)
testing=# select nametest.process(4);
process
---------------------
I am in the package
(1 row)
testing=# select nametest.docheck();
docheck
---------------------
I am in the package
(1 row)
First we see that the standard.process() routine says it is in the
"standard" package, and that the nametest.process() routine says it is in
the package. Then we call the nametest.docheck() routine.
It evaluates "process(changer(4));" in the context of the nametest
package. We find the process() routine in the package, and use it.
The changer routine is there to test how typecasting works. It verifies
that Postgres would typecast the return of changer into a different
integer and call the process() routine in the package rather than call the
process() routine in standard. This behavior matches Oracle's.
The other routines in the package show of some examples of how sql will
parse according to the above rules.
Initialization routines:
There is only one recomended way to use them: call a function written in
the same PL in the package. That will cause the initialization routine to
be run. Assuming there are no errors, the routine you call won't be
executed until after the initialization routine finishes.
Of course the non-recomended way is to manually call __packinit_<langname>
directly. The problem with that is that you are depending on
implimentation details which might change. Like exactly how the name is
generated (which probably won't change) and the calling convention (which
hopefully will if procedures are ever suported).
Package-global variables:
Just use them. Assuming that the procedural language supports global
variables, they just work. Note that as with Oracle, each backend will get
its own set of variables. No effort is made to coordinate values across
backends. But chances are you don't want to do that, and if you did, just
make a table. :-)
** So what is the state of the diffs?
The diffs contain changes to last week's current (I'll cvs update before
sending out) which add package support to the backend, plpgsql, the SPI
interface, initdb, and pg_dump. The changes also include modifying the
system schema to support packages (pg_package which lists packages,
pg_packglobal which list global variables, and adding a package identifier
to pg_aggretage, pg_operator, pg_proc and pg_type).
The big things missing are documentation, and regression tests which
explicitly test packages.
Also, plpgsql is the only PL with package support. Adding package support
doesn't make sense for the 'C' and 'internal' languages, as you can
manually add "global" variables and initialization routines yourself. It
also doesn't make sense for 'sql' as sql doesn't support variables. The
other languages need to gain package support, and I'll appreciate help
from their authors. :-)
So I'd better wrap up here. Monday I'll send the diffs to the patches
list, and also send a message talking about more of the details of the
changes.
What do folks think?
Take care,
Bill
What do folks think?
Take care,
Bill
Hello Bill,
The community have been waiting for packages for a long time. I don't
believe you did it!!!
IMHO most applications do not fully benefit from the power of PostgreSQL
because transactions are performed at application lever
(PHP/asp/Java/Application server). Sometimes, libraries are mapped to
database structure, which is nonsense when a simple view with left joins
can solve a problem.
Most applications should be developed/ported at PostgreSQL level using the
full range of available tools (transactions, triggers, views, foreign keys,
rules and off course PL/pgSQL). This is much easier and powerful. Then, all
you need is to display information using a good object-oriented language
(Java/PHP).
With the help of packages, a lot of developers will probably release GPL
libraries and PostgreSQL will become the #1 database in the world.
At pgAdmin team, we were thinking of developing packages at client level.
This is nonsense when reading your paper. The ability of defining context
levels is a great feature. Question: how do you map package to PostgreSQL
objects (tables, views, triggers)? Is there any possibility of defining
templates? Can this be added to packages in the future with little impact
on PostgreSQL internals?
Now, we can only thank you for bringing Packages to PostgreSQL.
Best regards,
Jean-Michel POURE
pgAdmin Team
Bill Studenmund <wrstuden@netbsd.org> writes:
... operators and types in
packages are in the same name space as are types and operators not in
packages.
For functions and aggregates, things are a little more complicated. First
off, there is a package called "standard" which contains all types,
aggregates, operators, and functions which aren't in a specific package.
This includes all of the standard Postgres routines, and anything created
with CREATE FUNCTION, CREATE AGGREGATE, CREATE OPERATOR, and CREATE TYPE.
Secondly, parsing is always done in terms of a specified package context.
If we are parsing an equation in a routine inside of a package, then the
package context is that package. If we are just typing along in psql, then
the package context is "standard".
When you specify a function or aggregate, you have two choices. One is to
specify a package, and a function in that package, like
"nametest.process" to specify the "process" function in the "nametest"
package.
The other choice is to just give the function's name. The first place
Postgres will look is in the package context used for parsing. If it's not
there (and that context wasn't "standard"), then it will look in
"standard".
Hmm. How does/will all of this interact with SQL-style schemas?
The reason I'm concerned is that if we want to retain the present
convention that the rowtype of a table has the same name as the table,
I think we are going to have to make type names schema-local, just
like table names will be. And if type names are local to schemas
then so must be the functions that operate on those types, and therefore
also operators (which are merely syntactic sugar for functions).
This seems like it will overlap and possibly conflict with the decisions
you've made for packages. It also seems possible that a package *is*
a schema, if schemas are defined that way --- does a package bring
anything more to the table?
I also wonder how the fixed, single-level namespace search path you
describe interacts with the SQL rules for schema search. (I don't
actually know what those rules are offhand; haven't yet read the schema
parts of the spec in any detail...)
Also, both operators and functions normally go through ambiguity
resolution based on the types of their inputs. How does the existence
of a name search path affect this --- are candidates nearer the front
of the search path preferred? Offhand I'm not sure if they should get
any preference or not.
I'd like to see schemas implemented per the spec in 7.3, so we need to
coordinate all this stuff.
regards, tom lane
Bill Studenmund writes:
So what are packages? In Oracle, they are a feature which helps developers
make stored procedures and functions.
I think you have restricted yourself too much to functions and procedures.
A package could/should also be able to contain views, tables, and such.
They provide a name space for functions local to the package,
Namespacing is the task of schemas. I think of packages as a bunch of
objects that can be addressed under a common name (think RPMs).
But it seems like some of this work could be used to implement schema
support.
session-specific package variables,
I think this is assuming a little too much about how a PL might operate.
Some PLs already support this in their own language-specific way, with or
without packages. Thus, I don't think packages should touch this.
Actually, I think you could easily set up session variables in the package
initializer function.
The last component of a package are the functions usable for type
declarations. They are declared as:
BEFORE TYPE FUNCTION <standard package function declaration>They are useful as the normal functions in a package are declared after
the types are declared, so that they can use a type newly-defined in a
package.
I think it would make much more sense to allow the creation of objects in
the CREATE PACKAGE command in any order. PostgreSQL has not so far had a
concept of "functions suitable for type declarations" and we shouldn't add
one.
--
Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter
On Sat, 13 Oct 2001, Tom Lane wrote:
Bill Studenmund <wrstuden@netbsd.org> writes:
For functions and aggregates, things are a little more complicated. First
off, there is a package called "standard" which contains all types,
aggregates, operators, and functions which aren't in a specific package.
This includes all of the standard Postgres routines, and anything created
with CREATE FUNCTION, CREATE AGGREGATE, CREATE OPERATOR, and CREATE TYPE.Secondly, parsing is always done in terms of a specified package context.
If we are parsing an equation in a routine inside of a package, then the
package context is that package. If we are just typing along in psql, then
the package context is "standard".When you specify a function or aggregate, you have two choices. One is to
specify a package, and a function in that package, like
"nametest.process" to specify the "process" function in the "nametest"
package.The other choice is to just give the function's name. The first place
Postgres will look is in the package context used for parsing. If it's not
there (and that context wasn't "standard"), then it will look in
"standard".Hmm. How does/will all of this interact with SQL-style schemas?
Independent as I understand it. Schemas (as I understand Oracle schemas)
operate at a level above the level where packages operate.
The reason I'm concerned is that if we want to retain the present
convention that the rowtype of a table has the same name as the table,
I think we are going to have to make type names schema-local, just
like table names will be. And if type names are local to schemas
then so must be the functions that operate on those types, and therefore
also operators (which are merely syntactic sugar for functions).This seems like it will overlap and possibly conflict with the decisions
you've made for packages. It also seems possible that a package *is*
a schema, if schemas are defined that way --- does a package bring
anything more to the table?
I don't think it conflicts. My understanding of schemas is rather
simplistic and practical. As I understand it, they correspond roughly to
databases in PG. So with schema support, one database can essentially
reach into another one. Package support deals with the functions (and
types and in this case aggregates and operators) that schema support would
find in the other schemas/databases.
I also wonder how the fixed, single-level namespace search path you
describe interacts with the SQL rules for schema search. (I don't
actually know what those rules are offhand; haven't yet read the schema
parts of the spec in any detail...)
Should be independent. The searching only happens when you are not in the
"standard" package, and you give just a function name for a function.
The searching would only happen in the current schems. If
you give a schema name, then I'd expect PG to look in that schema, in
standard, for that function. If you give both a schema and package name,
then PG would look in that package in that schema.
Also, both operators and functions normally go through ambiguity
resolution based on the types of their inputs. How does the existence
of a name search path affect this --- are candidates nearer the front
of the search path preferred? Offhand I'm not sure if they should get
any preference or not.
There is no name spacing for operators in my implimentation as to have one
strikes me as reducing the utility of having types and operators in a
package. For functions (and aggregates), I tried to touch on that in the
latter part of my message; that's what the example with
"process(changer(4))" was about. PG will try to type coerce a function in
the current package before it looks in standard. So yes, candidates nearer
the front are prefered.
I'd like to see schemas implemented per the spec in 7.3, so we need to
coordinate all this stuff.
Sounds good. I don't think it will be that hard, though. :-)
Take care,
Bill
On Sat, 13 Oct 2001, Jean-Michel POURE wrote:
What do folks think?
Take care,
BillHello Bill,
The community have been waiting for packages for a long time. I don't
believe you did it!!!IMHO most applications do not fully benefit from the power of PostgreSQL
because transactions are performed at application lever
(PHP/asp/Java/Application server). Sometimes, libraries are mapped to
database structure, which is nonsense when a simple view with left joins
can solve a problem.Most applications should be developed/ported at PostgreSQL level using the
full range of available tools (transactions, triggers, views, foreign keys,
rules and off course PL/pgSQL). This is much easier and powerful. Then, all
you need is to display information using a good object-oriented language
(Java/PHP).With the help of packages, a lot of developers will probably release GPL
libraries and PostgreSQL will become the #1 database in the world.
Yep. PostgreSQL is within reach of really challenging the commercial
databases. I think the core developers are working on the changes needed
to challenge the commercial db's in terms of speed and performance for big
datastores (WAL, working to prevent OID rollover, etc.). Packages address
a different side of what will be needed to challenge the big boys - better
stored procedure support. :-)
At pgAdmin team, we were thinking of developing packages at client level.
This is nonsense when reading your paper. The ability of defining context
levels is a great feature. Question: how do you map package to PostgreSQL
objects (tables, views, triggers)? Is there any possibility of defining
templates? Can this be added to packages in the future with little impact
on PostgreSQL internals?
Packages don't really map to DB objects (tables, views, triggers) at the
moment. Have you used Oracle much? These packages are a direct translation
of Oracle packages, with a few PostgreSQL extentions thrown in (Oracle
doesn't have PostgreSQL's ability to add aggregates, operators, and system
types AFAIK, so their packages likewise don't, and types in packages AFAIK
are package-specific).
I forget who said it, but operators (and aggregates) are basically just
sugar wrapped around functions; these packages are another form of sugar
wrapped around functions. To start adding views and tables and triggers
makes packages more than just special sugar around functions.
Also, my big concern is that if we start adding tables and views and
triggers to packages, pg_dump becomes a nightmare.
Now, we can only thank you for bringing Packages to PostgreSQL.
You're welcome.
Take care,
Bill
On Sat, 13 Oct 2001, Bill Studenmund wrote:
On Sat, 13 Oct 2001, Tom Lane wrote:
I also wonder how the fixed, single-level namespace search path you
describe interacts with the SQL rules for schema search. (I don't
actually know what those rules are offhand; haven't yet read the schema
parts of the spec in any detail...)Should be independent. The searching only happens when you are not in the
"standard" package, and you give just a function name for a function.
The searching would only happen in the current schems. If
you give a schema name, then I'd expect PG to look in that schema, in
standard, for that function. If you give both a schema and package name,
then PG would look in that package in that schema.
My description of namespaces seems to have caused a fair bit of confusion.
Let me try again.
The ability of the package changes to automatically check standard when
you give an ambiguous function name while in a package context is a
convenience for the procedure author. Nothing more.
It means that when you want to use one of the built in functions
(date_part, abs, floor, sqrt etc.) you don't have to prefix it with
"standard.". You can just say date_part(), abs(), floor(), sqrt(), etc.
The only time you need to prefix a call with "standard." is if you want to
exclude any so-named routines in your own package.
I've attached a copy of a package I wrote as part of testing package
initializers and package global variables. It is an adaptation of the
Random package described in Chapter 8 of _Oracle8 PL/SQL Programming_ by
Scott Urman. Other than adapting it to PostgreSQL, I also tweaked the
RandMax routine to give a flat probability.
Note the use of date_part() in the BODY AS section, and the use of rand()
in randmax(). Both of these uses are the ambiguous sort of function naming
which can trigger the multiple searching. Since they are in plpgsql code,
they get parsed in the context of the random package. So when each of them
gets parsed, parse_func first looks in the random package. For rand(), it
will find the rand() function and use it. But for date_part(), since there
isn't a date_part function in the package, we use the one in standard.
If we didn't have this ability, one of the two calls would need to have
had an explicit package with it. There are two choices (either "standard."
would be needed for date_part(), or "random." for rand()), but I think
both would lead to problems. Either choice makes the syntax heavy, for
little gain. Also, if we scatter the package name throughout the package,
if we ever want to change it, we have more occurences to change.
Does that make more sense?
Take care,
Bill
Attachments:
random.pgsqltext/plain; CHARSET=US-ASCII; NAME=random.pgsqlDownload
On Sat, 13 Oct 2001, Tom Lane wrote:
Bill Studenmund <wrstuden@netbsd.org> writes:
The other choice is to just give the function's name. The first place
Postgres will look is in the package context used for parsing. If it's not
there (and that context wasn't "standard"), then it will look in
"standard".Hmm. How does/will all of this interact with SQL-style schemas?
The reason I'm concerned is that if we want to retain the present
convention that the rowtype of a table has the same name as the table,
I think we are going to have to make type names schema-local, just
like table names will be. And if type names are local to schemas
then so must be the functions that operate on those types, and therefore
also operators (which are merely syntactic sugar for functions).
Ahhh... There's the operators == sugar comment.
I agree with you above; types and functions need to be schema-specific.
This seems like it will overlap and possibly conflict with the decisions
you've made for packages. It also seems possible that a package *is*
a schema, if schemas are defined that way --- does a package bring
anything more to the table?
I'm repeating myself a little. :-)
Packages aren't schemas. What they bring to the table is they facilitate
making stored procedures (functions). You can have twelve different
developers working on twenty different packages, with no fear of name
conflicts. The package names will have to be different, so there can be
functions with the same names in different pacakges.
This ability isn't that important in small development projects, but is
really important for big ones. Think about big db applications, like
Clarify. Any project with multiple procedure authors. Without something
like packages, you'd need to spend a lot of effort coordinating names &
such so that they didn't conflict. With packages, it's rather easy.
Also, I think PostgreSQL can challenge the commercial databases for these
applications. But to do so, changing over to PG will need to be easy.
Having packages there will greatly help.
I'd like to see schemas implemented per the spec in 7.3, so we need to
coordinate all this stuff.
For the most part, I think packages and schemas are orthogonal. I'm taking
a cue from Oracle here. Oracle considers packages to be a schema-specific
object.
Take care,
Bill
On Sat, 13 Oct 2001, Peter Eisentraut wrote:
Bill Studenmund writes:
So what are packages? In Oracle, they are a feature which helps developers
make stored procedures and functions.I think you have restricted yourself too much to functions and procedures.
A package could/should also be able to contain views, tables, and such.
I disagree. Views and tables are the purview of schemas, which as I
mentioned to Tom, strike me as being different from packages. Packages
basically are modules which make life easier for functions (and types and
aggregates and operators).
If we really want to make tables and views and triggers part of packages,
we can. My big concern is that it then makes pg_dump harder. I'll go into
that more below.
They provide a name space for functions local to the package,
Namespacing is the task of schemas. I think of packages as a bunch of
objects that can be addressed under a common name (think RPMs).
Regrettablely Oracle beat you to it with what "packages" are in terms of
Oracle, and I suspect also in the minds of many DBAs.
I also think that you and Tom have something different in mind about the
namespacing in packages. It is purely a convenience for the package
developer; whenever you want to use a function built into the database,
you _don't_ have to type "standard." everywhere. Think what a PITA it
would be to have to say "standard.abs(" instead of "abs(" in your
functions! I'm sorry if my explanation went abstract quickly & making that
unclear.
But it seems like some of this work could be used to implement schema
support.
I think the big boost this will have to schema support is that it shows
how to make a far-reaching change to PostgreSQL. :-) It's an internal
schema change and more, just as schema support will be.
session-specific package variables,
I think this is assuming a little too much about how a PL might operate.
Some PLs already support this in their own language-specific way, with or
without packages. Thus, I don't think packages should touch this.
Actually, I think you could easily set up session variables in the package
initializer function.
I agree that some PLs might do things their own way and so package
variables won't be as useful. If these variables are not appropriate to a
PL, it can ignore them.
PL/pgSQL is a counter-example, though, showing that something needs to be
done. It is not set up to support global variables; each code block
generates its own namespace, and removes it on the way out. Thus I can
not see a clean way to add package global variables to say the
initialization routine - this routine's exit code would need to not
destroy the context. That strikes me as a mess.
The last component of a package are the functions usable for type
declarations. They are declared as:
BEFORE TYPE FUNCTION <standard package function declaration>They are useful as the normal functions in a package are declared after
the types are declared, so that they can use a type newly-defined in a
package.I think it would make much more sense to allow the creation of objects in
the CREATE PACKAGE command in any order. PostgreSQL has not so far had a
concept of "functions suitable for type declarations" and we shouldn't add
one.
I think you misread me slightly. BEFORE TYPE FUNCTION functions are
"usable" for type declarations, not "suitable" for them. Also, I didn't
say one key clause, "in this package". The main difference is when in the
creation of the package the functions are created; they get created before
the types, rather than after.
This concept is new to PostgreSQL because PostgreSQL has never before
chained creations together like this.
Thinking about it though it would be feasable to scan the list of types in
the package, and see if there are references to functions declared in that
package, and if so to create them before the types get declared. That
would remove the need for BEFORE TYPE FUNCTION and also make pg_dump a
little simpler.
Take care,
Bill
On Mon, 15 Oct 2001, Tom Lane wrote:
Bill Studenmund <wrstuden@netbsd.org> writes:
For the most part, I think packages and schemas are orthogonal. I'm taking
a cue from Oracle here. Oracle considers packages to be a schema-specific
object.Nonetheless, it's not clear to me that we need two independent concepts.
Given a name search path that can go through multiple schemas, it seems
to me that you could get all the benefits of a package from a schema.I'm not necessarily averse to accepting Oracle's syntax for declaring
packages --- if we can make it easier for Oracle users to port to Postgres,
that's great. But I'm uncomfortable with the notion of implementing two
separate mechanisms that seem to do the exact same thing, ie, control
name visibility.
I'm at a loss as to what to say. I think that what packages do and what
schemas do are different - they are different kinds of namespaces. That's
why they should have different mechanisms. Packages are for making it
easier to write stored procedures for large programming projects or for
code reuse. Schemas, well, I need to learn more. But they strike me more
as a tool to partition entire chunks of a database.
Also, packages have a whole concept of initialization routines and global
variables, which strike me as having no place alongside tables and views.
Take care,
Bill
Import Notes
Reply to msg id not found: 6510.1003179731@sss.pgh.pa.us | Resolved by subject fallback
On Sun, 14 Oct 2001, Peter Eisentraut wrote:
I have been pondering a little about something I called "package",
completely independent of anything previously implemented. What I would
like to get out of a package is the same thing I get out of package
systems on operating systems, namely that I can remove all the things that
belong to the package with one command. Typical packages on PostgreSQL
could be the PgAccess admin tables or the ODBC catalog extensions.One might think that this could also be done with schemas. I'm thinking
using schemas for this would be analogous to installing one package per
directory. Now since we don't have to deal with command search paths or
file system mount points there might be nothing wrong with that.Packages typically also have post-install/uninstall code, as does this
proposed implementation, so that would have to be fit in somewhere.This is basically where my thinking has stopped... ;-)
Now I'm also confused as to what this package system really represents:
Is it a namespace mechanisms -- but Oracle does have schemas; or is it a
package manager like I had in mind -- for that it does too many things
that don't belong there; or is it a mechanism to set up global variables
-- that already exists and doesn't need "packages".
It is an implimentation of Oracle Packages for PostgreSQL, taking
advantage of some of PostgreSQL's abilities (the aggregates & operators in
a package bit is new). It is a tool to help developers create large
projects and/or reuse code.
It is not schema support; schema support operates on a level above package
support. It is also not the package support you had in mind. That support
is different. What you describe above is packaging which primarily helps
the admin, while this packaging primarily helps the procedure developer.
That difference in emphasis is why this package support does things an
administrator-focused package system wouldn't.
Also, please note that while many of PostgreSQL's procedure languages
might not need global variable support, PL/pgSQL does.
Take care,
Bill
Import Notes
Reply to msg id not found: Pine.LNX.4.30.0110141401480.849-100000@peter.localdomain | Resolved by subject fallback
On Mon, 15 Oct 2001, Tom Lane wrote:
Bill Studenmund <wrstuden@netbsd.org> writes:
For the most part, I think packages and schemas are orthogonal. I'm taking
a cue from Oracle here. Oracle considers packages to be a schema-specific
object.Nonetheless, it's not clear to me that we need two independent concepts.
Given a name search path that can go through multiple schemas, it seems
to me that you could get all the benefits of a package from a schema.
About the best response to this I can come up with is that in its present
implimentation, types and operators are not scoped as package-specific. If
you declare a type in a package, that type is usable anywhere; you don't
have to say package.type. If we did packages via schemas, as I understand
it, you would (and should).
We both agree that types and the functions that operate on them should be
schema-specific. Thus operators should be schema-specific. If we did
packages via schemas, I don't see how we would get at operators in
packages. If you create a new integer type, would you really want to have
to type "3 packname.< table.attr" to do a comparison?
So I guess that's the reason; this package implimentation creates types
and operators in the same namespace as built-in types and operators. As I
understand schemas, user types (and thus operators) should exist in a
schema-specific space.
I can see reasons for both, thus I think there is a place for two
independent concepts.
Take care,
Bill
Import Notes
Reply to msg id not found: 6510.1003179731@sss.pgh.pa.us | Resolved by subject fallback
Tom Lane writes:
This seems like it will overlap and possibly conflict with the decisions
you've made for packages. It also seems possible that a package *is*
a schema, if schemas are defined that way --- does a package bring
anything more to the table?
I have been pondering a little about something I called "package",
completely independent of anything previously implemented. What I would
like to get out of a package is the same thing I get out of package
systems on operating systems, namely that I can remove all the things that
belong to the package with one command. Typical packages on PostgreSQL
could be the PgAccess admin tables or the ODBC catalog extensions.
One might think that this could also be done with schemas. I'm thinking
using schemas for this would be analogous to installing one package per
directory. Now since we don't have to deal with command search paths or
file system mount points there might be nothing wrong with that.
Packages typically also have post-install/uninstall code, as does this
proposed implementation, so that would have to be fit in somewhere.
This is basically where my thinking has stopped... ;-)
Now I'm also confused as to what this package system really represents:
Is it a namespace mechanisms -- but Oracle does have schemas; or is it a
package manager like I had in mind -- for that it does too many things
that don't belong there; or is it a mechanism to set up global variables
-- that already exists and doesn't need "packages".
--
Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter
On Tue, 16 Oct 2001, Peter Eisentraut wrote:
Bill Studenmund writes:
I disagree. Views and tables are the purview of schemas, which as I
mentioned to Tom, strike me as being different from packages.Well, obviously schemas are a namespacing mechanism for tables and views.
And apparently the "packages" you propose are (among other things) a
namespacing mechanism for functions. But the fact is that schemas already
provide a namespacing mechanism for functions. (That's what SQL says and
that's how it's going to happen.) Now perhaps you want to have a
namespacing mechanism *below* schemas. But then I think this could be
done with nested schemas, since the sub-schemas would really be the same
concept as a top-level schema. That would be a much more general
mechanism.
Yes, I want a namespace below schemas.
The difference between packages and schemas is that schemas encapsulate
everything. As Tom pointed out, that includes types (and I'd assume
operators too). Packages do not encapsulate types and operators. That's
what makes them different from a sub-schema (assuming a sub-schema is a
schema within a schema).
Obviously there is a large number of ideas that "make life easier". But
I'm still missing a clear statement what exactly the design idea behind
these packages is. So far I understood namespace and global variables for
PL/pgSQL. For the namespace thing we've already got a different design.
For global variables, see below.
See above.
I agree that some PLs might do things their own way and so package
variables won't be as useful. If these variables are not appropriate to a
PL, it can ignore them.PL/pgSQL is a counter-example, though, showing that something needs to be
done.Then PL/pgSQL should be fixed. But that doesn't need a such a large
Why is PL/pgSQL broken?
It has a very clean design element; you enter a code block, you get a new
namespace. You can declare variables in that namespace if you want. When
you use a variable name, PL/pgSQL looks in the current namespace, then the
parent, and so on. You exit a code block, the namespace goes away. That's
how C works, for instance.
concept as "packages". It could be as easy as
DECLARE GLOBAL
...
BEGIN
...
ENDIt is not set up to support global variables; each code block
generates its own namespace, and removes it on the way out. Thus I can
not see a clean way to add package global variables to say the
initialization routine - this routine's exit code would need to not
destroy the context. That strikes me as a mess.The language handler should have no problem creating persistent storage --
I don't see that as a problem. If the language is misdesigned that it
cannot be done (which I doubt, but consider the theoretical case) then the
language should be replaced by something better, but please keep in mind
that it's a PL/pgSQL problem only. Maybe if you're from an Oracle
background this separation is not quite as natural.
The problem is not creating persistent storage; the issue is that the
langyage was designed to not use it. What you're proposing could be done,
but would effectivly be shoving the change in with a hammer. Also, any
other PLs which are based on languages with strict namespaces will have
the same problem.
Look at C for instance. What you're describing is the equivalent to
letting a function or procedure in C declare global variables. That's not
now the language works, and no one seems to mind. :-)
Right, that's why I suggested allowing the CREATE statements in any order
so you could order them yourself to have the function before the types or
whatever you want.
My concern with that is that then we have to make sure to dump it in the
same order you entered it. Right now, in general, pg_dump dumps objects in
stages; all of the languages are dumped, then all of the types, then the
functions, and so on. Functions needed for types and languages get dumped
right before the type or language which needs it.
If we go with strict package order mattering, then pg_dump needs to be
able to recreate that order. That means that it has to look in pg_proc,
pg_operator, pg_type, and pg_aggreagate, sort things (in the package being
dumped) by oid, and dump things in order of increasing oid. Nothing else
in pg_dump works like that. I'd rather not start.
I have however come up with another way to make BEFORE TYPE FUNCTION go
away. I'll just scan the types in a package (I doubt there will be many),
get a set of candidate names, and scan the functions in the package for
them. If they are found, they get added before the types do. So then the
decision as to when a function should get added is implicit, rather than
explicit.
I'll see about adding this before I send in the patch (it is the only
thing left).
Take care,
Bill
Import Notes
Reply to msg id not found: Pine.LNX.4.30.0110162044040.627-100000@peter.localdomain | Resolved by subject fallback
Bill Studenmund <wrstuden@netbsd.org> writes:
For the most part, I think packages and schemas are orthogonal. I'm taking
a cue from Oracle here. Oracle considers packages to be a schema-specific
object.
Nonetheless, it's not clear to me that we need two independent concepts.
Given a name search path that can go through multiple schemas, it seems
to me that you could get all the benefits of a package from a schema.
I'm not necessarily averse to accepting Oracle's syntax for declaring
packages --- if we can make it easier for Oracle users to port to Postgres,
that's great. But I'm uncomfortable with the notion of implementing two
separate mechanisms that seem to do the exact same thing, ie, control
name visibility.
regards, tom lane
On Sat, 13 Oct 2001, Peter Eisentraut wrote:
Bill Studenmund writes:
session-specific package variables,
I think this is assuming a little too much about how a PL might operate.
Some PLs already support this in their own language-specific way, with or
without packages. Thus, I don't think packages should touch this.
Actually, I think you could easily set up session variables in the package
initializer function.
Could you please give me an example of how to do this, say for plperl or
plpython? Just showing how two functions made with CREATE FUNCTION can use
global variables will be fine. This example will help me understand how
they work.
Take care,
Bill
On Wed, 17 Oct 2001, Peter Eisentraut wrote:
Bill Studenmund writes:
Yes, I want a namespace below schemas.
The difference between packages and schemas is that schemas encapsulate
everything. As Tom pointed out, that includes types (and I'd assume
operators too). Packages do not encapsulate types and operators.Of course nobody is forcing you to put types into subschemas. But the
user would have the freedom to spread things around as he sees fit.
???
Then PL/pgSQL should be fixed. But that doesn't need a such a large
Why is PL/pgSQL broken?
Maybe read "fixed" as "enhanced".
The problem is not creating persistent storage; the issue is that the
langyage was designed to not use it. What you're proposing could be done,
but would effectivly be shoving the change in with a hammer. Also, any
other PLs which are based on languages with strict namespaces will have
the same problem.Other PLs have shown that storing global data in a language-typical way
*is* possible. I read your argumentation as "PL/pgSQL is not designed to
have global variables, so I'm going to implement 'packages' as a way to
make some anyway". Either PL/pgSQL is not designed for it, then there
should not be any -- at all. Or it can handle them after all, but then
it's the business of the language handler to deal with it.
Do you really think that my employer paid me for three months to come up
with an 800k diff _just_ to add global variables to PL/pgSQL? While part
of it, global variables are only one part of the work. I would actually
say it is a minor one.
Honestly, I do not understand why "global variables" have been such a sore
point for you. PLs for which they don't make sense like this don't have to
do it, and Oracle, on whom our Pl/pgSQL was based, thinks that they make
perfect sense for the language we copied.
Also, remember that this is an implimentation of Oracle packages for
Postgres. One of our goals was to make it so that you can mechanically
transform an Oracle package into a Postgres one, and vis versa. This
implimentation does a good job of that. To make the change you suggest
would not.
My concern with that is that then we have to make sure to dump it in the
same order you entered it.pg_dump can do dependency ordering if you ask it nicely. ;-) When we
implement schemas we'll have to make sure it works anyway. Thinking about
pg_dump when designing backend features is usually not worthwhile.
The thing is what you're talking about is more than just dependency
ordering (which I taught pg_dump to do for packages). "doing things in the
order you list" to me means that things get dumped in the exact same
order. Say you added some functions and then some operators and then some
functions. If order matters, then the operators should get generated in
the dump before the functions, even though there's no dependency-reason to
do so.
Maybe I'm taking that a bit more literal than you mean, but how it comes
across to me is unnecessarily difficult. We cah achieve the same thing
other ways.
I did however take your point that BEFORE TYPE FUNCTION should go away;
the patch I sent in does not have it. In the patch, stanzas in the CREATE
PACKAGE command are gathered, and done in sequence according to kind.
First the global variables are defined, then the initialization routines,
then functions which are needed for types in the package, then types, then
functions (other than the ones already done), aggregates, and operators.
Take care,
Bill
Import Notes
Reply to msg id not found: Pine.LNX.4.30.0110172033570.628-100000@peter.localdomain | Resolved by subject fallback
Bill Studenmund writes:
I disagree. Views and tables are the purview of schemas, which as I
mentioned to Tom, strike me as being different from packages.
Well, obviously schemas are a namespacing mechanism for tables and views.
And apparently the "packages" you propose are (among other things) a
namespacing mechanism for functions. But the fact is that schemas already
provide a namespacing mechanism for functions. (That's what SQL says and
that's how it's going to happen.) Now perhaps you want to have a
namespacing mechanism *below* schemas. But then I think this could be
done with nested schemas, since the sub-schemas would really be the same
concept as a top-level schema. That would be a much more general
mechanism.
Packages basically are modules which make life easier for functions
(and types and aggregates and operators).
Obviously there is a large number of ideas that "make life easier". But
I'm still missing a clear statement what exactly the design idea behind
these packages is. So far I understood namespace and global variables for
PL/pgSQL. For the namespace thing we've already got a different design.
For global variables, see below.
If we really want to make tables and views and triggers part of packages,
we can. My big concern is that it then makes pg_dump harder. I'll go into
that more below.
That has never stopped us from doing anything. ;-)
Regrettablely Oracle beat you to it with what "packages" are in terms of
Oracle, and I suspect also in the minds of many DBAs.
Oracle appears to have beaten us to define the meaning of quite a few
things, but that doesn't mean we have to accept them. We don't
re-implement Oracle here. And exactly because all Oracle has is
procedures and PL/SQL, whereas PostgreSQL has operators, types, and such,
and user-defined procedural languages, designs may need to be changed or
thrown out. It wouldn't be the first time.
I agree that some PLs might do things their own way and so package
variables won't be as useful. If these variables are not appropriate to a
PL, it can ignore them.PL/pgSQL is a counter-example, though, showing that something needs to be
done.
Then PL/pgSQL should be fixed. But that doesn't need a such a large
concept as "packages". It could be as easy as
DECLARE GLOBAL
...
BEGIN
...
END
It is not set up to support global variables; each code block
generates its own namespace, and removes it on the way out. Thus I can
not see a clean way to add package global variables to say the
initialization routine - this routine's exit code would need to not
destroy the context. That strikes me as a mess.
The language handler should have no problem creating persistent storage --
I don't see that as a problem. If the language is misdesigned that it
cannot be done (which I doubt, but consider the theoretical case) then the
language should be replaced by something better, but please keep in mind
that it's a PL/pgSQL problem only. Maybe if you're from an Oracle
background this separation is not quite as natural.
I think you misread me slightly. BEFORE TYPE FUNCTION functions are
"usable" for type declarations, not "suitable" for them. Also, I didn't
say one key clause, "in this package". The main difference is when in the
creation of the package the functions are created; they get created before
the types, rather than after.
Right, that's why I suggested allowing the CREATE statements in any order
so you could order them yourself to have the function before the types or
whatever you want.
This concept is new to PostgreSQL because PostgreSQL has never before
chained creations together like this.
Externally perhaps not, but internally these things happen all the time.
--
Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter
On Sun, 14 Oct 2001, Bill Studenmund wrote:
On Mon, 15 Oct 2001, Tom Lane wrote:
Bill Studenmund <wrstuden@netbsd.org> writes:
For the most part, I think packages and schemas are orthogonal. I'm taking
a cue from Oracle here. Oracle considers packages to be a schema-specific
object.Nonetheless, it's not clear to me that we need two independent concepts.
Given a name search path that can go through multiple schemas, it seems
to me that you could get all the benefits of a package from a schema.
I've been thinking about this. I've changed my mind. Well, I've come to
realize that you can have multiple schemas in one db, so that multiple
schema support != one db reaching into another.
I still think that schemas and packages are different, but I now think
they are interrelated. And that it shouldn't be too hard to leverage the
package work into schema support. Still a lot of work, but the package
work has shown how to go from one to two in a number of ways. :-)
First off, do you (Tom) have a spec for schema support? I think that would
definitly help things.
Second, can you help me with gram.y? I'm trying to get gram.y to deal with
figuring out if you've typed in packagename.function name, rather than
relying on the lexer to notice you've typed ${identifier}\.${identifier}
where the first identifier is a package name & send a terminal saying so.
Twelve r/r conflicts. They involve a conflict between ColId and something
else, and focus on not knowing what reduction to take when seeing a '[',
',', or ')'. Thoughts?
Take care,
Bill
On Thu, 18 Oct 2001, Peter Eisentraut wrote:
Bill Studenmund writes:
Could you please give me an example of how to do this, say for plperl or
plpython? Just showing how two functions made with CREATE FUNCTION can use
global variables will be fine. This example will help me understand how
they work.For PL/Tcl you use regular Tcl global variables:
create function produce(text) returns text as '
global foo; set foo $1;
' language pltcl;create function consume() returns text as '
global foo; return $foo;
' language pltcl;There is also a mechanism for one procedure to save private data across
calls.For PL/Python you use a global dictionary:
create function produce(text) returns text as '
GD["key"] = args[0]
' language plpython;create function consume() returns text as '
return GD["key"]
' language plpython;There is also a dictionary for private data.
Private to what?
For PL/Perl I'm not sure if something has been implemented. In C you can
use shared memory, and for PL/sh you would use temp files of course. ;-)
Thank you. I can now experiment with them to see how they do.
I've never thought of adding package variables for C routines; there are
other options open. :-)
Oh, by shared memory, do you mean SYSV Shared Memory (like how the
backends talk) or just memory shared between routines? I ask as part of
the idea with these variables is that they are backend-specific. So C
routines actually should NOT used SYSV Shared Mem. :-)
Take care,
Bill
Import Notes
Reply to msg id not found: Pine.LNX.4.30.0110172329010.628-100000@peter.localdomain | Resolved by subject fallback