Implicit cast of literal in SQL statements

Started by Scott Roystonover 24 years ago4 messageshackersbugs
Jump to latest
#1Scott Royston
scroyston71@yahoo.com
hackersbugs

I've seen a few postings in multiple newsgroups saying that in 7.1.x and
up, literals in SQL statements are implicitly cast to strings.

For example in:
select distinct 'hello' from mytable;
the 'hello' is implicitly assumed to be 'hello'::text

However, in both 7.1.3, and a fresh build of 7.2b4 from cvs, (with all
regressions passing) I get:

mytest=# select distinct 'hello' from mytable;
ERROR: Unable to identify an ordering operator '<' for type 'unknown'
Use an explicit ordering operator or modify the query

an explicit 'hello'::text works fine.

I've spent a day looking through the code and can't really find any
obvious #define's or compile time flags that would be causing this
problem.
It looks like
Const *
make_const(Value *value)
{
...
case T_String:
val = DirectFunctionCall1(textin,
CStringGetDatum(strVal(value)));

typeid = UNKNOWNOID; /* will be coerced
later */
typelen = -1; /* variable len */
typebyval = false;
break;
...
}

does the damage, and it never gets 'coerced later', at least not before
transformDistinctClause(...) gets called, which is where the failure
happens (a few levels down).

does this really work for everybody else? Can someone point me to a
compile flag I may be missing, or the code that actually does the
implicit cast?

thanks

_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Scott Royston (#1)
hackersbugs
Re: Implicit cast of literal in SQL statements

Scott Royston <scroyston71@yahoo.com> writes:

I've seen a few postings in multiple newsgroups saying that in 7.1.x and
up, literals in SQL statements are implicitly cast to strings.

That's an oversimplification: the implicit coercion of unknown literals
only happens when looking for an operator or function to apply to them.
For an unprocessed result literal such as you describe, the type
never does get changed. Which is okay because type "unknown" does have
an output routine, which is all that's needed to emit the literal.
You may care to peruse the rules in
http://developer.postgresql.org/docs/postgres/typeconv.html

However, in both 7.1.3, and a fresh build of 7.2b4 from cvs, (with all
regressions passing) I get:

mytest=# select distinct 'hello' from mytable;
ERROR: Unable to identify an ordering operator '<' for type 'unknown'
Use an explicit ordering operator or modify the query

This is mildly annoying but I'm not sure that fixing it wouldn't
introduce greater annoyances. As an example of the pitfalls, consider:

regression=# select 1 union select '2';
?column?
----------
1
2
(2 rows)

regression=# select 1 union select '2'::text;
ERROR: UNION types "int4" and "text" not matched

The first example works because the right-hand SELECT's result is not
coerced to "text" before UNION can get its hands on it.

Possibly DISTINCT should be allowed to type-coerce unknown inputs to
text the same way that explicit operators and functions can. Offhand
I'm not sure if that's a good solution or not. There are related
cases to consider too, eg ORDER BY and GROUP BY.

regards, tom lane

#3Thomas Lockhart
lockhart@fourpalms.org
In reply to: Scott Royston (#1)
hackersbugs
Re: Implicit cast of literal in SQL statements

I've seen a few postings in multiple newsgroups saying that in 7.1.x and
up, literals in SQL statements are implicitly cast to strings.

In some contexts, that statement is true, yes. The cases where this is
true is when the parser is trying to match literals with available
function calls. If there is a literal of unknown type, and if there is a
function which could take a string literal as input, then that function
is the one chosen.

does this really work for everybody else? Can someone point me to a
compile flag I may be missing, or the code that actually does the
implicit cast?

It looks like we are not handling the case where there is no explicit
function call, and there a string literal in the target list (so no
underlying column to infer a type from), and there is a subsequent
ordering operation. That might be fixable, but it may not be a useful
real world example afaict.

Do you have another example to illustrate the problem for a query which
one might actually need to use?

- Thomas

#4Scott Royston
scroyston71@yahoo.com
In reply to: Thomas Lockhart (#3)
hackersbugs
Re: Implicit cast of literal in SQL statements

I've got some 'legacy' code that I'm dealing with - sometimes it will
receive query requests that are simply the union of two easier requests
it already knows the sql for.
These 'easier' queries have 'distincts' in them, and the code doesn't go
to the trouble of removing by hand when doing a union.
so the query ends up looking like:
SELECT DISTINCT firstName, middleName, lastName FROM completeNameTable
WHERE (...)
UNION
SELECT DISTINCT firstName, ' ', lastName FROM partialNameTable WHERE(...)

ugly, I know. ( and probably inefficient, I should check the plan )

thanks for the quick response

On Thursday, December 27, 2001, at 03:28 PM, Thomas Lockhart wrote:

I've seen a few postings in multiple newsgroups saying that in 7.1.x
and
up, literals in SQL statements are implicitly cast to strings.

In some contexts, that statement is true, yes. The cases where this is
true is when the parser is trying to match literals with available
function calls. If there is a literal of unknown type, and if there is a
function which could take a string literal as input, then that function
is the one chosen.

does this really work for everybody else? Can someone point me to a
compile flag I may be missing, or the code that actually does the
implicit cast?

It looks like we are not handling the case where there is no explicit
function call, and there a string literal in the target list (so no
underlying column to infer a type from), and there is a subsequent
ordering operation. That might be fixable, but it may not be a useful
real world example afaict.

Do you have another example to illustrate the problem for a query which
one might actually need to use?

- Thomas

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org

_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com