Обсуждение: Where's the doc for "array()" — as in "select array(values (17), (42))"

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

Where's the doc for "array()" — as in "select array(values (17), (42))"

От
Bryn Llewellyn
Дата:
I noticed that "array()" is used in the query that implements the "\du" psql meta-command. It has some similarity with "array_agg()" thus:

create temporary view x(v) as (values (17), (42));
select array_agg(v) from x;
select array(select v from x);

But there are differences. The "array()" function requires that its argument is a subquery that returns a single column. (Its data type can be composite.) But the "array_agg()" function's argument must be the select list in the larger context of a select statement—and in general together with "group by".

It seems that the functionality of "array()" can always be achieved by using "array_agg()"—but the overall construct might be less compact. I don't know if the converse is true. (I didn't think it through.)

Anyway, I can't find where "array()" is documented. Google does find me a hit on stackexchange.com. But it doesn't x-ref to the PG doc.

Finally, my new realization that even the humble "length()" is just a function in the pg_catalog schema that comes with any newly-created database led me to think that I'd find "array()" there. But while "\df length" and "\df array_agg" give me useful information, "\df array" gives me nothing. More carefully stated, this:

select proname from pg_proc
where proname in ('length', 'array_agg', 'array');

gets rows for "length" and "array_agg" but not for "array". What's going on here? I wondered if "array()" might be part of SQL syntax, like (loosely) "as(…)" is. But the account of the "select" statement doesn't mention it.

Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
Adrian Klaver
Дата:
On 9/18/22 13:25, Bryn Llewellyn wrote:
> I noticed that "array()" is used in the query that implements the "\du" 
> psql meta-command. It has some similarity with "array_agg()" thus:
> 
> create temporary view x(v) as (values (17), (42));
> select array_agg(v) from x;
> select array(select v from x);
> 

> Anyway, I can't find where "array()" is documented. Google does find me 
> a hit on stackexchange.com <http://stackexchange.com>. But it doesn't 
> x-ref to the PG doc.

https://www.postgresql.org/docs/current/sql-expressions.html

4.2.12. Array Constructors

"It is also possible to construct an array from the results of a 
subquery. In this form, the array constructor is written with the key 
word ARRAY followed by a parenthesized (not bracketed) subquery. For 
example:

SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
..."

-- 
Adrian Klaver
adrian.klaver@aklaver.com



Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
Adrian Klaver
Дата:
On 9/18/22 13:25, Bryn Llewellyn wrote:
> I noticed that "array()" is used in the query that implements the "\du" 
> psql meta-command. It has some similarity with "array_agg()" thus:
> 
> create temporary view x(v) as (values (17), (42));
> select array_agg(v) from x;
> select array(select v from x);
> 
> But there are differences. The "array()" function requires that its 
> argument is a subquery that returns a single column. (Its data type can 
> be composite.) But the "array_agg()" function's argument must be the 
> select list in the larger context of a select statement—and in general 
> together with "group by".
> 

Lack of an explicit GROUP BY falls through to an implied one:

https://www.postgresql.org/docs/current/sql-select.html#SQL-GROUPBY

"If there are aggregate functions but no GROUP BY clause, the query is 
treated as having a single group comprising all the selected rows."


-- 
Adrian Klaver
adrian.klaver@aklaver.com



Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
"David G. Johnston"
Дата:
On Sunday, September 18, 2022, Adrian Klaver <adrian.klaver@aklaver.com> wrote:
On 9/18/22 13:25, Bryn Llewellyn wrote:
I noticed that "array()" is used in the query that implements the "\du" psql meta-command. It has some similarity with "array_agg()" thus:

create temporary view x(v) as (values (17), (42));
select array_agg(v) from x;
select array(select v from x);


Anyway, I can't find where "array()" is documented. Google does find me a hit on stackexchange.com <http://stackexchange.com>. But it doesn't x-ref to the PG doc.

https://www.postgresql.org/docs/current/sql-expressions.html

Which on can find fairly directly via the index entry for array:


Or browsing the syntax chapter via the table of contents (everything is either a function or syntax, and you ruled out the former).


David J.

Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
Bryn Llewellyn
Дата:
adrian.klaver@aklaver.com wrote:

bryn@yugabyte.com wrote:

I noticed that "array()" is used in the query that implements the "\du" psql meta-command. It has some similarity with "array_agg()" thus:

create temporary view x(v) as (values (17), (42));
select array_agg(v) from x;
select array(select v from x);

Anyway, I can't find where "array()" is documented. Google does find me a hit on stackexchange-dot-com. But it doesn't x-ref to the PG doc.

www.postgresql.org/docs/current/sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS

4.2.12. Array Constructors

It is also possible to construct an array from the results of a subquery. In this form, the array constructor is written with the key word ARRAY followed by a parenthesized (not bracketed) subquery. For example:

SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');

Thanks. I can't, even now, formulate a search that finds this—unless I know that it's a kind of array constructor. (I'll concede, with the benefit of hindsight, that I should have thought of that.) I hope that I'll be able to learn to navigate the PG docs better over time.

Why is the "array()" constructor not found in "pg_proc"? After all, section 4.2.12 refers to "array_agg()" as a constructor. And that *is* found in "pg_proc".

Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
"David G. Johnston"
Дата:
On Sunday, September 18, 2022, Bryn Llewellyn <bryn@yugabyte.com> wrote:
Why is the "array()" constructor not found in "pg_proc"?

Because it isn’t a function.
 

 After all, section 4.2.12 refers to "array_agg()" as a constructor. And that *is* found in "pg_proc".

I do not see this 4.2.12 reference you speak of.

David J.

Re: Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
Tom Lane
Дата:
Bryn Llewellyn <bryn@yugabyte.com> writes:
> Why is the "array()" constructor not found in "pg_proc"?

Because it isn't a function.  Yeah, it kind of looks like one,
but its argument is a subquery.  If SQL had first-class functions
and closures, maybe ARRAY() could be implemented as an ordinary
function.  But I don't see any plausible way to do that as things
stand.

There are a bunch of other things that look like functions but
aren't in pg_proc, too :-(.  Most of them are just catering to
the SQL committee's weird allergy to writing functions with
plain function syntax.  But ARRAY()'s problem is semantic not
syntactic.

            regards, tom lane



Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
Adrian Klaver
Дата:
On 9/18/22 21:20, Bryn Llewellyn wrote:

> 
> Thanks. I can't, even now, formulate a search that finds this—unless I 
> know that it's a kind of array constructor. (I'll concede, with the 
> benefit of hindsight, that I should have thought of that.) I hope that 
> I'll be able to learn to navigate the PG docs better over time.

The way I found it:

1) Use documentation search box.

2) Enter array(

3) It was in the fifth item PostgreSQL: Documentation: 14: 4.2. Value 
Expressions. The first four dealt with functions or the index and I knew 
they where not relevant.

> 
> Why is the "array()" constructor not found in "pg_proc"? After all, 
> section 4.2.12 refers to "array_agg()" as a constructor. And that *is* 
> found in "pg_proc".


The only place I see array_agg in 4.2.x is 4.2.7. Aggregate Expressions.

-- 
Adrian Klaver
adrian.klaver@aklaver.com



Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
Bryn Llewellyn
Дата:
> adrian.klaver@aklaver.com wrote:
>
> bryn@yugabyte.com wrote:
>
>> Thanks. I can't, even now, formulate a search that finds this—unless I know that it's a kind of array constructor.
(I'llconcede, with the benefit of hindsight, that I should have thought of that.) I hope that I'll be able to learn to
navigatethe PG docs better over time. 
>
> The way I found it:
>
> 1) Use documentation search box.
>
> 2) Enter array(
>
> 3) It was in the fifth item PostgreSQL: Documentation: 14: 4.2. Value Expressions. The first four dealt with
functionsor the index and I knew they where not relevant. 

I just repeated exactly those five search steps. I copied the first ten results at the end. Yes, the fifth hit is the
linkto where the account of the array() constructor is found. But you can't tell this from the hitlist itself. And
searchingin the page of the first twenty hits for "array(" finds nothing there. I do see that if you know the answer in
advance,then you could realize that hit #5 is what you want. But the wording "a specific element of the array value can
beextracted" didn't help me. 

Never mind, I trust that I'll remember where to look now.

--------------------------------------------------------------------------------

Result pages: 1 2 3 4 5 6 7 8 9 Next

1. PostgreSQL: Documentation: 14: 8.15. Arrays [8.21]
...Arrays Prev Up Chapter 8. Data Types Home Next 8.15. Arrays 8.15.1. Declaration of Array...
https://www.postgresql.org/docs/14/arrays.html

2. PostgreSQL: Documentation: 14: 9.19. Array Functions and Operators [5.04]
...Array Functions and Operators Prev Up Chapter 9. Functions and Operators Home Next 9.19. Array...
https://www.postgresql.org/docs/14/functions-array.html

3. PostgreSQL: Documentation: 14: 9.16. JSON Functions and Operators [4.25]
...array (array elements are indexed from zero, but negative integers count from the end).
'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json...
https://www.postgresql.org/docs/14/functions-json.html

4. PostgreSQL: Documentation: 14: Index [2.63]
...array, Arrays accessing, Accessing Arrays constant, Array Value Input constructor, Array Constructors declaration,
Declarationof Array... 
https://www.postgresql.org/docs/14/bookindex.html

5. PostgreSQL: Documentation: 14: 4.2. Value Expressions [2.27]
...array type, then a specific element of the array value can be extracted by writing...
https://www.postgresql.org/docs/14/sql-expressions.html

6. PostgreSQL: Documentation: 14: 8.14. JSON Types [1.76]
...array on the right side is not considered contained within the -- array on the left...
https://www.postgresql.org/docs/14/datatype-json.html

7. PostgreSQL: Documentation: 14: 66.3. Extensibility [1.33]
...array of operators and comparison values */ ScanKey orderbys; /* array of ordering operators and comparison *
values...
https://www.postgresql.org/docs/14/spgist-extensibility.html

8. PostgreSQL: Documentation: 14: F.18. intarray [1.33]
...arrays. Although they will accept input arrays of more dimensions, the data is treated as though...
https://www.postgresql.org/docs/14/intarray.html

9. PostgreSQL: Documentation: 14: CREATE TYPE [1.33]
...array type; for example, it will not be a candidate for the result type of ARRAY...
https://www.postgresql.org/docs/14/sql-createtype.html

10. PostgreSQL: Documentation: 14: 9.24. Row and Array Comparisons [1.15]
...Array Comparisons Prev Up Chapter 9. Functions and Operators Home Next 9.24. Row and Array...
https://www.postgresql.org/docs/14/functions-comparisons.html




Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
Bryn Llewellyn
Дата:
tgl@sss.pgh.pa.us wrote:

bryn@yugabyte.com wrote:

Why is the "array()" constructor not found in "pg_proc"?

Because it isn't a function. Yeah, it kind of looks like one, but its argument is a subquery. If SQL had first-class functions and closures, maybe ARRAY() could be implemented as an ordinary function. But I don't see any plausible way to do that as things stand.

There are a bunch of other things that look like functions but aren't in pg_proc, too :-(. Most of them are just catering to the SQL committee's weird allergy to writing functions with plain function syntax. But ARRAY()'s problem is semantic not syntactic.

There must be a significant difference between this:

  select 'dog'

and this:

  (select 'dog')

This works fine:

  select length( (select 'dog') )

But without the doubled parentheses, it causes a syntax error.

On the other hand, an extra pair of surrounding parentheses here

  select array( (values (17), (42)) )

while not necessary, *is* tolerated.

All this started because I had wrongly assumed that "pg_terminate_backend()" would have the same character as "array()" by not being subject to the "execute" privilege — just as is the case for all SQL built-ins in Oracle database, like "length()". I have a better mental model now.

Anyway, I know what to do in future. I'll simply look in pg_proc on a case-by-case basis.

Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
"David G. Johnston"
Дата:
On Mon, Sep 19, 2022 at 9:44 AM Bryn Llewellyn <bryn@yugabyte.com> wrote:

There must be a significant difference between this:

  select 'dog'

That isn't anything in particular (it is a command by itself, it can be a subquery in a FROM clause or the ARRAY() expression.

and this:

  (select 'dog')

That is a scalar subquery the produces exactly one row and one column that can be substituted in anyplace a single value is required.


This works fine:

  select length( (select 'dog') )

But without the doubled parentheses, it causes a syntax error.

Scalar subqueries are required to have surrounding parentheses.


"A scalar subquery is an ordinary SELECT query in parentheses that returns exactly one row with one column."


On the other hand, an extra pair of surrounding parentheses here

  select array( (values (17), (42)) )

while not necessary, *is* tolerated.

An actual subquery works here so the parentheses are grouping in nature and not an inherent part of the syntax.

David J.

Re: Re: Where's the doc for "array()" — as in "select array(values (17), (42))"

От
Tom Lane
Дата:
Bryn Llewellyn <bryn@yugabyte.com> writes:
> This works fine:
>   select length( (select 'dog') )
> But without the doubled parentheses, it causes a syntax error.

The parens are required for it to be a valid scalar subquery, as per
https://www.postgresql.org/docs/current/sql-expressions.html#SQL-SYNTAX-SCALAR-SUBQUERIES

The reason ARRAY() is different is exactly that its argument is
directly a subquery, not an expression that chances to be a
scalar subquery.

> On the other hand, an extra pair of surrounding parentheses here
>   select array( (values (17), (42)) )
> while not necessary, *is* tolerated.

You can pretty much always add *extra* parens in any expression
context.

            regards, tom lane