Thread: Function call

Function call

From
Dennis Bjorklund
Date:
I've been looking in the sql200x draft and there are no function calls 
with named arguments.

Thinking more about it, I'm not sure if it really is an important addition
at all. I've got a number of requests for the feature. so there are people 
that want it, that much I know.

I don't think it's very hard to add. I've been playing a little with it,
making myself familiar with the code. Before making an implementation I
just want to make sure that we really want an implementation. It's a neat 
feture, but it's not that very important so I wanted to bring it up.

If one combine it with default values on parameters, then it's more useful
since you easier can leave out arguments when you use the "ident => expr"
syntax. Default values is also not in the standard.

-- 
/Dennis Björklund



Re: Function call

From
Peter Eisentraut
Date:
Dennis Bjorklund wrote:
> Thinking more about it, I'm not sure if it really is an important
> addition at all. I've got a number of requests for the feature. so
> there are people that want it, that much I know.

I like it very much, and I think mostly everyone else does, too.  It's 
just a question of what syntax to use.  Personally, I would be OK with 
"=>".  The SQL standard already attaches a special meaning to "->" 
(object dereference, like in C), so I'd just avoid all "arrows" as 
operator names.



Re: Function call

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
> Dennis Bjorklund wrote:
>> Thinking more about it, I'm not sure if it really is an important
>> addition at all. I've got a number of requests for the feature. so
>> there are people that want it, that much I know.

> I like it very much, and I think mostly everyone else does, too.  It's 
> just a question of what syntax to use.

There are some pretty severe implementation problems that I haven't seen
mentioned yet.  In particular, how will you avoid individually trawling
through every function with a matching name to try to match up the
arguments?  The index on proargtypes won't help you if you don't know
what order the arguments are actually in.  And I think the heuristics in
func_select_candidate() that involve comparing matches at "the same
argument position" will break down completely.

(Adding default values would make overloaded functions an order of
magnitude slower yet, not to mention outright ambiguous.)
        regards, tom lane


Re: Function call

From
Dennis Bjorklund
Date:
On Tue, 27 Jan 2004, Tom Lane wrote:

> In particular, how will you avoid individually trawling through every
> function with a matching name to try to match up the arguments?

I don't think you can avoid that. But it's just done once to find the oid
of the real function, so if it's used multiple times in the same query
it's not that bad.

In most cases you don't have that many functions with the same name 
anyway.

I've looked at the current code that finds the correct function and it 
looked doable. But, I wont know until I make the implementation. And don't 
hold your breath, I can't work all the time on this, so a couple of days 
work might take a couple of weeks. I have some code already, but it's 
not nearly done.

> func_select_candidate() that involve comparing matches at "the same
> argument position" will break down completely.

I was planning to reorder the arguments before the matching according to
the function prototype so I can reuse the old select_candidate (more or
less, the reordering needs to be done for each matching). But if it's not
that simple I will just have to solve it in some more difficult way. In
any case, the currect semantics will stay the same.

> (Adding default values would make overloaded functions an order of
> magnitude slower yet, not to mention outright ambiguous.)

The ambigious part i've complained about to the people that have asked me
for the feature. Now I've come to the conclusion that it doesn't really
matter if it's ambigious. If I can't find one function that match then
I'll just throw an error. There are still a lot of cases where it is
useful and where there are no amiguities.

About the speed, how many functions do you have with the same name. I 
don't think I've ever seen more then 10 or something. It should not be 
that slow to iterate over that a couple of times (I hope). It will never 
be as fast as a direct call, with the correct types of course. Of course I 
still like it to be fast, but it can never be as fast.

-- 
/Dennis Björklund



Re: Function call

From
Dennis Bjorklund
Date:
On Tue, 27 Jan 2004, Peter Eisentraut wrote:

> just a question of what syntax to use.  Personally, I would be OK with 
> "=>".

That's also what I'm leaning towards now. As Greg suggested, just making
=> a special case as a function parameter. And if one want's to call a
function with an expression containing a => one have to write foo((x=>23))
and not foo(x=>23). That's the current plan I have, I think it's
implementable in a not so ugly way.

If that works out the symbol is not stolen, I would just borrow it a
little when it's the top level of an expression in a function call 
position.

-- 
/Dennis Björklund



Re: Function call

From
Tom Lane
Date:
Dennis Bjorklund <db@zigo.dhs.org> writes:
> On Tue, 27 Jan 2004, Tom Lane wrote:
>> func_select_candidate() that involve comparing matches at "the same
>> argument position" will break down completely.

> I was planning to reorder the arguments before the matching according to
> the function prototype so I can reuse the old select_candidate (more or
> less, the reordering needs to be done for each matching).

You're not thinking this through.  The reordering might be different for
each candidate.  func_select_candidate depends on having some notion of
the "same argument position", but what does that mean in such a case?

There are also some difficult questions raised by schemas and search
paths.  s1.f1(text, text) masks s2.f1(text, text) if s1 appears before
s2 in your search path.  But does s1.f1(foo text, bar text) mask
s2.f1(baz text, xyzzy text)?  Does your answer change depending on
whether the actual call has parameter names or not?  For that matter,
should f1(foo text, bar text) and f1(baz text, xyzzy text) be considered
to be different function signatures that ought to be permitted to
coexist in a single schema?  If actual parameter names are going to
affect resolution of search-path ambiguity, it's hard to argue that the
parameter names aren't part of the signature.

What might be the best compromise is to treat parameter names as
documentation *only*, that is, we insist that the parameters have to
appear in the declared order in any case.  All we do with the names in a
call (if supplied) is check that they match the function declaration
after we have resolved which function is meant using the existing
methods.

>> (Adding default values would make overloaded functions an order of
>> magnitude slower yet, not to mention outright ambiguous.)

> The ambigious part i've complained about to the people that have asked me
> for the feature. Now I've come to the conclusion that it doesn't really
> matter if it's ambigious.

Yes it does.

> About the speed, how many functions do you have with the same name.

Try "select proname, count(*) from pg_proc group by 1 order by 2 desc;"
Note that the ones at the top are pretty popular in usage, not only in
having lots of variants.  I don't think it's acceptable to take major
speed hits in parsing them, especially not if the hit occurs whether
one uses the named-parameters feature or not ...
        regards, tom lane


Re: Function call

From
Dennis Bjorklund
Date:
On Tue, 27 Jan 2004, Tom Lane wrote:

> speed hits in parsing them, especially not if the hit occurs whether
> one uses the named-parameters feature or not ...

I'll read the rest of the mail more careful tomorrow moring, I just want
to point out directly that for calls that doesn't use named arguments you
get the exact same speed as before. Except for an extra if() to check if
there are named arguments. I don't understand why you think that this will
affect the current behaviour.

That is more or less the only thing I feel sure about, that it should not
hurt anything that we have today.

-- 
/Dennis Björklund



Re: Function call

From
Tom Lane
Date:
Dennis Bjorklund <db@zigo.dhs.org> writes:
> I'll read the rest of the mail more careful tomorrow moring, I just want
> to point out directly that for calls that doesn't use named arguments you
> get the exact same speed as before. Except for an extra if() to check if
> there are named arguments. I don't understand why you think that this will
> affect the current behaviour.

It looked to me like you were talking about a major redesign of
func_select_candidate and friends.  I'll be interested to see how you do
it without that.
        regards, tom lane


Re: Function call

From
Dennis Bjorklund
Date:
On Tue, 27 Jan 2004, Tom Lane wrote:

> each candidate.  func_select_candidate depends on having some notion of
> the "same argument position", but what does that mean in such a case?

While it is true that I don't know everything about the current code I 
still claim that it can not be such a big problem as you try to paint 
a picture of here. And even more importantly, even if it is it should not 
affect the current behaviour, more about that later.

If you have function:
  f(x int, y text)  f(y float, x text);

and you make a call
   f(2,'foo');

then for each candidate above there is some matching going on based on the 
order of the arguments. I just assume that this works as it should today, 
even if I don't know the details. Not everyone have worked with PG before 
and knows everything directly.

Now, lets assume there is a call
    f (y => 2, x => 'foo')

then for each candidate the order is fixed again. I hoped to treat it 
differently for each candidate, so the possible calls are
   f('foo',2)   f(2, 'foo')

and these orders are the same every time we look at a candidate.

Now, the above is just my plan before coding and before understanding 
everything. It might work and it might not. So far I've got no reason to 
thing that it wont work,

Let's assume that I can't make something like the above to work as fast
as today. For functions calls without named arguments then the current
fast function can still be used. Only for the new kind of calls do you
need to do something more fancy. That would make named calls be "a lot"
slower (relatively speaking) then calls without named and a fixed order of
the arguments. The problem here is not speed but code duplication.

> There are also some difficult questions raised by schemas and search
> paths.  s1.f1(text, text) masks s2.f1(text, text) if s1 appears before
> s2 in your search path.

> But does s1.f1(foo text, bar text) mask s2.f1(baz text, xyzzy text)?  
> Does your answer change depending on whether the actual call has
> parameter names or not?

That is an open question, one can go either way. I think both will work 
and both will be understandable/predictable from the programmers point of 
view.

> For that matter, should f1(foo text, bar text) and f1(baz text, xyzzy
> text) be considered to be different function signatures that ought to be
> permitted to coexist in a single schema?  If actual parameter names are
> going to affect resolution of search-path ambiguity, it's hard to argue
> that the parameter names aren't part of the signature.

At first I plan to not have the argument names as part of the signature.
Mainly because if one start without one can add it later if needed.  To
have it part of the signature only lets you define more functions then
today. The other database that implements this does have the argument
names as part of the signature.

I think that the value of having it is no that big. Just don't name your
functions and arguments like that. Rejecting cases like that above will 
not make life harder for the programmer. It would rather help him/her 
designing better functions. If it hurts, don't do it.

> What might be the best compromise is to treat parameter names as
> documentation *only*, that is, we insist that the parameters have to
> appear in the declared order in any case.

That would suck big time.

> > About the speed, how many functions do you have with the same name.
> 
> Try "select proname, count(*) from pg_proc group by 1 order by 2 desc;"
> Note that the ones at the top are pretty popular in usage, not only in
> having lots of variants. I don't think it's acceptable to take major
> speed hits in parsing them

There will be no hit at all since the functions calls for these don't use 
named arguments, the exact same method of function resolution as today 
should work fine. You just need to detect at the start if this function 
call is with or without named arguments. I have never had any plans of 
slowing down the current method, including the fast case where all 
arguments have the correct types. I'm sure I will run into problems, like 
the above and/or others. I'll have to deal with it when I run into it.

There is of course another way all this can turn out also, that I don't 
manage to make it work in a good way. In that case there will be no named 
parameter function calls (unless somebody else makes them).

In any case, let me try to make it work before we throw it away. I work on
pg on some free hours here and there. It might take some time until I have
something working, but when I do I would love for you to review the patch
pointing out all errors!

The worst that can happen is that it doesn't work. So what, I can live 
with that :-)

-- 
/Dennis Björklund



Re: Function call

From
Tom Lane
Date:
Dennis Bjorklund <db@zigo.dhs.org> writes:
> Now, the above is just my plan before coding and before understanding 
> everything. It might work and it might not. So far I've got no reason to 
> thing that it wont work,

Before you start writing anything, I suggest you read
http://www.postgresql.org/docs/7.4/static/typeconv-func.html
I can see at least three assumptions in there that will be broken by
allowing different candidate functions to have arguments matched in
different orders.  That's not even counting the questions about whether
we should allow the names of parameters to affect which functions are
considered to be potential candidates.

>> What might be the best compromise is to treat parameter names as
>> documentation *only*, that is, we insist that the parameters have to
>> appear in the declared order in any case.

> That would suck big time.

I don't think you should reject it out of hand.  It's simple and
understandable, and it is guaranteed not to break any existing code
when the programmer simply adds names to the parameter declarations
of a function without changing any call sites.  If the presence of
parameter names changes the ambiguity resolution rules at all, I'm
doubtful that we could guarantee not to break things.
        regards, tom lane


Re: Function call

From
Dennis Bjorklund
Date:
On Wed, 28 Jan 2004, Tom Lane wrote:

> when the programmer simply adds names to the parameter declarations
> of a function without changing any call sites.  If the presence of
> parameter names changes the ambiguity resolution rules at all, I'm
> doubtful that we could guarantee not to break things.

Agreed. Calls without argument names shall work exactly as today.

If you are saying that a call like foo(x => 14, y => 'text') shall always
call the same function even if you add parameter names to a function who
did not have it before. Then that is wrong.

-- 
/Dennis Björklund