Foreign Database Connectivity
I have been thinking about this for a while. Now that we have a
practical methodology for returning full rows from functions, we could
make this sort of thing pretty "easily."
How should it look? How much work is worth putting into it?
My thinking is that there is a module in contrib or something that
enables this.
The foreign DB link module should be able to load external DB drivers,
this way anyone can add a new DB to the system.
We should start with DBF files, ODBC, and of course, PostgreSQL.
Does it need to look like a table or can we get away with it being a
function?
If we make it a function that's easier.
Any thoughts?
mlw <pgsql@mohawksoft.com> writes:
Any thoughts?
See previous discussion of SQL-MED standard. I'd prefer to see us try
to implement a standard than invent something off-the-cuff ...
regards, tom lane
I have been thinking about this for a while. Now that we have a
practical methodology for returning full rows from functions, we could
make this sort of thing pretty "easily."
Does postgres now support returning multiple rows / tuples from a stored
procedure / function?
Tom Lane wrote:
mlw <pgsql@mohawksoft.com> writes:
Any thoughts?
See previous discussion of SQL-MED standard. I'd prefer to see us try
to implement a standard than invent something off-the-cuff ...
Does anyone implement this? I have never seen it before. What about
Oracle's Create database link syntax?
On Tue, 2003-04-15 at 20:04, Rob Butler wrote:
Does postgres now support returning multiple rows / tuples from a stored
procedure / function?
Yes (since PostgreSQL 7.3).
Cheers,
Neil
mlw <pgsql@mohawksoft.com> writes:
Tom Lane wrote:
See previous discussion of SQL-MED standard. I'd prefer to see us try
to implement a standard than invent something off-the-cuff ...
Does anyone implement this?
Couldn't say. It's a relatively new standard. That hasn't stopped us
from implementing SQL99 stuff though, nor in some cases SQL200x stuff
that the ink is still wet on...
What about Oracle's Create database link syntax?
What about it? Does anyone beside Oracle support it? Can we implement
it without running afoul of Oracle patents? Quite honestly, I'm afraid
to base any feature on "this is how Oracle does it", first because it's
foolish to shoot at a target that the competition can move at will, and
second because I know that sooner or later they are going to be looking
for ways to nail us for patent infringement.
regards, tom lane
Tom Lane wrote:
What about Oracle's Create database link syntax?
What about it? Does anyone beside Oracle support it? Can we implement
it without running afoul of Oracle patents? Quite honestly, I'm afraid
to base any feature on "this is how Oracle does it", first because it's
foolish to shoot at a target that the competition can move at will, and
second because I know that sooner or later they are going to be looking
for ways to nail us for patent infringement.
A real concern for sure. OK, but...
Supporting the SQL/MED syntax will take *a lot* of work, where as a
simpler PG-Only feature can be developed as a contrib. I think there is
a *need* for the ability, but not nessisarily a requirement for a
specific implementation.
So, lets assume that the core PG crowd hates what ever it is that would
get built to do this. No worries, its not the first time :) Lets forget
that it is a feature that you do not like, and I am asking for a more
"generic" feature for functions returning sets.
How about this: (a varient)
CREATE [OR REPLACE] FUNCTION name (args)
RETURNS setof (mycol1 integer, mycol2 varchar)
LANGUAGE langname
.....
WITH (attribute, param1='param1', param2='param2',...)
Now, what would be cool, is if there was a way for the RETURNS specifier
to be passed to the function in some easy to use preparsed form. So that
the function could "know" what it was supposed to return and the name of
the field, it is important for the function to know the data type and
its name.
The "WITH" attributes could provide one more attribute, a parameter
which could be passed to the function. his will allow functions to do
virtually anything, for instance:
create function "ODBC_Music" (varchar) returns setof (id integer, title
varchar, artist varchar)
as 'mydll.so', 'ODBC_Music'
LANGUAGE C
WITH(STABLE, param1='NAME:DBUSER;DSN:FREEDB;AUTH:FUBAR', param2='select
* from sometable where title = ''%s''');
Would this implementation take much *any* real work? If PostgreSQL had
this, then external DB access would be trivial to implement. More
importantly, it makes it easier for a DBA to use an ISV's data link
function. Also, the "RETURNS" parameter could/should be he standard
CREATE TABLE syntax.
Import Notes
Resolved by subject fallback
mlw <pgsql@mohawksoft.com> writes:
How about this: (a varient)
CREATE [OR REPLACE] FUNCTION name (args)
RETURNS setof (mycol1 integer, mycol2 varchar)
LANGUAGE langname
.....
WITH (attribute, param1='param1', param2='param2',...)
Now, what would be cool, is if there was a way for the RETURNS specifier
to be passed to the function in some easy to use preparsed form.
Just create a rowtype and declare the function as returning that.
With Joe's recent additions for polymorphic functions, it's even
possible for the function to discover what it's supposed to return
at runtime. (Hey Joe, did we make that work for functions called
from the FROM clause? If not, seems like something to fix up.)
The "WITH" attributes could provide one more attribute, a parameter
which could be passed to the function.
Actually, the way that you probably ought to build it is as a new PL
language type. All the stuff you are thinking of as WITH parameters
would be inside the "function body" in some trivial syntax. I think
this could likely even be built in 7.3, without the polymorphic
functions (PL handlers are already polymorphic ...)
regards, tom lane
Tom Lane wrote:
mlw <pgsql@mohawksoft.com> writes:
Now, what would be cool, is if there was a way for the RETURNS specifier
to be passed to the function in some easy to use preparsed form.Just create a rowtype and declare the function as returning that.
Or for flexibility use "RETURNS setof record"
With Joe's recent additions for polymorphic functions, it's even
possible for the function to discover what it's supposed to return
at runtime. (Hey Joe, did we make that work for functions called
from the FROM clause? If not, seems like something to fix up.)
Yeah -- the best example is the new hash based crosstab function in
contrib/tablefunc:
CREATE OR REPLACE FUNCTION crosstab(text,text)
RETURNS setof record
AS 'MODULE_PATHNAME','crosstab_hash'
LANGUAGE 'C' STABLE STRICT;
create table cth(id serial, rowid text, rowdt timestamp,
attribute text, val text);
<insert data>
SELECT * FROM crosstab
(
'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
'SELECT DISTINCT attribute FROM cth ORDER BY 1'
)
AS (rowid text, rowdt timestamp, temp int4, res text,
startdate timestamp, volts float8);
In this case crosstab_hash() gets its tupdesc from rsinfo->expectedDesc.
It then uses the output of SPI_getvalue and the tupdesc to build the new
tuple via BuildTupleFromCStrings()
The "WITH" attributes could provide one more attribute, a parameter
which could be passed to the function.Actually, the way that you probably ought to build it is as a new PL
language type. All the stuff you are thinking of as WITH parameters
would be inside the "function body" in some trivial syntax. I think
this could likely even be built in 7.3, without the polymorphic
functions (PL handlers are already polymorphic ...)
Sounds like an interesting approach -- actually PL/R uses the
polymorphic abilities pretty extensively too. For example when the R
function returns a "data frame", PL/R uses the runtime return type to
decide what to do with it.
As far as foreign database connectivity goes specifically, someone has
already done a proof of concept "jdbclink" based on dblink (which he
sent to me). If I can find the time before the 7.4 feature freeze, I'm
going to try to merge his code into dblink so that dblink can access any
jdbc data source. Beyond that, I think heading down the SQL-MED road is
the way to go.
Joe
Joe Conway wrote:
Tom Lane wrote:
With Joe's recent additions for polymorphic functions, it's even
possible for the function to discover what it's supposed to return
at runtime. (Hey Joe, did we make that work for functions called
from the FROM clause? If not, seems like something to fix up.)Yeah -- the best example is the new hash based crosstab function in
contrib/tablefunc:
Dooh! I just reread what you wrote. Your referring to the FuncExpr
addition to the FmgrInfo struct. I'll have to check that out and let you
know. I'm getting ready to dive back into that stuff in the next day or so.
Joe
Tom Lane wrote:
With Joe's recent additions for polymorphic functions, it's even
possible for the function to discover what it's supposed to return
at runtime. (Hey Joe, did we make that work for functions called
from the FROM clause? If not, seems like something to fix up.)
I'm just getting back into the polymorphic-functions/array-expression
changes this weekend. To follow up on the question above, I checked and
found that get_fn_expr_rettype() works fine in FROM clause functions.
Of course, as I mentioned earlier, fcinfo->resultinfo->expectedDesc is
also available in FROM clause functions, and is probably more convenient
to use for return type discovery.
However, get_fn_expr_argtype() is your only real option as far as
discovering run time argument types. I'm sure it also works in FROM
clause functions (because I'm actively using it in plr)
Joe