Re: [HACKERS] declarations of range-vs-element @ and @

2011-11-17 Thread Jeff Davis
On Wed, 2011-11-16 at 16:41 -0500, Tom Lane wrote:
 But what surprises me about this example is that I'd have expected the
 heuristic assume the unknown is of the same type as the other input
 to resolve it.  Looking more closely, I see that we apply that heuristic
 in such a way that it works only for exact operator matches, not for
 matches requiring coercion (including polymorphic-type matches).  This
 seems a bit weird.  I propose adding a step to func_select_candidate
 that tries to resolve things that way, ie, if all the known-type inputs
 have the same type, then try assuming that the unknown-type ones are of
 that type, and see if that leads to a unique match.  There actually is a
 comment in there that claims we do that, but the code it's attached to
 is really doing something else that involves preferred types within
 type categories...
 
 Thoughts?

That sounds reasonable to me.

Regards,
Jeff Davis


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] declarations of range-vs-element @ and @

2011-11-17 Thread Tom Lane
Jeff Davis pg...@j-davis.com writes:
 On Wed, 2011-11-16 at 16:41 -0500, Tom Lane wrote:
 I propose adding a step to func_select_candidate
 that tries to resolve things that way, ie, if all the known-type inputs
 have the same type, then try assuming that the unknown-type ones are of
 that type, and see if that leads to a unique match.  There actually is a
 comment in there that claims we do that, but the code it's attached to
 is really doing something else that involves preferred types within
 type categories...
 
 Thoughts?

 That sounds reasonable to me.

Here's a draft patch (sans doc changes as yet) that extends the
ambiguous-function resolution rules that way.  It adds the heuristic at
the very end, at the point where we would otherwise fail, and therefore
it cannot change the system's behavior for any case that didn't
previously draw an ambiguous function/operator error.  I experimented
with placing the heuristic earlier in func_select_candidate, but found
that that caused some changes in regression test cases, which made me a
bit nervous.  Those changes were not clearly worse results, but this
isn't an area that I think we should toy with lightly.

I haven't yet tried again on changing the @ and @ declarations, but
will do that next.

regards, tom lane

diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 75f1e20475d1c2df628f0a866fc081c601340e98..01ed85b563d23e9288430a76b28aa5a7b2550b74 100644
*** a/src/backend/parser/parse_func.c
--- b/src/backend/parser/parse_func.c
*** func_select_candidate(int nargs,
*** 618,631 
  	  Oid *input_typeids,
  	  FuncCandidateList candidates)
  {
! 	FuncCandidateList current_candidate;
! 	FuncCandidateList last_candidate;
  	Oid		   *current_typeids;
  	Oid			current_type;
  	int			i;
  	int			ncandidates;
  	int			nbestMatch,
! nmatch;
  	Oid			input_base_typeids[FUNC_MAX_ARGS];
  	TYPCATEGORY slot_category[FUNC_MAX_ARGS],
  current_category;
--- 618,633 
  	  Oid *input_typeids,
  	  FuncCandidateList candidates)
  {
! 	FuncCandidateList current_candidate,
! first_candidate,
! last_candidate;
  	Oid		   *current_typeids;
  	Oid			current_type;
  	int			i;
  	int			ncandidates;
  	int			nbestMatch,
! nmatch,
! nunknowns;
  	Oid			input_base_typeids[FUNC_MAX_ARGS];
  	TYPCATEGORY slot_category[FUNC_MAX_ARGS],
  current_category;
*** func_select_candidate(int nargs,
*** 651,659 
  	 * take a domain as an input datatype.	Such a function will be selected
  	 * over the base-type function only if it is an exact match at all
  	 * argument positions, and so was already chosen by our caller.
  	 */
  	for (i = 0; i  nargs; i++)
! 		input_base_typeids[i] = getBaseType(input_typeids[i]);
  
  	/*
  	 * Run through all candidates and keep those with the most matches on
--- 653,674 
  	 * take a domain as an input datatype.	Such a function will be selected
  	 * over the base-type function only if it is an exact match at all
  	 * argument positions, and so was already chosen by our caller.
+ 	 *
+ 	 * While we're at it, count the number of unknown-type arguments for use
+ 	 * later.
  	 */
+ 	nunknowns = 0;
  	for (i = 0; i  nargs; i++)
! 	{
! 		if (input_typeids[i] != UNKNOWNOID)
! 			input_base_typeids[i] = getBaseType(input_typeids[i]);
! 		else
! 		{
! 			/* no need to call getBaseType on UNKNOWNOID */
! 			input_base_typeids[i] = UNKNOWNOID;
! 			nunknowns++;
! 		}
! 	}
  
  	/*
  	 * Run through all candidates and keep those with the most matches on
*** func_select_candidate(int nargs,
*** 749,762 
  		return candidates;
  
  	/*
! 	 * Still too many candidates? Try assigning types for the unknown columns.
! 	 *
! 	 * NOTE: for a binary operator with one unknown and one non-unknown input,
! 	 * we already tried the heuristic of looking for a candidate with the
! 	 * known input type on both sides (see binary_oper_exact()). That's
! 	 * essentially a special case of the general algorithm we try next.
  	 *
! 	 * We do this by examining each unknown argument position to see if we can
  	 * determine a type category for it.	If any candidate has an input
  	 * datatype of STRING category, use STRING category (this bias towards
  	 * STRING is appropriate since unknown-type literals look like strings).
--- 764,779 
  		return candidates;
  
  	/*
! 	 * Still too many candidates?  Try assigning types for the unknown inputs.
  	 *
! 	 * If there are no unknown inputs, we have no more heuristics that apply,
! 	 * and must fail.
! 	 */
! 	if (nunknowns == 0)
! 		return NULL;			/* failed to select a best candidate */
! 
! 	/*
! 	 * The next step examines each unknown argument position to see if we can
  	 * determine a type category for it.	If any candidate has an input
  	 * datatype of STRING category, use STRING category (this bias towards
  	 * STRING is appropriate since unknown-type literals look like strings).

[HACKERS] declarations of range-vs-element @ and @

2011-11-16 Thread Tom Lane
Why do these use anynonarray rather than anyelement?  Given that we
support ranges of arrays (there's even a regression test), this seems
a bogus limitation.

regards, tom lane

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] declarations of range-vs-element @ and @

2011-11-16 Thread Tom Lane
I wrote:
 Why do these use anynonarray rather than anyelement?  Given that we
 support ranges of arrays (there's even a regression test), this seems
 a bogus limitation.

After experimenting with changing that, I see why you did it: some of
the regression tests fail, eg,

  SELECT * FROM array_index_op_test WHERE i @ '{38,34,32,89}' ORDER BY seqno;
  ERROR:  operator is not unique: integer[] @ unknown

That is, if we have both anyarray @ anyarray and anyelement @ anyrange
operators, the parser is unable to decide which one is a better match to
integer[] @ unknown.  However, restricting @ to not work for ranges
over arrays is a pretty horrid fix for that, because there is simply not
any access to the lost functionality.  It'd be better IMO to fail here
and require the unknown literal to be cast explicitly than to do this.

But what surprises me about this example is that I'd have expected the
heuristic assume the unknown is of the same type as the other input
to resolve it.  Looking more closely, I see that we apply that heuristic
in such a way that it works only for exact operator matches, not for
matches requiring coercion (including polymorphic-type matches).  This
seems a bit weird.  I propose adding a step to func_select_candidate
that tries to resolve things that way, ie, if all the known-type inputs
have the same type, then try assuming that the unknown-type ones are of
that type, and see if that leads to a unique match.  There actually is a
comment in there that claims we do that, but the code it's attached to
is really doing something else that involves preferred types within
type categories...

Thoughts?

regards, tom lane

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers