Re: select (17, 42)::s.t2 into... fails with "invalid input syntax" - Mailing list pgsql-general

From Bryn Llewellyn
Subject Re: select (17, 42)::s.t2 into... fails with "invalid input syntax"
Date
Msg-id 9E792FAF-873E-40AA-A3CF-A4AB55EF8230@yugabyte.com
Whole thread Raw
In response to Re: select (17, 42)::s.t2 into... fails with "invalid input syntax"  ("David G. Johnston" <david.g.johnston@gmail.com>)
Responses Re: select (17, 42)::s.t2 into... fails with "invalid input syntax"
List pgsql-general
> david.g.johnston@gmail.com wrote:
>
>> bryn@yugabyte.com wrote:
>>
>> «
>> SELECT select_expressions INTO [STRICT] target FROM …;
>>
>> where target can be a record variable, a row variable, or a comma-separated list of simple variables and record/row
fields.
>> »
>>
>> In plain English, the "into" target cannot be a local variable whose data type is a composite type. That comes as a
completeshock. Moreover, it isn't true—as Tom's advice shows. (I tried it and it worked.) I don't know what "simple"
(asin "simple variable" means. I'm guessing that it means "single-valued" in the Codd-and-Date sense so that, for
example,42 and 'dog' are simple but array[1, 2, 3] isn't. My test (below), with a column "c1" and a local variable
"arr",both of data type "int[]",  showed that "select… c2… into arr…" works fine here. So the wording in the doc that I
copiedabove could be improved. 
>
> Reading the meaning of "simple" to be "not record or row variables" seems like the safe bet, since those are covered
inthe first part of the sentence.  As a composite type is the umbrella term covering both record and row that sentence
mostcertainly does allow for such a variable to be the target.  But when it is, each individual column of the result
getsmapped to individual fields of the composite type.  This seems like a reasonable use case to define behavior from. 
>
>> postgresql composite type constructor
>>
>> For example, "8.16. Composite Types" (www.postgresql.org/docs/current/rowtypes.html#id-1.5.7.24.6) talks only about
anonymous"row". And this little test seems to show that "row" and "record" mean the same thing—but you seed to write
(oryou see) different spellings in different contexts: 
>>
>> with
>>   c(r) as (values(row(1, 'a', true)))
>> select c.r, pg_typeof(c.r) from c;
>
> Composite types that don't have a system-defined name are instead named "record".  "Row" usually means that not only
isthe composite type named but the name matches that of a table in the system.  IOW, as noted above, "composite type"
isa type category or umbrella that covers all of these cases. 
>
>> Confusing, eh? There seems to be some doc missing here too that defines "type constructor" and that uses "(f1,
..fn)::qualified_type_id".(The "create type" account should x-ref it.) 
>
> You just pointed to the relevant documentation, and adding it to create type doesn't seem like a good fit but if
someonewanted to I'm not sure I'd veto it. 
>
>>   -- Tom's approach. Not nice.
>>   -- Two separate "select" statements to avoid
>>   -- 42601: record variable cannot be part of multiple-item INTO list.
>>   select (a.c1).a1, (a.c1).a2 into r  from s.t as a where a.k = 1;
>>   select a.c2 into arr                from s.t as a where a.k = 1;
>
> Yeah, I can see this as a natural consequence of the "column per field" behavior decision.  Maybe it should be
coveredbetter in the docs?  Seems like an unfortunate corner-case annoyance seldom encountered due to the general
disuseof composite types. 
>
>>   for the_row in (select a.c1, a.c2 from s.t as a order by a.k) loop
>>     z := the_row.c1::text||' / '||the_row.c2::text;                             return next;
>>   end loop;
>
> Doesn't seem like a terrible work-around even in the single-row case...

If "composite type" is the umbrella term that covers "row", "record", and the result of "create type… as (…)", what is
theterm of art for the latter? The account of "pg_type.typtype" says this: 

« b for a base type, c for a composite type (e.g., a table's row type), d for a domain, e for an enum type, p for a
pseudo-type,or r for a range type. » 

This wording doesn't help me because there are no DDLs to create occurrences of "row" or "record". And the companion
fora table is a real schema-object, distinct from the table itself like the result of "create type… as (…)" using the
namesand data types of the table's columns. (I'm assuming here that no particular schema-object can have a row both in
pg_classand pg_type.) So it seems wrong to call this a "row type" because doing so leaves no term of art left over for
theephemeral result of "row(1, 'a', true)" which pg_typeof anyway calls "record". 

Finally, what terms of art do PG experts use to distinguish between single-valued data types like "integer", "text",
"boolean"and so on and multi--valued data types like "array", "row", "record", and the result of "create type… as (…)"? 




pgsql-general by date:

Previous
From: Tomas Pospisek
Date:
Subject: Re: can't get psql authentication against Active Directory working
Next
From: "David G. Johnston"
Date:
Subject: Re: select (17, 42)::s.t2 into... fails with "invalid input syntax"