2017-03-12 00:36:50 +01:00
|
|
|
--
|
2019-07-06 05:56:34 +02:00
|
|
|
-- expression evaluation tests that don't fit into a more specific file
|
2017-03-12 00:36:50 +01:00
|
|
|
--
|
|
|
|
--
|
2023-05-17 03:19:17 +02:00
|
|
|
-- Tests for SQLValueFunction
|
2017-03-12 00:36:50 +01:00
|
|
|
--
|
|
|
|
-- current_date (always matches because of transactional behaviour)
|
|
|
|
SELECT date(now())::text = current_date::text;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- current_time / localtime
|
|
|
|
SELECT now()::timetz::text = current_time::text;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2019-07-06 05:56:34 +02:00
|
|
|
SELECT now()::timetz(4)::text = current_time(4)::text;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2017-03-12 00:36:50 +01:00
|
|
|
SELECT now()::time::text = localtime::text;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2019-07-06 05:56:34 +02:00
|
|
|
SELECT now()::time(3)::text = localtime(3)::text;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2022-12-30 12:47:57 +01:00
|
|
|
-- current_time[stamp]/ localtime[stamp] (always matches because of transactional behaviour)
|
2017-03-12 00:36:50 +01:00
|
|
|
SELECT current_timestamp = NOW();
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- precision
|
|
|
|
SELECT length(current_timestamp::text) >= length(current_timestamp(0)::text);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- localtimestamp
|
|
|
|
SELECT now()::timestamp::text = localtimestamp::text;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2022-12-30 12:47:57 +01:00
|
|
|
-- precision overflow
|
|
|
|
SELECT current_time = current_time(7);
|
|
|
|
WARNING: TIME(7) WITH TIME ZONE precision reduced to maximum allowed, 6
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT current_timestamp = current_timestamp(7);
|
|
|
|
WARNING: TIMESTAMP(7) WITH TIME ZONE precision reduced to maximum allowed, 6
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT localtime = localtime(7);
|
|
|
|
WARNING: TIME(7) precision reduced to maximum allowed, 6
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT localtimestamp = localtimestamp(7);
|
|
|
|
WARNING: TIMESTAMP(7) precision reduced to maximum allowed, 6
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2023-01-03 08:26:14 +01:00
|
|
|
-- current_role/user/user is tested in rolenames.sql
|
2017-03-12 00:36:50 +01:00
|
|
|
-- current database / catalog
|
|
|
|
SELECT current_catalog = current_database();
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- current_schema
|
|
|
|
SELECT current_schema;
|
|
|
|
current_schema
|
|
|
|
----------------
|
|
|
|
public
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SET search_path = 'notme';
|
|
|
|
SELECT current_schema;
|
|
|
|
current_schema
|
|
|
|
----------------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SET search_path = 'pg_catalog';
|
|
|
|
SELECT current_schema;
|
|
|
|
current_schema
|
|
|
|
----------------
|
|
|
|
pg_catalog
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
RESET search_path;
|
Don't elide casting to typmod -1.
Casting a value that's already of a type with a specific typmod
to an unspecified typmod doesn't do anything so far as run-time
behavior is concerned. However, it really ought to change the
exposed type of the expression to match. Up to now,
coerce_type_typmod hasn't bothered with that, which creates gotchas
in contexts such as recursive unions. If for example one side of
the union is numeric(18,3), but it needs to be plain numeric to
match the other side, there's no direct way to express that.
This is easy enough to fix, by inserting a RelabelType to update the
exposed type of the expression. However, it's a bit nervous-making
to change this behavior, because it's stood for a really long time.
(I strongly suspect that it's like this in part because the logic
pre-dates the introduction of RelabelType in 7.0. The commit log
message for 57b30e8e2 is interesting reading here.) As a compromise,
we'll sneak the change into 14beta3, and consider back-patching to
stable branches if no complaints emerge in the next three months.
Discussion: https://postgr.es/m/CABNQVagu3bZGqiTjb31a8D5Od3fUMs7Oh3gmZMQZVHZ=uWWWfQ@mail.gmail.com
2021-08-06 23:32:54 +02:00
|
|
|
--
|
|
|
|
-- Test parsing of a no-op cast to a type with unspecified typmod
|
|
|
|
--
|
|
|
|
begin;
|
|
|
|
create table numeric_tbl (f1 numeric(18,3), f2 numeric);
|
|
|
|
create view numeric_view as
|
|
|
|
select
|
|
|
|
f1, f1::numeric(16,4) as f1164, f1::numeric as f1n,
|
|
|
|
f2, f2::numeric(16,4) as f2164, f2::numeric as f2n
|
|
|
|
from numeric_tbl;
|
|
|
|
\d+ numeric_view
|
|
|
|
View "public.numeric_view"
|
|
|
|
Column | Type | Collation | Nullable | Default | Storage | Description
|
|
|
|
--------+---------------+-----------+----------+---------+---------+-------------
|
|
|
|
f1 | numeric(18,3) | | | | main |
|
|
|
|
f1164 | numeric(16,4) | | | | main |
|
|
|
|
f1n | numeric | | | | main |
|
|
|
|
f2 | numeric | | | | main |
|
|
|
|
f2164 | numeric(16,4) | | | | main |
|
|
|
|
f2n | numeric | | | | main |
|
|
|
|
View definition:
|
2023-01-18 19:23:57 +01:00
|
|
|
SELECT f1,
|
|
|
|
f1::numeric(16,4) AS f1164,
|
|
|
|
f1::numeric AS f1n,
|
|
|
|
f2,
|
|
|
|
f2::numeric(16,4) AS f2164,
|
|
|
|
f2 AS f2n
|
Don't elide casting to typmod -1.
Casting a value that's already of a type with a specific typmod
to an unspecified typmod doesn't do anything so far as run-time
behavior is concerned. However, it really ought to change the
exposed type of the expression to match. Up to now,
coerce_type_typmod hasn't bothered with that, which creates gotchas
in contexts such as recursive unions. If for example one side of
the union is numeric(18,3), but it needs to be plain numeric to
match the other side, there's no direct way to express that.
This is easy enough to fix, by inserting a RelabelType to update the
exposed type of the expression. However, it's a bit nervous-making
to change this behavior, because it's stood for a really long time.
(I strongly suspect that it's like this in part because the logic
pre-dates the introduction of RelabelType in 7.0. The commit log
message for 57b30e8e2 is interesting reading here.) As a compromise,
we'll sneak the change into 14beta3, and consider back-patching to
stable branches if no complaints emerge in the next three months.
Discussion: https://postgr.es/m/CABNQVagu3bZGqiTjb31a8D5Od3fUMs7Oh3gmZMQZVHZ=uWWWfQ@mail.gmail.com
2021-08-06 23:32:54 +02:00
|
|
|
FROM numeric_tbl;
|
|
|
|
|
|
|
|
explain (verbose, costs off) select * from numeric_view;
|
|
|
|
QUERY PLAN
|
|
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
Seq Scan on public.numeric_tbl
|
|
|
|
Output: numeric_tbl.f1, (numeric_tbl.f1)::numeric(16,4), (numeric_tbl.f1)::numeric, numeric_tbl.f2, (numeric_tbl.f2)::numeric(16,4), numeric_tbl.f2
|
|
|
|
(2 rows)
|
|
|
|
|
2021-12-16 21:36:02 +01:00
|
|
|
-- bpchar, lacking planner support for its length coercion function,
|
|
|
|
-- could behave differently
|
|
|
|
create table bpchar_tbl (f1 character(16) unique, f2 bpchar);
|
|
|
|
create view bpchar_view as
|
|
|
|
select
|
|
|
|
f1, f1::character(14) as f114, f1::bpchar as f1n,
|
|
|
|
f2, f2::character(14) as f214, f2::bpchar as f2n
|
|
|
|
from bpchar_tbl;
|
|
|
|
\d+ bpchar_view
|
|
|
|
View "public.bpchar_view"
|
|
|
|
Column | Type | Collation | Nullable | Default | Storage | Description
|
|
|
|
--------+---------------+-----------+----------+---------+----------+-------------
|
|
|
|
f1 | character(16) | | | | extended |
|
|
|
|
f114 | character(14) | | | | extended |
|
|
|
|
f1n | bpchar | | | | extended |
|
|
|
|
f2 | bpchar | | | | extended |
|
|
|
|
f214 | character(14) | | | | extended |
|
|
|
|
f2n | bpchar | | | | extended |
|
|
|
|
View definition:
|
2023-01-18 19:23:57 +01:00
|
|
|
SELECT f1,
|
|
|
|
f1::character(14) AS f114,
|
|
|
|
f1::bpchar AS f1n,
|
|
|
|
f2,
|
|
|
|
f2::character(14) AS f214,
|
|
|
|
f2 AS f2n
|
2021-12-16 21:36:02 +01:00
|
|
|
FROM bpchar_tbl;
|
|
|
|
|
|
|
|
explain (verbose, costs off) select * from bpchar_view
|
|
|
|
where f1::bpchar = 'foo';
|
|
|
|
QUERY PLAN
|
|
|
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
Index Scan using bpchar_tbl_f1_key on public.bpchar_tbl
|
|
|
|
Output: bpchar_tbl.f1, (bpchar_tbl.f1)::character(14), (bpchar_tbl.f1)::bpchar, bpchar_tbl.f2, (bpchar_tbl.f2)::character(14), bpchar_tbl.f2
|
|
|
|
Index Cond: ((bpchar_tbl.f1)::bpchar = 'foo'::bpchar)
|
|
|
|
(3 rows)
|
|
|
|
|
Don't elide casting to typmod -1.
Casting a value that's already of a type with a specific typmod
to an unspecified typmod doesn't do anything so far as run-time
behavior is concerned. However, it really ought to change the
exposed type of the expression to match. Up to now,
coerce_type_typmod hasn't bothered with that, which creates gotchas
in contexts such as recursive unions. If for example one side of
the union is numeric(18,3), but it needs to be plain numeric to
match the other side, there's no direct way to express that.
This is easy enough to fix, by inserting a RelabelType to update the
exposed type of the expression. However, it's a bit nervous-making
to change this behavior, because it's stood for a really long time.
(I strongly suspect that it's like this in part because the logic
pre-dates the introduction of RelabelType in 7.0. The commit log
message for 57b30e8e2 is interesting reading here.) As a compromise,
we'll sneak the change into 14beta3, and consider back-patching to
stable branches if no complaints emerge in the next three months.
Discussion: https://postgr.es/m/CABNQVagu3bZGqiTjb31a8D5Od3fUMs7Oh3gmZMQZVHZ=uWWWfQ@mail.gmail.com
2021-08-06 23:32:54 +02:00
|
|
|
rollback;
|
2021-04-08 13:51:22 +02:00
|
|
|
--
|
Fix failure to validate the result of select_common_type().
Although select_common_type() has a failure-return convention, an
apparent successful return just provides a type OID that *might* work
as a common supertype; we've not validated that the required casts
actually exist. In the mainstream use-cases that doesn't matter,
because we'll proceed to invoke coerce_to_common_type() on each input,
which will fail appropriately if the proposed common type doesn't
actually work. However, a few callers didn't read the (nonexistent)
fine print, and thought that if they got back a nonzero OID then the
coercions were sure to work.
This affects in particular the recently-added "anycompatible"
polymorphic types; we might think that a function/operator using
such types matches cases it really doesn't. A likely end result
of that is unexpected "ambiguous operator" errors, as for example
in bug #17387 from James Inform. Another, much older, case is that
the parser might try to transform an "x IN (list)" construct to
a ScalarArrayOpExpr even when the list elements don't actually have
a common supertype.
It doesn't seem desirable to add more checking to select_common_type
itself, as that'd just slow down the mainstream use-cases. Instead,
write a separate function verify_common_type that performs the
missing checks, and add a call to that where necessary. Likewise add
verify_common_type_from_oids to go with select_common_type_from_oids.
Back-patch to v13 where the "anycompatible" types came in. (The
symptom complained of in bug #17387 doesn't appear till v14, but
that's just because we didn't get around to converting || to use
anycompatible till then.) In principle the "x IN (list)" fix could
go back all the way, but I'm not currently convinced that it makes
much difference in real-world cases, so I won't bother for now.
Discussion: https://postgr.es/m/17387-5dfe54b988444963@postgresql.org
2022-01-29 17:41:12 +01:00
|
|
|
-- Ordinarily, IN/NOT IN can be converted to a ScalarArrayOpExpr
|
|
|
|
-- with a suitably-chosen array type.
|
|
|
|
--
|
|
|
|
explain (verbose, costs off)
|
|
|
|
select random() IN (1, 4, 8.0);
|
|
|
|
QUERY PLAN
|
|
|
|
------------------------------------------------------------
|
|
|
|
Result
|
|
|
|
Output: (random() = ANY ('{1,4,8}'::double precision[]))
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
explain (verbose, costs off)
|
|
|
|
select random()::int IN (1, 4, 8.0);
|
|
|
|
QUERY PLAN
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
Result
|
|
|
|
Output: (((random())::integer)::numeric = ANY ('{1,4,8.0}'::numeric[]))
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
-- However, if there's not a common supertype for the IN elements,
|
|
|
|
-- we should instead try to produce "x = v1 OR x = v2 OR ...".
|
|
|
|
-- In most cases that'll fail for lack of all the requisite = operators,
|
|
|
|
-- but it can succeed sometimes. So this should complain about lack of
|
|
|
|
-- an = operator, not about cast failure.
|
|
|
|
select '(0,0)'::point in ('(0,0,0,0)'::box, point(0,0));
|
|
|
|
ERROR: operator does not exist: point = box
|
|
|
|
LINE 1: select '(0,0)'::point in ('(0,0,0,0)'::box, point(0,0));
|
|
|
|
^
|
|
|
|
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
--
|
2021-04-08 13:51:22 +02:00
|
|
|
-- Tests for ScalarArrayOpExpr with a hashfn
|
|
|
|
--
|
|
|
|
-- create a stable function so that the tests below are not
|
|
|
|
-- evaluated using the planner's constant folding.
|
|
|
|
begin;
|
|
|
|
create function return_int_input(int) returns int as $$
|
|
|
|
begin
|
|
|
|
return $1;
|
|
|
|
end;
|
|
|
|
$$ language plpgsql stable;
|
|
|
|
create function return_text_input(text) returns text as $$
|
|
|
|
begin
|
|
|
|
return $1;
|
|
|
|
end;
|
|
|
|
$$ language plpgsql stable;
|
|
|
|
select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, null);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(1) in (null, null, null, null, null, null, null, null, null, null, null);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, null);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(null::int) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(null::int) in (10, 9, 2, 8, 3, 7, 4, 6, 5, null);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_text_input('a') in ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j');
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2021-07-07 06:29:17 +02:00
|
|
|
-- NOT IN
|
|
|
|
select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 0);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 2, null);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, null);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(1) not in (null, null, null, null, null, null, null, null, null, null, null);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(null::int) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_int_input(null::int) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, null);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select return_text_input('a') not in ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j');
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
2021-04-08 13:51:22 +02:00
|
|
|
rollback;
|
|
|
|
-- Test with non-strict equality function.
|
|
|
|
-- We need to create our own type for this.
|
|
|
|
begin;
|
|
|
|
create type myint;
|
|
|
|
create function myintin(cstring) returns myint strict immutable language
|
|
|
|
internal as 'int4in';
|
|
|
|
NOTICE: return type myint is only a shell
|
|
|
|
create function myintout(myint) returns cstring strict immutable language
|
|
|
|
internal as 'int4out';
|
|
|
|
NOTICE: argument type myint is only a shell
|
|
|
|
create function myinthash(myint) returns integer strict immutable language
|
|
|
|
internal as 'hashint4';
|
|
|
|
NOTICE: argument type myint is only a shell
|
|
|
|
create type myint (input = myintin, output = myintout, like = int4);
|
|
|
|
create cast (int4 as myint) without function;
|
|
|
|
create cast (myint as int4) without function;
|
|
|
|
create function myinteq(myint, myint) returns bool as $$
|
|
|
|
begin
|
|
|
|
if $1 is null and $2 is null then
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return $1::int = $2::int;
|
|
|
|
end if;
|
|
|
|
end;
|
|
|
|
$$ language plpgsql immutable;
|
2021-07-07 06:29:17 +02:00
|
|
|
create function myintne(myint, myint) returns bool as $$
|
|
|
|
begin
|
|
|
|
return not myinteq($1, $2);
|
|
|
|
end;
|
|
|
|
$$ language plpgsql immutable;
|
2021-04-08 13:51:22 +02:00
|
|
|
create operator = (
|
|
|
|
leftarg = myint,
|
|
|
|
rightarg = myint,
|
|
|
|
commutator = =,
|
|
|
|
negator = <>,
|
|
|
|
procedure = myinteq,
|
|
|
|
restrict = eqsel,
|
|
|
|
join = eqjoinsel,
|
|
|
|
merges
|
|
|
|
);
|
2021-07-07 06:29:17 +02:00
|
|
|
create operator <> (
|
|
|
|
leftarg = myint,
|
|
|
|
rightarg = myint,
|
|
|
|
commutator = <>,
|
|
|
|
negator = =,
|
|
|
|
procedure = myintne,
|
|
|
|
restrict = eqsel,
|
|
|
|
join = eqjoinsel,
|
|
|
|
merges
|
|
|
|
);
|
2021-04-08 13:51:22 +02:00
|
|
|
create operator class myint_ops
|
|
|
|
default for type myint using hash as
|
|
|
|
operator 1 = (myint, myint),
|
|
|
|
function 1 myinthash(myint);
|
|
|
|
create table inttest (a myint);
|
|
|
|
insert into inttest values(1::myint),(null);
|
|
|
|
-- try an array with enough elements to cause hashing
|
|
|
|
select * from inttest where a in (1::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null);
|
|
|
|
a
|
|
|
|
---
|
|
|
|
1
|
|
|
|
|
|
|
|
(2 rows)
|
|
|
|
|
2021-07-07 06:29:17 +02:00
|
|
|
select * from inttest where a not in (1::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null);
|
|
|
|
a
|
|
|
|
---
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
select * from inttest where a not in (0::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null);
|
|
|
|
a
|
|
|
|
---
|
|
|
|
(0 rows)
|
|
|
|
|
2021-04-08 13:51:22 +02:00
|
|
|
-- ensure the result matched with the non-hashed version. We simply remove
|
|
|
|
-- some array elements so that we don't reach the hashing threshold.
|
|
|
|
select * from inttest where a in (1::myint,2::myint,3::myint,4::myint,5::myint, null);
|
|
|
|
a
|
|
|
|
---
|
|
|
|
1
|
|
|
|
|
|
|
|
(2 rows)
|
|
|
|
|
2021-07-07 06:29:17 +02:00
|
|
|
select * from inttest where a not in (1::myint,2::myint,3::myint,4::myint,5::myint, null);
|
|
|
|
a
|
|
|
|
---
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
select * from inttest where a not in (0::myint,2::myint,3::myint,4::myint,5::myint, null);
|
|
|
|
a
|
|
|
|
---
|
|
|
|
(0 rows)
|
|
|
|
|
2021-04-08 13:51:22 +02:00
|
|
|
rollback;
|