Re: [PERFORM] typoed column name, but postgres didn't grump

Lists: pgsql-bugspgsql-performance
From: Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>
To: pgsql-performance(at)postgresql(dot)org
Subject: typoed column name, but postgres didn't grump
Date: 2010-10-29 16:40:24
Message-ID: AANLkTimYMA8D2h4-jHK5vD032jWwig1iJmW6uF-3i=Bx@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

I've been having trouble with a query.
The query is a cross join between two tables.
Initially, I mis-typed the query, and one of the columns specified in
the query doesn't exist, however the query ran nonetheless.

The actual query:
select gid from t2, t3 where t2.name = t3.name and t3.scope = 'city'
and t3.hierarchy = 'STANDARD' and t2.adiv = t3.adiv limit 1 ;
However, there *is* no column 'name' in table 't2'.
When I ran the query, it took a *really* long time to run (670 seconds).
When I corrected the query to use the right column name (city_name),
the query ran in 28ms.

The question, then, is why didn't the postgres grump about the
non-existent column name?

The version is 8.4.5 on x86_64, openSUSE 11.3

PostgreSQL 8.4.5 on x86_64-unknown-linux-gnu, compiled by GCC gcc
(SUSE Linux) 4.5.0 20100604 [gcc-4_5-branch revision 160292], 64-bit

--
Jon


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>
Cc: pgsql-performance(at)postgresql(dot)org
Subject: Re: typoed column name, but postgres didn't grump
Date: 2010-10-29 17:48:18
Message-ID: 4480.1288374498@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Jon Nelson <jnelson+pgsql(at)jamponi(dot)net> writes:
> Initially, I mis-typed the query, and one of the columns specified in
> the query doesn't exist, however the query ran nonetheless.

> The actual query:
> select gid from t2, t3 where t2.name = t3.name and t3.scope = 'city'
> and t3.hierarchy = 'STANDARD' and t2.adiv = t3.adiv limit 1 ;
> However, there *is* no column 'name' in table 't2'.

This is the old automatic-cast-from-record-to-text-string issue,
ie it treats this like "(t2.*)::name".

We've been over this a few times before, but it's not clear that
we can make this throw an error without introducing unpleasant
asymmetry into the casting behavior, as in you couldn't get the
cast when you did want it.

BTW this seems pretty far off-topic for pgsql-performance.

regards, tom lane


From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>, "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: <pgsql-performance(at)postgresql(dot)org>
Subject: Re: typoed column name, but postgres didn't grump
Date: 2010-10-29 18:38:54
Message-ID: 4CCACE6E0200002500036F95@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:

> BTW this seems pretty far off-topic for pgsql-performance.

It is once you understand what's happening. It was probably the 11+
minutes for the mistyped query run, versus the 28 ms without the
typo, that led them to this list.

I remembered this as an issued that has come up before, but couldn't
come up with good search criteria for finding the old thread before
you posted. If you happen to have a reference or search criteria
for a previous thread, could you post it? Otherwise, a brief
explanation of why this is considered a feature worth keeping would
be good. I know it has been explained before, but it just looks
wrong, on the face of it.

Playing around with it a little, it seems like a rather annoying
foot-gun which could confuse people and burn a lot of development
time:

test=# create domain make text;
CREATE DOMAIN
test=# create domain model text;
CREATE DOMAIN
test=# create table vehicle (id int primary key, make make);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index
"vehicle_pkey" for table "vehicle"
CREATE TABLE
test=# insert into vehicle values (1,
'Toyota'),(2,'Ford'),(3,'Rambler');
INSERT 0 3
test=# select v.make, v.model from vehicle v;
make | model
---------+-------------
Toyota | (1,Toyota)
Ford | (2,Ford)
Rambler | (3,Rambler)
(3 rows)

If someone incorrectly thinks they've added a column, and the
purported column name happens to match any character-based type or
domain name, they can get a query which behaves in a rather
unexpected way. In this simple query it's pretty easy to spot, but
it could surface in a much more complex query. If a mistyped query
runs for 11 days instead of 11 minutes, they may have a hard time
spotting the problem.

A typo like this could be particularly hazardous in a DELETE or
UPDATE statement.

-Kevin


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
Cc: "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>, pgsql-performance(at)postgresql(dot)org, pgsql-bugs(at)postgresql(dot)org
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-10-29 19:07:26
Message-ID: 6240.1288379246@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

[ please continue any further discussion in pgsql-bugs only ]

"Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
> Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>> BTW this seems pretty far off-topic for pgsql-performance.

> It is once you understand what's happening. It was probably the 11+
> minutes for the mistyped query run, versus the 28 ms without the
> typo, that led them to this list.

> I remembered this as an issued that has come up before, but couldn't
> come up with good search criteria for finding the old thread before
> you posted. If you happen to have a reference or search criteria
> for a previous thread, could you post it? Otherwise, a brief
> explanation of why this is considered a feature worth keeping would
> be good. I know it has been explained before, but it just looks
> wrong, on the face of it.

What's going on here is an unpleasant interaction of several different
features:

1. The notations a.b and b(a) are equivalent: either one can mean the
column b of a table a, or an invocation of a function b() that takes
a's composite type as parameter. This is an ancient PostQUEL-ism,
but we've preserved it because it is helpful for things like
emulating computed columns via functions.

2. The notation t(x) will be taken to mean x::t if there's no function
t() taking x's type, but there is a cast from x's type to t. This is
just as ancient as #1. It doesn't really add any functionality, but
I believe we would break a whole lot of users' code if we took it away.
Because of #1, this also means that x.t could mean x::t.

3. As of 8.4 or so, there are built-in casts available from pretty much
any type (including composites) to all the built-in string types, viz
text, varchar, bpchar, name.

Upshot is that t.name is a cast to type "name" if there's no column or
user-defined function that can match the call. We've seen bug reports
on this with respect to both the "name" and "text" cases, though I'm
too lazy to trawl the archives for them just now.

So, if you want to throw an error for this, you have to choose which
of these other things you want to break. I think if I had to pick a
proposal, I'd say we should disable #2 for the specific case of casting
a composite type to something else. The intentional uses I've seen were
all scalar types; and before 8.4 there was no built-in functionality
that such a call could match. If we slice off some other part of the
functionality, we risk breaking apps that've worked for many years.

regards, tom lane


From: Robert Haas <robertmhaas(at)gmail(dot)com>
To: pgsql-bugs(at)postgresql(dot)org
Cc: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>, Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-10-29 19:15:02
Message-ID: AANLkTim35FrP1EyZRmnotKSw=2rq8JNVutkitn9PXwFp@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

On Fri, Oct 29, 2010 at 3:07 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> [ please continue any further discussion in pgsql-bugs only ]
>
> "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
>> Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>>> BTW this seems pretty far off-topic for pgsql-performance.
>
>> It is once you understand what's happening.  It was probably the 11+
>> minutes for the mistyped query run, versus the 28 ms without the
>> typo, that led them to this list.
>
>> I remembered this as an issued that has come up before, but couldn't
>> come up with good search criteria for finding the old thread before
>> you posted.  If you happen to have a reference or search criteria
>> for a previous thread, could you post it?  Otherwise, a brief
>> explanation of why this is considered a feature worth keeping would
>> be good.  I know it has been explained before, but it just looks
>> wrong, on the face of it.
>
> What's going on here is an unpleasant interaction of several different
> features:
>
> 1. The notations a.b and b(a) are equivalent: either one can mean the
> column b of a table a, or an invocation of a function b() that takes
> a's composite type as parameter.  This is an ancient PostQUEL-ism,
> but we've preserved it because it is helpful for things like
> emulating computed columns via functions.
>
> 2. The notation t(x) will be taken to mean x::t if there's no function
> t() taking x's type, but there is a cast from x's type to t.  This is
> just as ancient as #1.  It doesn't really add any functionality, but
> I believe we would break a whole lot of users' code if we took it away.
> Because of #1, this also means that x.t could mean x::t.
>
> 3. As of 8.4 or so, there are built-in casts available from pretty much
> any type (including composites) to all the built-in string types, viz
> text, varchar, bpchar, name.
>
> Upshot is that t.name is a cast to type "name" if there's no column or
> user-defined function that can match the call.  We've seen bug reports
> on this with respect to both the "name" and "text" cases, though I'm
> too lazy to trawl the archives for them just now.
>
> So, if you want to throw an error for this, you have to choose which
> of these other things you want to break.  I think if I had to pick a
> proposal, I'd say we should disable #2 for the specific case of casting
> a composite type to something else.  The intentional uses I've seen were
> all scalar types; and before 8.4 there was no built-in functionality
> that such a call could match.  If we slice off some other part of the
> functionality, we risk breaking apps that've worked for many years.

Well, then let's do that. It's not the exact fix I'd pick, but it's
clearly better than nothing, so I'm willing to sign on to it as a
compromise position.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Robert Haas" <robertmhaas(at)gmail(dot)com>,<pgsql-bugs(at)postgresql(dot)org>, "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-10-29 19:46:28
Message-ID: 4CCADE440200002500036FB2@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Robert Haas <robertmhaas(at)gmail(dot)com> wrote:

>> 2. The notation t(x) will be taken to mean x::t if there's no
>> function t() taking x's type, but there is a cast from x's type
>> to t.

>> I think if I had to pick a proposal, I'd say we should disable #2
>> for the specific case of casting a composite type to something
>> else.

> Well, then let's do that. It's not the exact fix I'd pick, but
> it's clearly better than nothing, so I'm willing to sign on to it
> as a compromise position.

It seems a bad idea to have so many different syntaxes for identical
CAST semantics, but there they are, and it's bad to break things.
One of the reasons #2 seems like the place to fix it is that it's
pretty flaky anyway -- "it will be taken to mean x unless there no y
but there is a z" is pretty fragile to start with. Adding one more
condition to the places it kicks in doesn't seem as good to me as
dropping it entirely, but then I don't have any code which depends
on type(value) as a cast syntax -- those who do will likely feel
differently.

So, I'd rather scrap #2 entirely; but if that really would break
much working code, +1 for ignoring it when it would cast a composite
to something else.

-Kevin


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
Cc: "Robert Haas" <robertmhaas(at)gmail(dot)com>, pgsql-bugs(at)postgresql(dot)org, "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-10-29 20:12:42
Message-ID: 8216.1288383162@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

"Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
> Robert Haas <robertmhaas(at)gmail(dot)com> wrote:
>>> I think if I had to pick a proposal, I'd say we should disable #2
>>> for the specific case of casting a composite type to something
>>> else.

>> Well, then let's do that. It's not the exact fix I'd pick, but
>> it's clearly better than nothing, so I'm willing to sign on to it
>> as a compromise position.

> So, I'd rather scrap #2 entirely; but if that really would break
> much working code, +1 for ignoring it when it would cast a composite
> to something else.

Well, assuming for the sake of argument that we have consensus on fixing
it like that, is this something we should just do in HEAD, or should we
back-patch into 8.4 and 9.0? We'll be hearing about it nigh
indefinitely if we don't, but on the other hand this isn't the kind of
thing we like to change in released branches.

regards, tom lane


From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "Robert Haas" <robertmhaas(at)gmail(dot)com>, "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>, <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-10-29 20:21:09
Message-ID: 4CCAE6650200002500036FC3@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
>> Robert Haas <robertmhaas(at)gmail(dot)com> wrote:
>>>> I think if I had to pick a proposal, I'd say we should disable
>>>> #2 for the specific case of casting a composite type to
>>>> something else.
>
>>> Well, then let's do that. It's not the exact fix I'd pick, but
>>> it's clearly better than nothing, so I'm willing to sign on to
>>> it as a compromise position.
>
>> So, I'd rather scrap #2 entirely; but if that really would break
>> much working code, +1 for ignoring it when it would cast a
>> composite to something else.
>
> Well, assuming for the sake of argument that we have consensus on
> fixing it like that, is this something we should just do in HEAD,
> or should we back-patch into 8.4 and 9.0? We'll be hearing about
> it nigh indefinitely if we don't, but on the other hand this isn't
> the kind of thing we like to change in released branches.

I can't see back-patching it -- it's a behavior change.

On the bright side, in five years after the release where it's
removed, it will be out of support. Problem reports caused by it
should be tapering off before that....

-Kevin


From: Robert Haas <robertmhaas(at)gmail(dot)com>
To: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>, "<pgsql-bugs(at)postgresql(dot)org>" <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-10-29 21:48:59
Message-ID: 0E628919-9700-47B7-9436-41CEB09DC94F@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

On Oct 29, 2010, at 4:21 PM, "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> wrote:
> Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>> "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
>>> Robert Haas <robertmhaas(at)gmail(dot)com> wrote:
>>>>> I think if I had to pick a proposal, I'd say we should disable
>>>>> #2 for the specific case of casting a composite type to
>>>>> something else.
>>
>>>> Well, then let's do that. It's not the exact fix I'd pick, but
>>>> it's clearly better than nothing, so I'm willing to sign on to
>>>> it as a compromise position.
>>
>>> So, I'd rather scrap #2 entirely; but if that really would break
>>> much working code, +1 for ignoring it when it would cast a
>>> composite to something else.
>>
>> Well, assuming for the sake of argument that we have consensus on
>> fixing it like that, is this something we should just do in HEAD,
>> or should we back-patch into 8.4 and 9.0? We'll be hearing about
>> it nigh indefinitely if we don't, but on the other hand this isn't
>> the kind of thing we like to change in released branches.
>
> I can't see back-patching it -- it's a behavior change.
>
> On the bright side, in five years after the release where it's
> removed, it will be out of support. Problem reports caused by it
> should be tapering off before that....

Yeah, I think we're going to have to live with it, at least for 8.4. One could make an argument that 9.0 is new enough we could get away with a small behavior change to avoid a large amount of user confusion. But that may be a self-serving argument based on wanting to tamp down the bug reports rather than a wisely considered policy decision... so I'm not sure I quite buy it.

...Robert


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>, Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>, "<pgsql-bugs(at)postgresql(dot)org>" <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-10-29 21:53:52
Message-ID: 9887.1288389232@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Robert Haas <robertmhaas(at)gmail(dot)com> writes:
> Yeah, I think we're going to have to live with it, at least for 8.4. One could make an argument that 9.0 is new enough we could get away with a small behavior change to avoid a large amount of user confusion. But that may be a self-serving argument based on wanting to tamp down the bug reports rather than a wisely considered policy decision... so I'm not sure I quite buy it.

Well, tamping down the bug reports is good from the users' point of view
too.

The argument for not changing it in the back branches is that there
might be someone depending on the 8.4/9.0 behavior. However, that seems
moderately unlikely. Also, if we wait, that just increases the chances
that someone will come to depend on it, and then have a problem when
they migrate to 9.1. I think the "risk of breakage" argument has a lot
more force when considering long-standing behaviors than things we just
recently introduced.

regards, tom lane


From: Robert Haas <robertmhaas(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>, Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>, "<pgsql-bugs(at)postgresql(dot)org>" <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-10-30 00:24:54
Message-ID: 4CC661F3-5686-4A46-BF58-547601CB59B3@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

On Oct 29, 2010, at 5:53 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Robert Haas <robertmhaas(at)gmail(dot)com> writes:
>> Yeah, I think we're going to have to live with it, at least for 8.4. One could make an argument that 9.0 is new enough we could get away with a small behavior change to avoid a large amount of user confusion. But that may be a self-serving argument based on wanting to tamp down the bug reports rather than a wisely considered policy decision... so I'm not sure I quite buy it.
>
> Well, tamping down the bug reports is good from the users' point of view
> too.
>
> The argument for not changing it in the back branches is that there
> might be someone depending on the 8.4/9.0 behavior. However, that seems
> moderately unlikely. Also, if we wait, that just increases the chances
> that someone will come to depend on it, and then have a problem when
> they migrate to 9.1. I think the "risk of breakage" argument has a lot
> more force when considering long-standing behaviors than things we just
> recently introduced.

I'm not entirely sure that a behavior we released well over a year ago can be considered "just recently introduced"...

...Robert


From: Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>
To: pgsql-bugs(at)postgresql(dot)org
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-01 01:48:32
Message-ID: AANLkTiksQQzuG7EaNvXVTv0w0G11DZeSoSR5HjN3mWfA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

On Fri, Oct 29, 2010 at 2:07 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> [ please continue any further discussion in pgsql-bugs only ]
>
> "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
>> Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>>> BTW this seems pretty far off-topic for pgsql-performance.
>
>> It is once you understand what's happening.  It was probably the 11+
>> minutes for the mistyped query run, versus the 28 ms without the
>> typo, that led them to this list.

That is correct. Indeed, at this point, I'm not even sure whether I
should have included -performance, here.

>> I remembered this as an issued that has come up before, but couldn't
>> come up with good search criteria for finding the old thread before
>> you posted.  If you happen to have a reference or search criteria
>> for a previous thread, could you post it?  Otherwise, a brief
>> explanation of why this is considered a feature worth keeping would
>> be good.  I know it has been explained before, but it just looks
>> wrong, on the face of it.
>
..

I've spent some time thinking about this. Now, please remember that
I'm not a seasoned postgresql veteran like many of you, but I've been
doing one kind of programming or another for the better part of 20
years. I am also a strong believer in the principle of least surprise.
I say this only so that you might understand better the perspective
I'm coming from. With that said, when I read the first part of your
first item:

> 1. The notations a.b and b(a) are equivalent: either one can mean the
> column b of a table a, or an invocation of a function b() that takes
> a's composite type as parameter.

I feel that, while there may be a fair bit of history here, it's
certainly a bit of a surprise. From my perspective, a.b usually means,
in most other languages (as it does here), "access the named-thing 'b'
from the named-thing 'a' and returns it's value", and whenever
parentheses are involved (especially when in the form "b(a)") it means
"call function 'b' on named-thing 'a' and return the result".

Furthermore, regarding your second point:

> 2. The notation t(x) will be taken to mean x::t if there's no function
> t() taking x's type, but there is a cast from x's type to t. This is
> just as ancient as #1. It doesn't really add any functionality, but
> I believe we would break a whole lot of users' code if we took it away.
> Because of #1, this also means that x.t could mean x::t.

I've always found the form b(a) to have an implicit (if there is a
*type* b that can take a thing of type a, then do so (essentially an
alternate form of casting). For example, Python and some other
languages behave this way. I'm not sure what I might be doing wrong,
but there appears to be some sort of inconsistency here, however, as
select int(10.1) gives me a syntax error and select 10.1::int does
not.

So what I'm saying is that for people that do not have a significant
background in postgresql that the postquel behavior of treating 'a.b'
the same as b(a) is quite a surprise, whereas treating b(a) the same
as a::b is not (since frequently "types" are treated like functions in
many languages).

Therefore, I suggest that you bear these things in mind when
discussing or contemplating how the syntax should work - you probably
have many more people coming *to* postgresql from other languages than
you have users relying on syntax features of postquel.

If I saw this behavior ( a.b also meaning b(a) ) in another SQL
engine, I would consider it a thoroughly unintuitive wart, however I
also understand the need to balance this with existing applications.

--
Jon


From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>, <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-02 21:34:25
Message-ID: 4CD03D9102000025000371C6@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Jon Nelson <jnelson+pgsql(at)jamponi(dot)net> wrote:

> If I saw this behavior ( a.b also meaning b(a) ) in another SQL
> engine, I would consider it a thoroughly unintuitive wart

I think the main reason it has been kept is the converse -- if you
define a function "b" which takes record "a" as its only parameter,
you have effectively created a "generated column" on any relation
using record type "a". Kind of. It won't show up in the display of
the relation's structure or in a SELECT *, and you can't use it in
an unqualified reference; but you can use a.b to reference it, which
can be convenient.

It seems to me that this would be most useful in combination with
the inheritance model of PostgreSQL (when used for modeling object
hierarchies rather than partitioning).

-Kevin


From: Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>
To:
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-02 22:17:00
Message-ID: AANLkTikS1ne-VdEwKNp1FqWNhxF=84cXrL1P_zJYaie=@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

On Tue, Nov 2, 2010 at 4:34 PM, Kevin Grittner
<Kevin(dot)Grittner(at)wicourts(dot)gov> wrote:
> Jon Nelson <jnelson+pgsql(at)jamponi(dot)net> wrote:
>
>> If I saw this behavior ( a.b also meaning b(a) ) in another SQL
>> engine, I would consider it a thoroughly unintuitive wart
>
> I think the main reason it has been kept is the converse -- if you
> define a function "b" which takes record "a" as its only parameter,
> you have effectively created a "generated column" on any relation
> using record type "a".  Kind of.  It won't show up in the display of
> the relation's structure or in a SELECT *, and you can't use it in
> an unqualified reference; but you can use a.b to reference it, which
> can be convenient.

Aha. I think I understand, now. I also read up on CAST behavior
changes between 8.1 and 8.4 (what I'm using), and I found section
34.4.2 "SQL Functions on Composite Types" quite useful.

Thanks!

--
Jon


From: Merlin Moncure <mmoncure(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>, Robert Haas <robertmhaas(at)gmail(dot)com>, pgsql-bugs(at)postgresql(dot)org, Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-04 15:24:05
Message-ID: AANLkTimdEYcskXpSdiMDyK6R40G66T9SdM7JDUTvY=4h@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

On Fri, Oct 29, 2010 at 4:12 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
>> Robert Haas <robertmhaas(at)gmail(dot)com> wrote:
>>>> I think if I had to pick a proposal, I'd say we should disable #2
>>>> for the specific case of casting a composite type to something
>>>> else.
>
>>> Well, then let's do that.  It's not the exact fix I'd pick, but
>>> it's clearly better than nothing, so I'm willing to sign on to it
>>> as a compromise position.
>
>> So, I'd rather scrap #2 entirely; but if that really would break
>> much working code, +1 for ignoring it when it would cast a composite
>> to something else.
>
> Well, assuming for the sake of argument that we have consensus on fixing
> it like that, is this something we should just do in HEAD, or should we
> back-patch into 8.4 and 9.0?  We'll be hearing about it nigh
> indefinitely if we don't, but on the other hand this isn't the kind of
> thing we like to change in released branches.

Trying to understand real world cases that this would break...would
the following now fail w/o explicit cast?

create type x as (a int, b int);
select f((1,2));

merlin


From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Merlin Moncure" <mmoncure(at)gmail(dot)com>, "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "Robert Haas" <robertmhaas(at)gmail(dot)com>, "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>, <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-04 15:35:08
Message-ID: 4CD28C5C020000250003727B@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Merlin Moncure <mmoncure(at)gmail(dot)com> wrote:

> Trying to understand real world cases that this would
> break...would the following now fail w/o explicit cast?
>
> create type x as (a int, b int);
> select f((1,2));

It already does:

test=# create type x as (a int, b int);
CREATE TYPE
test=# select f((1,2));
ERROR: function f(record) does not exist
LINE 1: select f((1,2));
^
HINT: No function matches the given name and argument types. You
might need to add explicit type casts.

-Kevin


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
Cc: "Merlin Moncure" <mmoncure(at)gmail(dot)com>, "Robert Haas" <robertmhaas(at)gmail(dot)com>, "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-04 16:14:45
Message-ID: 9974.1288887285@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

"Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
> Merlin Moncure <mmoncure(at)gmail(dot)com> wrote:
>> Trying to understand real world cases that this would
>> break...would the following now fail w/o explicit cast?
>>
>> create type x as (a int, b int);
>> select f((1,2));

> It already does:

I think Merlin probably meant to write "select x((1,2))", but that
doesn't work out-of-the-box either. What would be affected is
something like

select text((1,2));

which you'd now be forced to write as

select (1,2)::text;

(or you could use CAST notation; but not text(row) or row.text).

regards, tom lane


From: Merlin Moncure <mmoncure(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>, Robert Haas <robertmhaas(at)gmail(dot)com>, Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-04 16:48:08
Message-ID: AANLkTikymqi_chTOgpUzmFfA_hCbEQLDwhaA7No_1hgq@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

On Thu, Nov 4, 2010 at 12:14 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
>> Merlin Moncure <mmoncure(at)gmail(dot)com> wrote:
>>> Trying to understand real world cases that this would
>>> break...would the following now fail w/o explicit cast?
>>>
>>> create type x as (a int, b int);
>>> select f((1,2));
>
>> It already does:
>
> I think Merlin probably meant to write "select x((1,2))", but that
> doesn't work out-of-the-box either.  What would be affected is
> something like

Actually I didn't -- I left out that there was a function f taking x.
I misunderstood your assertion above: "The notation t(x) will be taken
to mean x::t if there's no function t() taking x's type, but there is
a cast from x's type to t".

I thought you meant that it would no longer implicitly cast where it
used to for record types, rather than the expression rewrite it was
doing (it just clicked). Anyways, no objection to the change, or even
the backpatch if you'd like to do that. FWIW.

If we ever have an IOCCCish contest for postgresql variant of SQL,
there are some real gems in this thread :-).

merlin


From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "Merlin Moncure" <mmoncure(at)gmail(dot)com>, "Robert Haas" <robertmhaas(at)gmail(dot)com>, "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>, <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-04 16:49:28
Message-ID: 4CD29DC802000025000372A4@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:

> What would be affected is something like
>
> select text((1,2));
>
> which you'd now be forced to write as
>
> select (1,2)::text;
>
> (or you could use CAST notation; but not text(row) or row.text).

Right. As far as I'm aware, there are currently four ways to spell
"cast record to text":

select cast((1,2) as text);
select (1,2)::text;
select text((1,2));
select ((1,2)).text;

We would be disallowing the last two spellings. They aren't that
reliable as casts anyway, since whether they are taken as a cast
depends on the field names of the record.

test=# create type x as (a int, b int, c text);
CREATE TYPE
test=# select cast((1,2,'three')::x as text);
row
-------------
(1,2,three)
(1 row)

test=# select (1,2,'three')::x::text;
row
-------------
(1,2,three)
(1 row)

test=# select text((1,2,'three')::x);
text
-------------
(1,2,three)
(1 row)

test=# select ((1,2,'three')::x).text;
text
-------------
(1,2,three)
(1 row)

test=# drop type x;
DROP TYPE
test=# create type x as (a int, b int, text text);
CREATE TYPE
test=# select cast((1,2,'three')::x as text);
row
-------------
(1,2,three)
(1 row)

test=# select (1,2,'three')::x::text;
row
-------------
(1,2,three)
(1 row)

test=# select text((1,2,'three')::x);
text
-------
three
(1 row)

test=# select ((1,2,'three')::x).text;
text
-------
three
(1 row)

So we would only be keeping cast syntax which can be counted on to
retain cast semantics in the face of a column name change.

-Kevin


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Merlin Moncure <mmoncure(at)gmail(dot)com>
Cc: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>, Robert Haas <robertmhaas(at)gmail(dot)com>, Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-04 16:56:20
Message-ID: 11057.1288889780@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Merlin Moncure <mmoncure(at)gmail(dot)com> writes:
> On Thu, Nov 4, 2010 at 12:14 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>> "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
>>> Merlin Moncure <mmoncure(at)gmail(dot)com> wrote:
>>>> create type x as (a int, b int);
>>>> select f((1,2));

>> I think Merlin probably meant to write "select x((1,2))", but that
>> doesn't work out-of-the-box either. What would be affected is
>> something like

> Actually I didn't -- I left out that there was a function f taking x.

Ah. No, that would still work after the change. The case that I'm
proposing to break is using function-ish notation to invoke a cast
from a composite type to some other type whose name you use as if it
were a function. Even there, if you've created such a cast following
the usual convention of naming the cast function after the target type,
it'll still act the same. It's just the built-in I/O-based casts that
will stop working this way (for lack of a matching underlying function).

regards, tom lane


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Merlin Moncure <mmoncure(at)gmail(dot)com>, Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>, Robert Haas <robertmhaas(at)gmail(dot)com>, Jon Nelson <jnelson+pgsql(at)jamponi(dot)net>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-05 19:17:24
Message-ID: 29497.1288984644@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

I wrote:
> Ah. No, that would still work after the change. The case that I'm
> proposing to break is using function-ish notation to invoke a cast
> from a composite type to some other type whose name you use as if it
> were a function. Even there, if you've created such a cast following
> the usual convention of naming the cast function after the target type,
> it'll still act the same. It's just the built-in I/O-based casts that
> will stop working this way (for lack of a matching underlying function).

Here's a proposed patch, sans documentation as yet.

regards, tom lane

Attachment Content-Type Size
disable-composite-casts.patch text/x-patch 2.5 KB

From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Merlin Moncure" <mmoncure(at)gmail(dot)com>, "Robert Haas" <robertmhaas(at)gmail(dot)com>, "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>, <pgsql-bugs(at)postgresql(dot)org>,"Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-05 20:15:38
Message-ID: 4CD41F9A020000250003737F@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:

> Here's a proposed patch, sans documentation as yet.

I see you took the surgical approach -- only a cast from a record to
a character string type is affected. I agree that will fix the
complaints I've seen, and I imagine you're keeping the change narrow
to minimize the risk of breaking existing code, but this still looks
weird to me:

test=# select ('2010-11-05'::date).text;
text
------------
2010-11-05
(1 row)

Oh, well -- I guess you have to go well out of your way to shoot
your foot with such cases, so that's probably for the best.

-Kevin


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
Cc: "Merlin Moncure" <mmoncure(at)gmail(dot)com>, "Robert Haas" <robertmhaas(at)gmail(dot)com>, "Jon Nelson" <jnelson+pgsql(at)jamponi(dot)net>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: [PERFORM] typoed column name, but postgres didn't grump
Date: 2010-11-05 20:23:00
Message-ID: 1036.1288988580@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs pgsql-performance

"Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov> writes:
> Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>> Here's a proposed patch, sans documentation as yet.

> I see you took the surgical approach -- only a cast from a record to
> a character string type is affected. I agree that will fix the
> complaints I've seen, and I imagine you're keeping the change narrow
> to minimize the risk of breaking existing code, but this still looks
> weird to me:

> test=# select ('2010-11-05'::date).text;
> text
> ------------
> 2010-11-05
> (1 row)

Perhaps, but it's been accepted since 7.3, with few complaints.
I think we should only remove the behavior that was added in 8.4.

regards, tom lane