Re: [HACKERS] Domains and function arguments

2003-06-17 Thread Tom Lane
Peter Eisentraut [EMAIL PROTECTED] writes:
 Tom Lane writes:
 Admittedly, we have trouble resolving the type to use when a function is
 overloaded with both a domain and a base type, but that's hardly
 surprising.

 Even if you try to work it out, it's going to be a mess.  During
 resolution, you would have to look inside the data to figure out which
 domain, if any, it might fit into.

No, we'd just use the declared type of the input to determine what to
do, same as we do now.  If you want a domain-specific function to be
applied, you need to have the input be already of that domain, or you
coerce to it.

 If you insist on allowing domains in argument lists, then I think the best
 approach is this:  For purpose of function resolution, types and all
 domains defined over them are equivalent.  That would mean, for example,
 that if you define positive_int as domain over int, then you cannot define
 foofunc(int) and foofunc(positive_int) as the same time.

I think that'd be throwing the baby out with the bathwater.  The above
is, more or less, *exactly* what you want to do in typical scenarios.
foofunc(int) is the general case, foofunc(positive_int) offers some sort
of performance or other advantage for the special case.

We do have some usable functionality in this area today:

regression=# create domain positive_int as int check (value  0);
CREATE DOMAIN
regression=# create function foofunc(int) returns int as 'select 1' language sql;
CREATE FUNCTION
regression=# create function foofunc(positive_int) returns int as 'select 2' language 
sql;
CREATE FUNCTION
regression=# select foofunc(1);
 foofunc
-
   1
(1 row)

regression=# select foofunc(1::positive_int);
 foofunc
-
   2
(1 row)

regression=#

Prohibiting this setup would take away usable if limited functionality,
in return for what?  The fact that foofunc(1::int2) doesn't work
without an explicit cast is annoying, but it's not significantly
different in my mind from the fact that to_hex(1::int2) doesn't work.
We're not going to forbid users from supplying both int4 and int8
versions of a function, so we shouldn't forbid base and domain versions
either.

I think we could make most of the problems you cite go away if, at the
top of func_select_candidate() where we chop input types to base types,
we also discard any candidates that take domain types.  They're
guaranteed not to match at that point, so we aren't losing any cases
that work.  The overhead of doing this is a tad annoying, but maybe we
can combine it with some other catalog lookup.

regards, tom lane

---(end of broadcast)---
TIP 9: the planner will ignore your desire to choose an index scan if your
  joining column's datatypes do not match


Re: [HACKERS] Domains and function arguments

2003-06-17 Thread Josh Berkus
Tom,

If you insist on allowing domains in argument lists, then I think the best
approach is this:  For purpose of function resolution, types and all
domains defined over them are equivalent.  That would mean, for example,
that if you define positive_int as domain over int, then you cannot define
foofunc(int) and foofunc(positive_int) as the same time.

As a heavy PL/pgSQL function user, the above sounds completely reasonable  
workable to me.

-- 
Josh Berkus
Aglio Database Solutions
San Francisco

---(end of broadcast)---
TIP 5: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faqs/FAQ.html


[HACKERS] Domains and function arguments

2003-06-16 Thread Peter Eisentraut
It seems that there are still a few problems with the resolution of
functions that have domains as arguments.

Take these two domains:

create domain testdomain1 as int;
create domain testdomain2 as int;

Take these two functions:

create function foofunc(testdomain1) returns int as 'select 1' language sql;
create function foofunc(testdomain2) returns int as 'select 2' language sql;

Calling foofunc(1) fails with the usual error message.

Take these two functions:

create function foofunc(testdomain1) returns int as 'select 1' language sql;
create function foofunc(int) returns int as 'select 2' language sql;

Calling foofunc(1) calls the second function.  This is wrong, because int
and testdomain2 are equivalent types, so the behavior should be identical
to the above.

Take these two functions:

create function foofunc(testdomain1) returns int as 'select 1' language sql;
create function foofunc(bigint) returns int as 'select 2' language sql;

Calling foofunc(1) fails with the usual error message.  This is wrong,
because testdomain1 is equivalent to int, and had we written foofunc(int),
that's the one that would have been called, in preference to
foofunc(bigint).

The SQL standard does not allow functions to have domains as arguments.
Semantically, they have a point.  Domains are not distinct types from
their base types, just different ranges within those types, and the choice
of function should just depend on the nature of the data, not in which
range it was declared to fall.  I think we should consider following the
standard.

-- 
Peter Eisentraut   [EMAIL PROTECTED]


---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [HACKERS] Domains and function arguments

2003-06-16 Thread Tom Lane
Peter Eisentraut [EMAIL PROTECTED] writes:
 The SQL standard does not allow functions to have domains as arguments.
 Semantically, they have a point.

I don't think they do.  Declaring a domain as the input type seems a
very natural way of asserting that the function only works over a subset
of the base input type.  For example, log() might usefully be declared
to take arguments from a positivereal domain.

Admittedly, we have trouble resolving the type to use when a function is
overloaded with both a domain and a base type, but that's hardly
surprising.

The present algorithm for ambiguous-function resolution is probably
excessively unfriendly to functions with domain inputs: it will match
them *only* when they are an exact match (ie, the input argument is
already declared or coerced to the domain type).  I think that's bowing
quite far enough in the direction of the standard; I'd like to loosen
it someday, but don't have time to think about it more right now.

regards, tom lane

---(end of broadcast)---
TIP 5: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faqs/FAQ.html