2016-02-04 23:03:10 -05:00
|
|
|
--
|
|
|
|
|
-- num_nulls()
|
|
|
|
|
--
|
|
|
|
|
|
|
|
|
|
SELECT num_nonnulls(NULL);
|
|
|
|
|
SELECT num_nonnulls('1');
|
|
|
|
|
SELECT num_nonnulls(NULL::text);
|
|
|
|
|
SELECT num_nonnulls(NULL::text, NULL::int);
|
|
|
|
|
SELECT num_nonnulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL);
|
|
|
|
|
SELECT num_nonnulls(VARIADIC '{1,2,NULL,3}'::int[]);
|
|
|
|
|
SELECT num_nonnulls(VARIADIC '{"1","2","3","4"}'::text[]);
|
|
|
|
|
SELECT num_nonnulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i));
|
|
|
|
|
|
|
|
|
|
SELECT num_nulls(NULL);
|
|
|
|
|
SELECT num_nulls('1');
|
|
|
|
|
SELECT num_nulls(NULL::text);
|
|
|
|
|
SELECT num_nulls(NULL::text, NULL::int);
|
|
|
|
|
SELECT num_nulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL);
|
|
|
|
|
SELECT num_nulls(VARIADIC '{1,2,NULL,3}'::int[]);
|
|
|
|
|
SELECT num_nulls(VARIADIC '{"1","2","3","4"}'::text[]);
|
|
|
|
|
SELECT num_nulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i));
|
|
|
|
|
|
|
|
|
|
-- special cases
|
|
|
|
|
SELECT num_nonnulls(VARIADIC NULL::text[]);
|
|
|
|
|
SELECT num_nonnulls(VARIADIC '{}'::int[]);
|
|
|
|
|
SELECT num_nulls(VARIADIC NULL::text[]);
|
|
|
|
|
SELECT num_nulls(VARIADIC '{}'::int[]);
|
|
|
|
|
|
|
|
|
|
-- should fail, one or more arguments is required
|
|
|
|
|
SELECT num_nonnulls();
|
|
|
|
|
SELECT num_nulls();
|
2019-02-09 18:32:23 -05:00
|
|
|
|
Avoid holding a directory FD open across pg_ls_dir_files() calls.
This coding technique is undesirable because (a) it leaks the FD for
the rest of the transaction if the SRF is not run to completion, and
(b) allocated FDs are a scarce resource, but multiple interleaved
uses of the relevant functions could eat many such FDs.
In v11 and later, a query such as "SELECT pg_ls_waldir() LIMIT 1"
yields a warning about the leaked FD, and the only reason there's
no warning in earlier branches is that fd.c didn't whine about such
leaks before commit 9cb7db3f0. Even disregarding the warning, it
wouldn't be too hard to run a backend out of FDs with careless use
of these SQL functions.
Hence, rewrite the function so that it reads the directory within
a single call, returning the results as a tuplestore rather than
via value-per-call mode.
There are half a dozen other built-in SRFs with similar problems,
but let's fix this one to start with, just to see if the buildfarm
finds anything wrong with the code.
In passing, fix bogus error report for stat() failure: it was
whining about the directory when it should be fingering the
individual file. Doubtless a copy-and-paste error.
Back-patch to v10 where this function was added.
Justin Pryzby, with cosmetic tweaks and test cases by me
Discussion: https://postgr.es/m/20200308173103.GC1357@telsasoft.com
2020-03-11 15:27:59 -04:00
|
|
|
--
|
|
|
|
|
-- Test some built-in SRFs
|
|
|
|
|
--
|
|
|
|
|
-- The outputs of these are variable, so we can't just print their results
|
|
|
|
|
-- directly, but we can at least verify that the code doesn't fail.
|
|
|
|
|
--
|
|
|
|
|
select setting as segsize
|
|
|
|
|
from pg_settings where name = 'wal_segment_size'
|
|
|
|
|
\gset
|
|
|
|
|
|
|
|
|
|
select count(*) > 0 as ok from pg_ls_waldir();
|
|
|
|
|
-- Test ProjectSet as well as FunctionScan
|
|
|
|
|
select count(*) > 0 as ok from (select pg_ls_waldir()) ss;
|
|
|
|
|
-- Test not-run-to-completion cases.
|
|
|
|
|
select * from pg_ls_waldir() limit 0;
|
|
|
|
|
select count(*) > 0 as ok from (select * from pg_ls_waldir() limit 1) ss;
|
2020-03-11 18:23:57 -04:00
|
|
|
select (w).size = :segsize as ok
|
|
|
|
|
from (select pg_ls_waldir() w) ss where length((w).name) = 24 limit 1;
|
Avoid holding a directory FD open across pg_ls_dir_files() calls.
This coding technique is undesirable because (a) it leaks the FD for
the rest of the transaction if the SRF is not run to completion, and
(b) allocated FDs are a scarce resource, but multiple interleaved
uses of the relevant functions could eat many such FDs.
In v11 and later, a query such as "SELECT pg_ls_waldir() LIMIT 1"
yields a warning about the leaked FD, and the only reason there's
no warning in earlier branches is that fd.c didn't whine about such
leaks before commit 9cb7db3f0. Even disregarding the warning, it
wouldn't be too hard to run a backend out of FDs with careless use
of these SQL functions.
Hence, rewrite the function so that it reads the directory within
a single call, returning the results as a tuplestore rather than
via value-per-call mode.
There are half a dozen other built-in SRFs with similar problems,
but let's fix this one to start with, just to see if the buildfarm
finds anything wrong with the code.
In passing, fix bogus error report for stat() failure: it was
whining about the directory when it should be fingering the
individual file. Doubtless a copy-and-paste error.
Back-patch to v10 where this function was added.
Justin Pryzby, with cosmetic tweaks and test cases by me
Discussion: https://postgr.es/m/20200308173103.GC1357@telsasoft.com
2020-03-11 15:27:59 -04:00
|
|
|
|
|
|
|
|
select count(*) >= 0 as ok from pg_ls_archive_statusdir();
|
|
|
|
|
|
2020-03-16 21:05:28 -04:00
|
|
|
select * from (select pg_ls_dir('.') a) a where a = 'base' limit 1;
|
|
|
|
|
|
|
|
|
|
select * from (select (pg_timezone_names()).name) ptn where name='UTC' limit 1;
|
|
|
|
|
|
|
|
|
|
select count(*) > 0 from
|
|
|
|
|
(select pg_tablespace_databases(oid) as pts from pg_tablespace
|
|
|
|
|
where spcname = 'pg_default') pts
|
|
|
|
|
join pg_database db on pts.pts = db.oid;
|
|
|
|
|
|
2019-02-09 18:32:23 -05:00
|
|
|
--
|
|
|
|
|
-- Test adding a support function to a subject function
|
|
|
|
|
--
|
|
|
|
|
|
|
|
|
|
CREATE FUNCTION my_int_eq(int, int) RETURNS bool
|
|
|
|
|
LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE
|
|
|
|
|
AS $$int4eq$$;
|
|
|
|
|
|
|
|
|
|
-- By default, planner does not think that's selective
|
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
|
|
|
SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1
|
|
|
|
|
WHERE my_int_eq(a.unique2, 42);
|
|
|
|
|
|
|
|
|
|
-- With support function that knows it's int4eq, we get a different plan
|
|
|
|
|
ALTER FUNCTION my_int_eq(int, int) SUPPORT test_support_func;
|
|
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
|
|
|
SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1
|
|
|
|
|
WHERE my_int_eq(a.unique2, 42);
|
|
|
|
|
|
|
|
|
|
-- Also test non-default rowcount estimate
|
|
|
|
|
CREATE FUNCTION my_gen_series(int, int) RETURNS SETOF integer
|
|
|
|
|
LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE
|
|
|
|
|
AS $$generate_series_int4$$
|
|
|
|
|
SUPPORT test_support_func;
|
|
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
|
|
|
SELECT * FROM tenk1 a JOIN my_gen_series(1,1000) g ON a.unique1 = g;
|
|
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
|
|
|
SELECT * FROM tenk1 a JOIN my_gen_series(1,10) g ON a.unique1 = g;
|