Обсуждение: quote_literal with NULL

Поиск
Список
Период
Сортировка

quote_literal with NULL

От
"Brendan Jurd"
Дата:
Hi hackers,

I note that if you pass NULL to quote_literal(), you get NULL.

This isn't surprising, but I was thinking that the stated purpose of
quote_literal is preparing the argument for entry into a dynamic SQL
statement.  In this context, it fails for NULL input.

Wouldn't it be more useful if quote_literal(NULL) yielded the text value 'NULL'?

With the current behaviour, if you want quote_literal to be "null
safe" you have to replace any such calls with
coalesce(quote_literal(foo), 'NULL')).  Since the use case for
quote_literal is concatenating the result with some other text, a NULL
return seems guaranteed to be unhelpful.

Meanwhile, the string 'NULL' is the only way of representing a NULL in
SQL, so it makes sense (to me) that this is what quote_literal should
output.

Comments?

Cheers,
BJ


Re: quote_literal with NULL

От
Simon Riggs
Дата:
On Wed, 2007-10-10 at 14:57 +1000, Brendan Jurd wrote:

> Wouldn't it be more useful if quote_literal(NULL) yielded the text value 'NULL'?

I don't think you can change that now. There could be code out there
that relies on that behaviour.

It isn't very helpful to return the word NULL in many cases, since the
WHERE clause "col = NULL" does not do the same thing as "col is NULL".
So you need to know about NULL values and how to handle them in many
cases. 

It might be useful to define a new text concatenation operator ||| that
treats NULL values as zero-length strings, so that  'help ' ||| NULL ||| 'me' returns 'help me'

--  Simon Riggs 2ndQuadrant  http://www.2ndQuadrant.com



Re: quote_literal with NULL

От
"Brendan Jurd"
Дата:
On 10/10/07, Simon Riggs <simon@2ndquadrant.com> wrote:
> On Wed, 2007-10-10 at 14:57 +1000, Brendan Jurd wrote:
>
> > Wouldn't it be more useful if quote_literal(NULL) yielded the text value 'NULL'?
>
> I don't think you can change that now. There could be code out there
> that relies on that behaviour.
>

Bummer.  But I take your point.  If there's a good chance someone is
going to have their application murdered by a change here, best to
leave it alone.

I've already gotten around this in my own apps by adding a UDF
alternative to quote_literal that plays nicely with NULLs, but thought
I'd mention it here in case others were of the same mind.

> It isn't very helpful to return the word NULL in many cases, since the
> WHERE clause "col = NULL" does not do the same thing as "col is NULL".
> So you need to know about NULL values and how to handle them in many
> cases.
>

Well if you're expecting a possibly-NULL value in your dynamic query
you're going to be using something like 'WHERE foo IS NOT DISTINCT
FROM ' || quote_literal(bar) anyway.

Either way possibly-NULL values need to be anticipated and treated
specially.  With the string 'NULL' you need DISTINCT FROM.  With an
actual NULL you need COALESCE.  It just seemed to me that the string
'NULL' result was more in line with what quote_literal was supposed to
do; and leads to less cluttered code.

> It might be useful to define a new text concatenation operator ||| that
> treats NULL values as zero-length strings, so that
>   'help ' ||| NULL ||| 'me' returns 'help me'
>

That could be cool.  Not immediately practical for the dynamic query
scenario though: If I do 'WHERE foo IS NOT DISTINCT FROM ' |||
quote_literal(bar) it'll still give me an invalid query string if bar
is NULL.

Cheers,
BJ


Re: quote_literal with NULL

От
"Kevin Grittner"
Дата:
>>> On Wed, Oct 10, 2007 at  4:57 AM, in message
<37ed240d0710100257r149a8d2cmb671b69a1673eb54@mail.gmail.com>, "Brendan Jurd"
<direvus@gmail.com> wrote:
> On 10/10/07, Simon Riggs <simon@2ndquadrant.com> wrote:
>> On Wed, 2007-10-10 at 14:57 +1000, Brendan Jurd wrote:
>>
>> > Wouldn't it be more useful if quote_literal(NULL) yielded the text value
> 'NULL'?
>>
>> I don't think you can change that now. There could be code out there
>> that relies on that behaviour.
>>
>
> Bummer.  But I take your point.  If there's a good chance someone is
> going to have their application murdered by a change here, best to
> leave it alone.
In particular, it seems like exactly what you would want for values
you're going to use in an INSERT or the SET clause of an UPDATE.
-Kevin




Re: quote_literal with NULL

От
Simon Riggs
Дата:
On Wed, 2007-10-10 at 10:12 -0500, Kevin Grittner wrote:
> >>> On Wed, Oct 10, 2007 at  4:57 AM, in message
> <37ed240d0710100257r149a8d2cmb671b69a1673eb54@mail.gmail.com>, "Brendan Jurd"
> <direvus@gmail.com> wrote: 
> > On 10/10/07, Simon Riggs <simon@2ndquadrant.com> wrote:
> >> On Wed, 2007-10-10 at 14:57 +1000, Brendan Jurd wrote:
> >>
> >> > Wouldn't it be more useful if quote_literal(NULL) yielded the text value 
> > 'NULL'?
> >>
> >> I don't think you can change that now. There could be code out there
> >> that relies on that behaviour.
> >>
> > 
> > Bummer.  But I take your point.  If there's a good chance someone is
> > going to have their application murdered by a change here, best to
> > leave it alone.
>  
> In particular, it seems like exactly what you would want for values
> you're going to use in an INSERT or the SET clause of an UPDATE.

Perhaps have quote_nullable() then as well?

You then use quote_nullable() in INSERT and UPDATE SET clauses and
quote_literal() in SELECT WHERE clauses. 

--  Simon Riggs 2ndQuadrant  http://www.2ndQuadrant.com



Re: quote_literal with NULL

От
"Greg Sabino Mullane"
Дата:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160


> Perhaps have quote_nullable() then as well?
>
> You then use quote_nullable() in INSERT and UPDATE SET clauses and
> quote_literal() in SELECT WHERE clauses. 

I still don't see the use case. Wouldn't your app still need to check 
for nullability anyway, to avoid " = NULL"? (Aside: seems to me that 
SET foo = NULL; really should be SET foo TO NULL; to be consistent 
with WHERE foo IS NULL;)

- --
Greg Sabino Mullane greg@turnstep.com
PGP Key: 0x14964AC8 200710101221
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8

-----BEGIN PGP SIGNATURE-----

iD8DBQFHDPwyvJuQZxSWSsgRAwGaAJ92ICR+MyclkmWvJRkC4vazIw+b0ACghpZt
WXbCxe0abFlp8jwr0ol/fac=
=oWqD
-----END PGP SIGNATURE-----




Re: quote_literal with NULL

От
Tom Lane
Дата:
"Greg Sabino Mullane" <greg@turnstep.com> writes:
>> Perhaps have quote_nullable() then as well?
>> 
>> You then use quote_nullable() in INSERT and UPDATE SET clauses and
>> quote_literal() in SELECT WHERE clauses. 

> I still don't see the use case. Wouldn't your app still need to check 
> for nullability anyway, to avoid " = NULL"?

Well, it's clearly useful in INSERT and UPDATE.  For WHERE cases, you
might or might not be able to use it, but I note that quote_nullable()
would work much more like what happens if you use a parameter symbol
and then bind NULL as the actual parameter value ...

In hindsight we should probably have done quote_literal the way the OP
suggests, but I concur that it's too late to change it.  An additional
function seems a reasonable compromise.
        regards, tom lane


Re: quote_literal with NULL

От
Michael Glaesemann
Дата:
On Oct 10, 2007, at 11:24 , Greg Sabino Mullane wrote:

> (Aside: seems to me that
> SET foo = NULL; really should be SET foo TO NULL; to be consistent
> with WHERE foo IS NULL;)

The = character has different meanings in these two cases.

UPDATE foos
SET foo = NULL  -- assignment
WHERE bar IS NULL -- comparison    AND foo = 'ignore me' -- comparison

Or is that what the smiley was about? :)

Michael Glaesemann
grzm seespotcode net



Re: quote_literal with NULL

От
"Brendan Jurd"
Дата:
On 10/11/07, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Well, it's clearly useful in INSERT and UPDATE.  For WHERE cases, you
> might or might not be able to use it, but I note that quote_nullable()
> would work much more like what happens if you use a parameter symbol
> and then bind NULL as the actual parameter value ...
>
> In hindsight we should probably have done quote_literal the way the OP
> suggests, but I concur that it's too late to change it.  An additional
> function seems a reasonable compromise.

quote_nullable() works for me.  I'll write up a patch.

Cheers,
BJ