Thread: Re: BUG #4078: ERROR: operator does not exist: numeric = character varying
Re: BUG #4078: ERROR: operator does not exist: numeric = character varying
From
Eric Haszlakiewicz
Date:
Peter Eisentraut, April 1 2008 > Am Dienstag, 1. April 2008 schrieb rupesh: > > ERROR: operator does not exist: numeric = character varying at character > > 675 > > HINT: No operator matches the given name and argument type(s). You might > > need to add explicit type casts. > > (0.735 sec) > > > > > > This was previously working in 8.2.3 but not in 8.3 > This was an intentional change. Please read the release notes about fixing > your code. I read the release notes, and the idea of removing this to avoid problematic automatic casts seems reasonable, but why not add an additional operator so the useful cases actually still work? I created this, which seems to solve the problem: create function casting_eq_operator(integer, "char") returns boolean as 'begin return $1 = cast ($2 as integer); end;' language plpgsql immutable strict; CREATE OPERATOR = (PROCEDURE = casting_eq_operator, LEFTARG = integer , RIGHTARG = "char", COMMUTATOR = =, NEGATOR = !=, HASHES, MERGES ); Can this be included by default? On a related note, I originally wrote this using 'character varying' instead of '"char"', but that caused simple string comparisons in queries to fail. e.g. select * from foo where mycol = 'abc'; when mycol is a varchar column complained about "invalid input syntax for integer". Is there a simple explanation for why it wouldn't just try to do a plain string comparison instead of using my custom operator? eric
Eric Haszlakiewicz <erh@swapsimple.com> writes: > I created this, which seems to solve the problem: > create function casting_eq_operator(integer, "char") > returns boolean as 'begin > return $1 = cast ($2 as integer); > end;' language plpgsql immutable strict; > CREATE OPERATOR = (PROCEDURE = casting_eq_operator, > LEFTARG = integer , RIGHTARG = "char", > COMMUTATOR = =, NEGATOR = !=, HASHES, MERGES > ); > Can this be included by default? No. Even if we desired to reverse the decision about not having implicit casting behavior, this definition of the operator would not be appropriate because it provides the opposite of the old behavior. The pre-8.3 behavior would have been to cast the integer to text and apply a textual comparison; which gives different comparison behavior, eg leading zeroes in the string would affect the result. Not to mention that the cast to integer in this definition would fail outright if the string didn't look like an integer. A large part of the reasoning for getting rid of the implicit casts was exactly that it's not very clear what a comparison of this sort should act like, and most people who are accidentally invoking it haven't thought that through either. (Some other problems: I'm pretty sure you meant to refer to text or varchar not "char"; you referenced commutator and negator operators without defining them; this operator certainly does not hash, and I don't think it merges either, though maybe you could make the latter work if you'd provided all the requisite btree-opfamily infrastructure.) regards, tom lane
Re: Re: BUG #4078: ERROR: operator does not exist: numeric = character varying
From
Eric Haszlakiewicz
Date:
On Mon, Oct 13, 2008 at 09:10:41PM -0400, Tom Lane wrote: > Eric Haszlakiewicz <erh@swapsimple.com> writes: > > I created this, which seems to solve the problem: > > > create function casting_eq_operator(integer, "char") > > returns boolean as 'begin > > return $1 = cast ($2 as integer); > > end;' language plpgsql immutable strict; > > > CREATE OPERATOR = (PROCEDURE = casting_eq_operator, > > LEFTARG = integer , RIGHTARG = "char", > > COMMUTATOR = =, NEGATOR = !=, HASHES, MERGES > > ); > > > Can this be included by default? > > No. Even if we desired to reverse the decision about not having > implicit casting behavior, this definition of the operator would not be > appropriate because it provides the opposite of the old behavior. > The pre-8.3 behavior would have been to cast the integer to text and > apply a textual comparison; which gives different comparison behavior, > eg leading zeroes in the string would affect the result. Not to mention > that the cast to integer in this definition would fail outright if the > string didn't look like an integer. > > A large part of the reasoning for getting rid of the implicit casts > was exactly that it's not very clear what a comparison of this sort > should act like, and most people who are accidentally invoking it > haven't thought that through either. hmm.. I was thinking that a comparison between a number and a string would cause an error if the string wasn't parseable. Now that I think about it more, I can see that having it just return false might be reasonable too. > > (Some other problems: I'm pretty sure you meant to refer to text or > varchar not "char"; you referenced commutator and negator operators > without defining them; this operator certainly does not hash, and > I don't think it merges either, though maybe you could make the latter > work if you'd provided all the requisite btree-opfamily infrastructure.) Yeah, you're right. I didn't think that through entirely. Sorry for the noise. eric