+++ /dev/null
---
--- AGGREGATES
---
-SELECT avg(four) AS avg_1 FROM onek;
- avg_1
---------------------
- 1.5000000000000000
-(1 row)
-
-SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100;
- avg_32
----------------------
- 32.6666666666666667
-(1 row)
-
--- In 7.1, avg(float4) is computed using float8 arithmetic.
--- Round the result to 3 digits to avoid platform-specific results.
-SELECT avg(b)::numeric(10,3) AS avg_107_943 FROM aggtest;
- avg_107_943
--------------
- 107.943
-(1 row)
-
-SELECT avg(gpa) AS avg_3_4 FROM ONLY student;
- avg_3_4
----------
- 3.4
-(1 row)
-
-SELECT sum(four) AS sum_1500 FROM onek;
- sum_1500
-----------
- 1500
-(1 row)
-
-SELECT sum(a) AS sum_198 FROM aggtest;
- sum_198
----------
- 198
-(1 row)
-
-SELECT sum(b) AS avg_431_773 FROM aggtest;
- avg_431_773
--------------
- 431.773
-(1 row)
-
-SELECT sum(gpa) AS avg_6_8 FROM ONLY student;
- avg_6_8
----------
- 6.8
-(1 row)
-
-SELECT max(four) AS max_3 FROM onek;
- max_3
--------
- 3
-(1 row)
-
-SELECT max(a) AS max_100 FROM aggtest;
- max_100
----------
- 100
-(1 row)
-
-SELECT max(aggtest.b) AS max_324_78 FROM aggtest;
- max_324_78
-------------
- 324.78
-(1 row)
-
-SELECT max(student.gpa) AS max_3_7 FROM student;
- max_3_7
----------
- 3.7
-(1 row)
-
-SELECT stddev_pop(b) FROM aggtest;
- stddev_pop
-------------------
- 131.107032318951
-(1 row)
-
-SELECT stddev_samp(b) FROM aggtest;
- stddev_samp
-------------------
- 151.389360803998
-(1 row)
-
-SELECT var_pop(b) FROM aggtest;
- var_pop
-------------------
- 17189.0539234824
-(1 row)
-
-SELECT var_samp(b) FROM aggtest;
- var_samp
-------------------
- 22918.7385646432
-(1 row)
-
-SELECT stddev_pop(b::numeric) FROM aggtest;
- stddev_pop
-------------------
- 131.107032862199
-(1 row)
-
-SELECT stddev_samp(b::numeric) FROM aggtest;
- stddev_samp
-------------------
- 151.389361431288
-(1 row)
-
-SELECT var_pop(b::numeric) FROM aggtest;
- var_pop
---------------------
- 17189.054065929769
-(1 row)
-
-SELECT var_samp(b::numeric) FROM aggtest;
- var_samp
---------------------
- 22918.738754573025
-(1 row)
-
--- population variance is defined for a single tuple, sample variance
--- is not
-SELECT var_pop(1.0), var_samp(2.0);
- var_pop | var_samp
----------+----------
- 0 |
-(1 row)
-
-SELECT stddev_pop(3.0::numeric), stddev_samp(4.0::numeric);
- stddev_pop | stddev_samp
-------------+-------------
- 0 |
-(1 row)
-
--- verify correct results for null and NaN inputs
-select sum(null::int4) from generate_series(1,3);
- sum
------
-
-(1 row)
-
-select sum(null::int8) from generate_series(1,3);
- sum
------
-
-(1 row)
-
-select sum(null::numeric) from generate_series(1,3);
- sum
------
-
-(1 row)
-
-select sum(null::float8) from generate_series(1,3);
- sum
------
-
-(1 row)
-
-select avg(null::int4) from generate_series(1,3);
- avg
------
-
-(1 row)
-
-select avg(null::int8) from generate_series(1,3);
- avg
------
-
-(1 row)
-
-select avg(null::numeric) from generate_series(1,3);
- avg
------
-
-(1 row)
-
-select avg(null::float8) from generate_series(1,3);
- avg
------
-
-(1 row)
-
-select sum('NaN'::numeric) from generate_series(1,3);
- sum
------
- NaN
-(1 row)
-
-select avg('NaN'::numeric) from generate_series(1,3);
- avg
------
- NaN
-(1 row)
-
--- SQL2003 binary aggregates
-SELECT regr_count(b, a) FROM aggtest;
- regr_count
-------------
- 4
-(1 row)
-
-SELECT regr_sxx(b, a) FROM aggtest;
- regr_sxx
-----------
- 5099
-(1 row)
-
-SELECT regr_syy(b, a) FROM aggtest;
- regr_syy
-------------------
- 68756.2156939297
-(1 row)
-
-SELECT regr_sxy(b, a) FROM aggtest;
- regr_sxy
-------------------
- 2614.51582155001
-(1 row)
-
-SELECT regr_avgx(b, a), regr_avgy(b, a) FROM aggtest;
- regr_avgx | regr_avgy
------------+------------------
- 49.5 | 107.943152273074
-(1 row)
-
-SELECT regr_r2(b, a) FROM aggtest;
- regr_r2
---------------------
- 0.0194977982031796
-(1 row)
-
-SELECT regr_slope(b, a), regr_intercept(b, a) FROM aggtest;
- regr_slope | regr_intercept
--------------------+------------------
- 0.512750700441265 | 82.5619926012313
-(1 row)
-
-SELECT covar_pop(b, a), covar_samp(b, a) FROM aggtest;
- covar_pop | covar_samp
-------------------+------------------
- 653.628955387502 | 871.505273850003
-(1 row)
-
-SELECT corr(b, a) FROM aggtest;
- corr
--------------------
- 0.139634516517871
-(1 row)
-
-SELECT count(four) AS cnt_1000 FROM onek;
- cnt_1000
-----------
- 1000
-(1 row)
-
-SELECT count(DISTINCT four) AS cnt_4 FROM onek;
- cnt_4
--------
- 4
-(1 row)
-
-select ten, count(*), sum(four) from onek
-group by ten order by ten;
- ten | count | sum
------+-------+-----
- 0 | 100 | 100
- 1 | 100 | 200
- 2 | 100 | 100
- 3 | 100 | 200
- 4 | 100 | 100
- 5 | 100 | 200
- 6 | 100 | 100
- 7 | 100 | 200
- 8 | 100 | 100
- 9 | 100 | 200
-(10 rows)
-
-select ten, count(four), sum(DISTINCT four) from onek
-group by ten order by ten;
- ten | count | sum
------+-------+-----
- 0 | 100 | 2
- 1 | 100 | 4
- 2 | 100 | 2
- 3 | 100 | 4
- 4 | 100 | 2
- 5 | 100 | 4
- 6 | 100 | 2
- 7 | 100 | 4
- 8 | 100 | 2
- 9 | 100 | 4
-(10 rows)
-
--- user-defined aggregates
-SELECT newavg(four) AS avg_1 FROM onek;
- avg_1
---------------------
- 1.5000000000000000
-(1 row)
-
-SELECT newsum(four) AS sum_1500 FROM onek;
- sum_1500
-----------
- 1500
-(1 row)
-
-SELECT newcnt(four) AS cnt_1000 FROM onek;
- cnt_1000
-----------
- 1000
-(1 row)
-
-SELECT newcnt(*) AS cnt_1000 FROM onek;
- cnt_1000
-----------
- 1000
-(1 row)
-
-SELECT oldcnt(*) AS cnt_1000 FROM onek;
- cnt_1000
-----------
- 1000
-(1 row)
-
-SELECT sum2(q1,q2) FROM int8_tbl;
- sum2
--------------------
- 18271560493827981
-(1 row)
-
--- test for outer-level aggregates
--- this should work
-select ten, sum(distinct four) from onek a
-group by ten
-having exists (select 1 from onek b where sum(distinct a.four) = b.four)
-order by ten;
- ten | sum
------+-----
- 0 | 2
- 2 | 2
- 4 | 2
- 6 | 2
- 8 | 2
-(5 rows)
-
--- this should fail because subquery has an agg of its own in WHERE
-select ten, sum(distinct four) from onek a
-group by ten
-having exists (select 1 from onek b
- where sum(distinct a.four + b.four) = b.four);
-ERROR: aggregate functions are not allowed in WHERE
-LINE 4: where sum(distinct a.four + b.four) = b.four)...
- ^
--- Test handling of sublinks within outer-level aggregates.
--- Per bug report from Daniel Grace.
-select
- (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)))
-from tenk1 o;
- max
-------
- 9999
-(1 row)
-
---
--- test for bitwise integer aggregates
---
-CREATE TEMPORARY TABLE bitwise_test(
- i2 INT2,
- i4 INT4,
- i8 INT8,
- i INTEGER,
- x INT2,
- y BIT(4)
-);
--- empty case
-SELECT
- BIT_AND(i2) AS "?",
- BIT_OR(i4) AS "?"
-FROM bitwise_test;
- ? | ?
----+---
- |
-(1 row)
-
-COPY bitwise_test FROM STDIN NULL 'null';
-SELECT
- BIT_AND(i2) AS "1",
- BIT_AND(i4) AS "1",
- BIT_AND(i8) AS "1",
- BIT_AND(i) AS "?",
- BIT_AND(x) AS "0",
- BIT_AND(y) AS "0100",
- BIT_OR(i2) AS "7",
- BIT_OR(i4) AS "7",
- BIT_OR(i8) AS "7",
- BIT_OR(i) AS "?",
- BIT_OR(x) AS "7",
- BIT_OR(y) AS "1101"
-FROM bitwise_test;
- 1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101
----+---+---+---+---+------+---+---+---+---+---+------
- 1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101
-(1 row)
-
---
--- test boolean aggregates
---
--- first test all possible transition and final states
-SELECT
- -- boolean and transitions
- -- null because strict
- booland_statefunc(NULL, NULL) IS NULL AS "t",
- booland_statefunc(TRUE, NULL) IS NULL AS "t",
- booland_statefunc(FALSE, NULL) IS NULL AS "t",
- booland_statefunc(NULL, TRUE) IS NULL AS "t",
- booland_statefunc(NULL, FALSE) IS NULL AS "t",
- -- and actual computations
- booland_statefunc(TRUE, TRUE) AS "t",
- NOT booland_statefunc(TRUE, FALSE) AS "t",
- NOT booland_statefunc(FALSE, TRUE) AS "t",
- NOT booland_statefunc(FALSE, FALSE) AS "t";
- t | t | t | t | t | t | t | t | t
----+---+---+---+---+---+---+---+---
- t | t | t | t | t | t | t | t | t
-(1 row)
-
-SELECT
- -- boolean or transitions
- -- null because strict
- boolor_statefunc(NULL, NULL) IS NULL AS "t",
- boolor_statefunc(TRUE, NULL) IS NULL AS "t",
- boolor_statefunc(FALSE, NULL) IS NULL AS "t",
- boolor_statefunc(NULL, TRUE) IS NULL AS "t",
- boolor_statefunc(NULL, FALSE) IS NULL AS "t",
- -- actual computations
- boolor_statefunc(TRUE, TRUE) AS "t",
- boolor_statefunc(TRUE, FALSE) AS "t",
- boolor_statefunc(FALSE, TRUE) AS "t",
- NOT boolor_statefunc(FALSE, FALSE) AS "t";
- t | t | t | t | t | t | t | t | t
----+---+---+---+---+---+---+---+---
- t | t | t | t | t | t | t | t | t
-(1 row)
-
-CREATE TEMPORARY TABLE bool_test(
- b1 BOOL,
- b2 BOOL,
- b3 BOOL,
- b4 BOOL);
--- empty case
-SELECT
- BOOL_AND(b1) AS "n",
- BOOL_OR(b3) AS "n"
-FROM bool_test;
- n | n
----+---
- |
-(1 row)
-
-COPY bool_test FROM STDIN NULL 'null';
-SELECT
- BOOL_AND(b1) AS "f",
- BOOL_AND(b2) AS "t",
- BOOL_AND(b3) AS "f",
- BOOL_AND(b4) AS "n",
- BOOL_AND(NOT b2) AS "f",
- BOOL_AND(NOT b3) AS "t"
-FROM bool_test;
- f | t | f | n | f | t
----+---+---+---+---+---
- f | t | f | | f | t
-(1 row)
-
-SELECT
- EVERY(b1) AS "f",
- EVERY(b2) AS "t",
- EVERY(b3) AS "f",
- EVERY(b4) AS "n",
- EVERY(NOT b2) AS "f",
- EVERY(NOT b3) AS "t"
-FROM bool_test;
- f | t | f | n | f | t
----+---+---+---+---+---
- f | t | f | | f | t
-(1 row)
-
-SELECT
- BOOL_OR(b1) AS "t",
- BOOL_OR(b2) AS "t",
- BOOL_OR(b3) AS "f",
- BOOL_OR(b4) AS "n",
- BOOL_OR(NOT b2) AS "f",
- BOOL_OR(NOT b3) AS "t"
-FROM bool_test;
- t | t | f | n | f | t
----+---+---+---+---+---
- t | t | f | | f | t
-(1 row)
-
---
--- Test cases that should be optimized into indexscans instead of
--- the generic aggregate implementation.
--- In Postgres-XL, plans printed by explain are the ones created on the
--- coordinator. Coordinator does not generate index scan plans.
---
--- Basic cases
-explain (costs off, nodes off)
- select min(unique1) from tenk1;
- QUERY PLAN
-------------------------------------------------------------------------
- Result
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan using tenk1_unique1 on tenk1
- Index Cond: (unique1 IS NOT NULL)
-(7 rows)
-
-select min(unique1) from tenk1;
- min
------
- 0
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique1) from tenk1;
- QUERY PLAN
----------------------------------------------------------------------------------
- Result
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_unique1 on tenk1
- Index Cond: (unique1 IS NOT NULL)
-(7 rows)
-
-select max(unique1) from tenk1;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique1) from tenk1 where unique1 < 42;
- QUERY PLAN
-------------------------------------------------------------------------------------
- Result
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_unique1 on tenk1
- Index Cond: ((unique1 IS NOT NULL) AND (unique1 < 42))
-(7 rows)
-
-select max(unique1) from tenk1 where unique1 < 42;
- max
------
- 41
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique1) from tenk1 where unique1 > 42;
- QUERY PLAN
-------------------------------------------------------------------------------------
- Result
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_unique1 on tenk1
- Index Cond: ((unique1 IS NOT NULL) AND (unique1 > 42))
-(7 rows)
-
-select max(unique1) from tenk1 where unique1 > 42;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique1) from tenk1 where unique1 > 42000;
- QUERY PLAN
----------------------------------------------------------------------------------------
- Result
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_unique1 on tenk1
- Index Cond: ((unique1 IS NOT NULL) AND (unique1 > 42000))
-(7 rows)
-
-select max(unique1) from tenk1 where unique1 > 42000;
- max
------
-
-(1 row)
-
--- multi-column index (uses tenk1_thous_tenthous)
-explain (costs off, nodes off)
- select max(tenthous) from tenk1 where thousand = 33;
- QUERY PLAN
-----------------------------------------------------------------------------------------
- Result
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_thous_tenthous on tenk1
- Index Cond: ((thousand = 33) AND (tenthous IS NOT NULL))
-(7 rows)
-
-select max(tenthous) from tenk1 where thousand = 33;
- max
-------
- 9033
-(1 row)
-
-explain (costs off, nodes off)
- select min(tenthous) from tenk1 where thousand = 33;
- QUERY PLAN
---------------------------------------------------------------------------------------
- Result
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan using tenk1_thous_tenthous on tenk1
- Index Cond: ((thousand = 33) AND (tenthous IS NOT NULL))
-(7 rows)
-
-select min(tenthous) from tenk1 where thousand = 33;
- min
------
- 33
-(1 row)
-
--- check parameter propagation into an indexscan subquery
-explain (costs off, nodes off)
- select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt
- from int4_tbl;
- QUERY PLAN
------------------------------------------------------------------------------------------------------------
- Remote Subquery Scan on all
- -> Seq Scan on int4_tbl
- SubPlan 2
- -> Result
- InitPlan 1 (returns $1)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan using tenk1_unique1 on tenk1
- Index Cond: ((unique1 IS NOT NULL) AND (unique1 > int4_tbl.f1))
-(10 rows)
-
-select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt
-from int4_tbl
-order by f1;
- f1 | gt
--------------+----
- -2147483647 | 0
- -123456 | 0
- 0 | 1
- 123456 |
- 2147483647 |
-(5 rows)
-
--- check some cases that were handled incorrectly in 8.3.0
-explain (costs off, nodes off)
- select distinct max(unique2) from tenk1;
- QUERY PLAN
----------------------------------------------------------------------------------
- HashAggregate
- Group Key: $0
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_unique2 on tenk1
- Index Cond: (unique2 IS NOT NULL)
- -> Result
-(9 rows)
-
-select distinct max(unique2) from tenk1;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique2) from tenk1 order by 1;
- QUERY PLAN
----------------------------------------------------------------------------------
- Sort
- Sort Key: ($0)
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_unique2 on tenk1
- Index Cond: (unique2 IS NOT NULL)
- -> Result
-(9 rows)
-
-select max(unique2) from tenk1 order by 1;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique2) from tenk1 order by max(unique2);
- QUERY PLAN
----------------------------------------------------------------------------------
- Sort
- Sort Key: ($0)
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_unique2 on tenk1
- Index Cond: (unique2 IS NOT NULL)
- -> Result
-(9 rows)
-
-select max(unique2) from tenk1 order by max(unique2);
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique2) from tenk1 order by max(unique2)+1;
- QUERY PLAN
----------------------------------------------------------------------------------
- Sort
- Sort Key: (($0 + 1))
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_unique2 on tenk1
- Index Cond: (unique2 IS NOT NULL)
- -> Result
-(9 rows)
-
-select max(unique2) from tenk1 order by max(unique2)+1;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique2), generate_series(1,3) as g from tenk1 order by g desc;
- QUERY PLAN
----------------------------------------------------------------------------------
- Sort
- Sort Key: (generate_series(1, 3)) DESC
- InitPlan 1 (returns $0)
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Index Only Scan Backward using tenk1_unique2 on tenk1
- Index Cond: (unique2 IS NOT NULL)
- -> Result
-(9 rows)
-
-select max(unique2), generate_series(1,3) as g from tenk1 order by g desc;
- max | g
-------+---
- 9999 | 3
- 9999 | 2
- 9999 | 1
-(3 rows)
-
--- try it on an inheritance tree
-create table minmaxtest(f1 int);
-create table minmaxtest1() inherits (minmaxtest);
-create table minmaxtest2() inherits (minmaxtest);
-create table minmaxtest3() inherits (minmaxtest);
-create index minmaxtesti on minmaxtest(f1);
-create index minmaxtest1i on minmaxtest1(f1);
-create index minmaxtest2i on minmaxtest2(f1 desc);
-create index minmaxtest3i on minmaxtest3(f1) where f1 is not null;
-insert into minmaxtest values(11), (12);
-insert into minmaxtest1 values(13), (14);
-insert into minmaxtest2 values(15), (16);
-insert into minmaxtest3 values(17), (18);
-explain (costs off, nodes off)
- select min(f1), max(f1) from minmaxtest;
- QUERY PLAN
--------------------------------------------------
- Aggregate
- -> Remote Subquery Scan on all
- -> Aggregate
- -> Append
- -> Seq Scan on minmaxtest
- -> Seq Scan on minmaxtest1
- -> Seq Scan on minmaxtest2
- -> Seq Scan on minmaxtest3
-(8 rows)
-
-select min(f1), max(f1) from minmaxtest;
- min | max
------+-----
- 11 | 18
-(1 row)
-
--- DISTINCT doesn't do anything useful here, but it shouldn't fail
-explain (costs off)
- select distinct min(f1), max(f1) from minmaxtest;
- QUERY PLAN
------------------------------------------------------------------
- HashAggregate
- Group Key: min((min(f1))), max((max(f1)))
- -> Aggregate
- -> Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Aggregate
- -> Append
- -> Seq Scan on minmaxtest
- -> Seq Scan on minmaxtest1
- -> Seq Scan on minmaxtest2
- -> Seq Scan on minmaxtest3
-(10 rows)
-
-select distinct min(f1), max(f1) from minmaxtest;
- min | max
------+-----
- 11 | 18
-(1 row)
-
-drop table minmaxtest cascade;
-NOTICE: drop cascades to 3 other objects
-DETAIL: drop cascades to table minmaxtest1
-drop cascades to table minmaxtest2
-drop cascades to table minmaxtest3
--- check for correct detection of nested-aggregate errors
-select max(min(unique1)) from tenk1;
-ERROR: aggregate function calls cannot be nested
-LINE 1: select max(min(unique1)) from tenk1;
- ^
-select (select max(min(unique1)) from int8_tbl) from tenk1;
-ERROR: aggregate function calls cannot be nested
-LINE 1: select (select max(min(unique1)) from int8_tbl) from tenk1;
- ^
---
--- Test combinations of DISTINCT and/or ORDER BY
---
-select array_agg(a order by b)
- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b);
- array_agg
------------
- {3,4,2,1}
-(1 row)
-
-select array_agg(a order by a)
- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b);
- array_agg
------------
- {1,2,3,4}
-(1 row)
-
-select array_agg(a order by a desc)
- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b);
- array_agg
------------
- {4,3,2,1}
-(1 row)
-
-select array_agg(b order by a desc)
- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b);
- array_agg
------------
- {2,1,3,4}
-(1 row)
-
-select array_agg(distinct a)
- from (values (1),(2),(1),(3),(null),(2)) v(a);
- array_agg
---------------
- {1,2,3,NULL}
-(1 row)
-
-select array_agg(distinct a order by a)
- from (values (1),(2),(1),(3),(null),(2)) v(a);
- array_agg
---------------
- {1,2,3,NULL}
-(1 row)
-
-select array_agg(distinct a order by a desc)
- from (values (1),(2),(1),(3),(null),(2)) v(a);
- array_agg
---------------
- {NULL,3,2,1}
-(1 row)
-
-select array_agg(distinct a order by a desc nulls last)
- from (values (1),(2),(1),(3),(null),(2)) v(a);
- array_agg
---------------
- {3,2,1,NULL}
-(1 row)
-
--- multi-arg aggs, strict/nonstrict, distinct/order by
-select aggfstr(a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
- aggfstr
----------------------------------------
- {"(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select aggfns(a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
- aggfns
------------------------------------------------
- {"(1,3,foo)","(0,,)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select aggfstr(distinct a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
- aggfstr
----------------------------------------
- {"(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select aggfns(distinct a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
- aggfns
------------------------------------------------
- {"(0,,)","(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select aggfstr(distinct a,b,c order by b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
- aggfstr
----------------------------------------
- {"(3,1,baz)","(2,2,bar)","(1,3,foo)"}
-(1 row)
-
-select aggfns(distinct a,b,c order by b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
- aggfns
------------------------------------------------
- {"(3,1,baz)","(2,2,bar)","(1,3,foo)","(0,,)"}
-(1 row)
-
--- test specific code paths
-select aggfns(distinct a,a,c order by c using ~<~,a)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
- aggfns
-------------------------------------------------
- {"(2,2,bar)","(3,3,baz)","(1,1,foo)","(0,0,)"}
-(1 row)
-
-select aggfns(distinct a,a,c order by c using ~<~)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
- aggfns
-------------------------------------------------
- {"(2,2,bar)","(3,3,baz)","(1,1,foo)","(0,0,)"}
-(1 row)
-
-select aggfns(distinct a,a,c order by a)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
- aggfns
-------------------------------------------------
- {"(0,0,)","(1,1,foo)","(2,2,bar)","(3,3,baz)"}
-(1 row)
-
-select aggfns(distinct a,b,c order by a,c using ~<~,b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
- aggfns
------------------------------------------------
- {"(0,,)","(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
--- check node I/O via view creation and usage, also deparsing logic
-create view agg_view1 as
- select aggfns(a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(1,3,foo)","(0,,)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(v.a, v.b, v.c) AS aggfns +
- FROM ( VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(distinct a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(0,,)","(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(DISTINCT v.a, v.b, v.c) AS aggfns +
- FROM ( VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c),+
- generate_series(1, 3) i(i);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(distinct a,b,c order by b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(3,1,baz)","(2,2,bar)","(1,3,foo)","(0,,)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(DISTINCT v.a, v.b, v.c ORDER BY v.b) AS aggfns +
- FROM ( VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c),+
- generate_series(1, 3) i(i);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(a,b,c order by b+1)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(3,1,baz)","(2,2,bar)","(1,3,foo)","(0,,)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(v.a, v.b, v.c ORDER BY (v.b + 1)) AS aggfns +
- FROM ( VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(a,a,c order by b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
-select * from agg_view1;
- aggfns
-------------------------------------------------
- {"(3,3,baz)","(2,2,bar)","(1,1,foo)","(0,0,)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(v.a, v.a, v.c ORDER BY v.b) AS aggfns +
- FROM ( VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(a,b,c order by c using ~<~)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(2,2,bar)","(3,1,baz)","(1,3,foo)","(0,,)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(v.a, v.b, v.c ORDER BY v.c USING ~<~ NULLS LAST) AS aggfns +
- FROM ( VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(distinct a,b,c order by a,c using ~<~,b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(0,,)","(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(DISTINCT v.a, v.b, v.c ORDER BY v.a, v.c USING ~<~ NULLS LAST, v.b) AS aggfns +
- FROM ( VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c),+
- generate_series(1, 2) i(i);
-(1 row)
-
-drop view agg_view1;
--- incorrect DISTINCT usage errors
-select aggfns(distinct a,b,c order by i)
- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i;
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select aggfns(distinct a,b,c order by i)
- ^
-select aggfns(distinct a,b,c order by a,b+1)
- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i;
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select aggfns(distinct a,b,c order by a,b+1)
- ^
-select aggfns(distinct a,b,c order by a,b,i,c)
- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i;
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select aggfns(distinct a,b,c order by a,b,i,c)
- ^
-select aggfns(distinct a,a,c order by a,b)
- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i;
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select aggfns(distinct a,a,c order by a,b)
- ^
--- string_agg tests
-select string_agg(a,',') from (values('aaaa'),('bbbb'),('cccc')) g(a);
- string_agg
-----------------
- aaaa,bbbb,cccc
-(1 row)
-
-select string_agg(a,',') from (values('aaaa'),(null),('bbbb'),('cccc')) g(a);
- string_agg
-----------------
- aaaa,bbbb,cccc
-(1 row)
-
-select string_agg(a,'AB') from (values(null),(null),('bbbb'),('cccc')) g(a);
- string_agg
-------------
- bbbbABcccc
-(1 row)
-
-select string_agg(a,',') from (values(null),(null)) g(a);
- string_agg
-------------
-
-(1 row)
-
--- check some implicit casting cases, as per bug #5564
-select string_agg(distinct f1, ',' order by f1) from varchar_tbl; -- ok
- string_agg
-------------
- a,ab,abcd
-(1 row)
-
-select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl; -- not ok
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select string_agg(distinct f1::text, ',' order by f1) from v...
- ^
-select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; -- not ok
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select string_agg(distinct f1, ',' order by f1::text) from v...
- ^
-select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -- ok
- string_agg
-------------
- a,ab,abcd
-(1 row)
-
--- string_agg bytea tests
-create table bytea_test_table(v bytea);
-select string_agg(v, '') from bytea_test_table;
- string_agg
-------------
-
-(1 row)
-
-insert into bytea_test_table values(decode('ff','hex'));
-select string_agg(v, '') from bytea_test_table;
- string_agg
-------------
- \xff
-(1 row)
-
-insert into bytea_test_table values(decode('aa','hex'));
-select string_agg(v, '') from bytea_test_table;
- string_agg
-------------
- \xffaa
-(1 row)
-
-select string_agg(v, NULL) from bytea_test_table;
- string_agg
-------------
- \xffaa
-(1 row)
-
-select string_agg(v, decode('ee', 'hex')) from bytea_test_table;
- string_agg
-------------
- \xffeeaa
-(1 row)
-
-drop table bytea_test_table;
--- FILTER tests
-select min(unique1) filter (where unique1 > 100) from tenk1;
- min
------
- 101
-(1 row)
-
-select ten, sum(distinct four) filter (where four::text ~ '123') from onek a
-group by ten;
- ten | sum
------+-----
- 0 |
- 1 |
- 2 |
- 3 |
- 4 |
- 5 |
- 6 |
- 7 |
- 8 |
- 9 |
-(10 rows)
-
-select ten, sum(distinct four) filter (where four > 10) from onek a
-group by ten
-having exists (select 1 from onek b where sum(distinct a.four) = b.four);
- ten | sum
------+-----
- 0 |
- 2 |
- 4 |
- 6 |
- 8 |
-(5 rows)
-
-select max(foo COLLATE "C") filter (where (bar collate "POSIX") > '0')
-from (values ('a', 'b')) AS v(foo,bar);
- max
------
- a
-(1 row)
-
--- outer reference in FILTER (PostgreSQL extension)
-select (select count(*)
- from (values (1)) t0(inner_c))
-from (values (2),(3)) t1(outer_c); -- inner query is aggregation query
- count
--------
- 1
- 1
-(2 rows)
-
-select (select count(*) filter (where outer_c <> 0)
- from (values (1)) t0(inner_c))
-from (values (2),(3)) t1(outer_c); -- outer query is aggregation query
- count
--------
- 2
-(1 row)
-
-select (select count(inner_c) filter (where outer_c <> 0)
- from (values (1)) t0(inner_c))
-from (values (2),(3)) t1(outer_c); -- inner query is aggregation query
- count
--------
- 1
- 1
-(2 rows)
-
-select
- (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1))
- filter (where o.unique1 < 10))
-from tenk1 o; -- outer query is aggregation query
- max
-------
- 9998
-(1 row)
-
--- subquery in FILTER clause (PostgreSQL extension)
-select sum(unique1) FILTER (WHERE
- unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1;
- sum
-------
- 4950
-(1 row)
-
--- exercise lots of aggregate parts with FILTER
-select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
- aggfns
----------------------------
- {"(2,2,bar)","(3,1,baz)"}
-(1 row)
-
--- ordered-set aggregates
-select p, percentile_cont(p) within group (order by x::float8)
-from generate_series(1,5) x,
- (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p)
-group by p order by p;
- p | percentile_cont
-------+-----------------
- 0 | 1
- 0.1 | 1.4
- 0.25 | 2
- 0.4 | 2.6
- 0.5 | 3
- 0.6 | 3.4
- 0.75 | 4
- 0.9 | 4.6
- 1 | 5
-(9 rows)
-
-select p, percentile_cont(p order by p) within group (order by x) -- error
-from generate_series(1,5) x,
- (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p)
-group by p order by p;
-ERROR: cannot use multiple ORDER BY clauses with WITHIN GROUP
-LINE 1: select p, percentile_cont(p order by p) within group (order ...
- ^
-select p, sum() within group (order by x::float8) -- error
-from generate_series(1,5) x,
- (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p)
-group by p order by p;
-ERROR: sum is not an ordered-set aggregate, so it cannot have WITHIN GROUP
-LINE 1: select p, sum() within group (order by x::float8)
- ^
-select p, percentile_cont(p,p) -- error
-from generate_series(1,5) x,
- (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p)
-group by p order by p;
-ERROR: WITHIN GROUP is required for ordered-set aggregate percentile_cont
-LINE 1: select p, percentile_cont(p,p)
- ^
-select percentile_cont(0.5) within group (order by b) from aggtest;
- percentile_cont
-------------------
- 53.4485001564026
-(1 row)
-
-select percentile_cont(0.5) within group (order by b), sum(b) from aggtest;
- percentile_cont | sum
-------------------+---------
- 53.4485001564026 | 431.773
-(1 row)
-
-select percentile_cont(0.5) within group (order by thousand) from tenk1;
- percentile_cont
------------------
- 499.5
-(1 row)
-
-select percentile_disc(0.5) within group (order by thousand) from tenk1;
- percentile_disc
------------------
- 499
-(1 row)
-
-select rank(3) within group (order by x)
-from (values (1),(1),(2),(2),(3),(3),(4)) v(x);
- rank
-------
- 5
-(1 row)
-
-select cume_dist(3) within group (order by x)
-from (values (1),(1),(2),(2),(3),(3),(4)) v(x);
- cume_dist
------------
- 0.875
-(1 row)
-
-select percent_rank(3) within group (order by x)
-from (values (1),(1),(2),(2),(3),(3),(4),(5)) v(x);
- percent_rank
---------------
- 0.5
-(1 row)
-
-select dense_rank(3) within group (order by x)
-from (values (1),(1),(2),(2),(3),(3),(4)) v(x);
- dense_rank
-------------
- 3
-(1 row)
-
-select percentile_disc(array[0,0.1,0.25,0.5,0.75,0.9,1]) within group (order by thousand)
-from tenk1;
- percentile_disc
-----------------------------
- {0,99,249,499,749,899,999}
-(1 row)
-
-select percentile_cont(array[0,0.25,0.5,0.75,1]) within group (order by thousand)
-from tenk1;
- percentile_cont
------------------------------
- {0,249.75,499.5,749.25,999}
-(1 row)
-
-select percentile_disc(array[[null,1,0.5],[0.75,0.25,null]]) within group (order by thousand)
-from tenk1;
- percentile_disc
----------------------------------
- {{NULL,999,499},{749,249,NULL}}
-(1 row)
-
-select percentile_cont(array[0,1,0.25,0.75,0.5,1,0.3,0.32,0.35,0.38,0.4]) within group (order by x)
-from generate_series(1,6) x;
- percentile_cont
-------------------------------------------
- {1,6,2.25,4.75,3.5,6,2.5,2.6,2.75,2.9,3}
-(1 row)
-
-select ten, mode() within group (order by string4) from tenk1 group by ten;
- ten | mode
------+--------
- 0 | HHHHxx
- 1 | OOOOxx
- 2 | VVVVxx
- 3 | OOOOxx
- 4 | HHHHxx
- 5 | HHHHxx
- 6 | OOOOxx
- 7 | AAAAxx
- 8 | VVVVxx
- 9 | VVVVxx
-(10 rows)
-
-select percentile_disc(array[0.25,0.5,0.75]) within group (order by x)
-from unnest('{fred,jim,fred,jack,jill,fred,jill,jim,jim,sheila,jim,sheila}'::text[]) u(x);
- percentile_disc
------------------
- {fred,jill,jim}
-(1 row)
-
--- check collation propagates up in suitable cases:
-select pg_collation_for(percentile_disc(1) within group (order by x collate "POSIX"))
- from (values ('fred'),('jim')) v(x);
- pg_collation_for
-------------------
- "POSIX"
-(1 row)
-
--- ordered-set aggs created with CREATE AGGREGATE
-select test_rank(3) within group (order by x)
-from (values (1),(1),(2),(2),(3),(3),(4)) v(x);
- test_rank
------------
- 5
-(1 row)
-
-select test_percentile_disc(0.5) within group (order by thousand) from tenk1;
- test_percentile_disc
-----------------------
- 499
-(1 row)
-
--- ordered-set aggs can't use ungrouped vars in direct args:
-select rank(x) within group (order by x) from generate_series(1,5) x;
-ERROR: column "x.x" must appear in the GROUP BY clause or be used in an aggregate function
-LINE 1: select rank(x) within group (order by x) from generate_serie...
- ^
-DETAIL: Direct arguments of an ordered-set aggregate must use only grouped columns.
--- outer-level agg can't use a grouped arg of a lower level, either:
-select array(select percentile_disc(a) within group (order by x)
- from (values (0.3),(0.7)) v(a) group by a)
- from generate_series(1,5) g(x);
-ERROR: outer-level aggregate cannot contain a lower-level variable in its direct arguments
-LINE 1: select array(select percentile_disc(a) within group (order b...
- ^
--- agg in the direct args is a grouping violation, too:
-select rank(sum(x)) within group (order by x) from generate_series(1,5) x;
-ERROR: aggregate function calls cannot be nested
-LINE 1: select rank(sum(x)) within group (order by x) from generate_...
- ^
--- hypothetical-set type unification and argument-count failures:
-select rank(3) within group (order by x) from (values ('fred'),('jim')) v(x);
-ERROR: WITHIN GROUP types text and integer cannot be matched
-LINE 1: select rank(3) within group (order by x) from (values ('fred...
- ^
-select rank(3) within group (order by stringu1,stringu2) from tenk1;
-ERROR: function rank(integer, name, name) does not exist
-LINE 1: select rank(3) within group (order by stringu1,stringu2) fro...
- ^
-HINT: To use the hypothetical-set aggregate rank, the number of hypothetical direct arguments (here 1) must match the number of ordering columns (here 2).
-select rank('fred') within group (order by x) from generate_series(1,5) x;
-ERROR: invalid input syntax for integer: "fred"
-LINE 1: select rank('fred') within group (order by x) from generate_...
- ^
-select rank('adam'::text collate "C") within group (order by x collate "POSIX")
- from (values ('fred'),('jim')) v(x);
-ERROR: collation mismatch between explicit collations "C" and "POSIX"
-LINE 1: ...adam'::text collate "C") within group (order by x collate "P...
- ^
--- hypothetical-set type unification successes:
-select rank('adam'::varchar) within group (order by x) from (values ('fred'),('jim')) v(x);
- rank
-------
- 1
-(1 row)
-
-select rank('3') within group (order by x) from generate_series(1,5) x;
- rank
-------
- 3
-(1 row)
-
--- divide by zero check
-select percent_rank(0) within group (order by x) from generate_series(1,0) x;
- percent_rank
---------------
- 0
-(1 row)
-
--- deparse and multiple features:
-create view aggordview1 as
-select ten,
- percentile_disc(0.5) within group (order by thousand) as p50,
- percentile_disc(0.5) within group (order by thousand) filter (where hundred=1) as px,
- rank(5,'AZZZZ',50) within group (order by hundred, string4 desc, hundred)
- from tenk1
- group by ten order by ten;
-select pg_get_viewdef('aggordview1');
- pg_get_viewdef
--------------------------------------------------------------------------------------------------------------------------------
- SELECT tenk1.ten, +
- percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY tenk1.thousand) AS p50, +
- percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY tenk1.thousand) FILTER (WHERE (tenk1.hundred = 1)) AS px,+
- rank(5, 'AZZZZ'::name, 50) WITHIN GROUP (ORDER BY tenk1.hundred, tenk1.string4 DESC, tenk1.hundred) AS rank +
- FROM tenk1 +
- GROUP BY tenk1.ten +
- ORDER BY tenk1.ten;
-(1 row)
-
-select * from aggordview1 order by ten;
- ten | p50 | px | rank
------+-----+-----+------
- 0 | 490 | | 101
- 1 | 491 | 401 | 101
- 2 | 492 | | 101
- 3 | 493 | | 101
- 4 | 494 | | 101
- 5 | 495 | | 67
- 6 | 496 | | 1
- 7 | 497 | | 1
- 8 | 498 | | 1
- 9 | 499 | | 1
-(10 rows)
-
-drop view aggordview1;
--- variadic aggregates
-select least_agg(q1,q2) from int8_tbl;
- least_agg
--------------------
- -4567890123456789
-(1 row)
-
-select least_agg(variadic array[q1,q2]) from int8_tbl;
- least_agg
--------------------
- -4567890123456789
-(1 row)
-
--- int8 aggregates for distributed tables
-CREATE TABLE int8_tbl_aggtest AS SELECT * FROM int8_tbl;
-SELECT avg(q1) FROM int8_tbl_aggtest;
- avg
------------------------
- 2740734074074122.6000
-(1 row)
-
-SELECT sum(q1) FROM int8_tbl_aggtest;
- sum
--------------------
- 13703670370370613
-(1 row)
-
-SELECT max(q1) FROM int8_tbl_aggtest;
- max
-------------------
- 4567890123456789
-(1 row)
-
-SELECT min(q1) FROM int8_tbl_aggtest;
- min
------
- 123
-(1 row)
-
-SELECT stddev_pop(q1) FROM int8_tbl_aggtest;
- stddev_pop
-------------------
- 2237800000713538
-(1 row)
-
-SELECT stddev_samp(q1) FROM int8_tbl_aggtest;
- stddev_samp
-------------------
- 2501936460822274
-(1 row)
-
-SELECT var_pop(q1) FROM int8_tbl_aggtest;
- var_pop
----------------------------------
- 5007748843193509284246811160533
-(1 row)
-
-SELECT var_samp(q1) FROM int8_tbl_aggtest;
- var_samp
----------------------------------
- 6259686053991886605308513950667
-(1 row)
-
-DROP TABLE int8_tbl_aggtest;
+++ /dev/null
---
--- AGGREGATES
---
-SELECT avg(four) AS avg_1 FROM onek;
- avg_1
---------------------
- 1.5000000000000000
-(1 row)
-
-SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100;
- avg_32
----------------------
- 32.6666666666666667
-(1 row)
-
--- In 7.1, avg(float4) is computed using float8 arithmetic.
--- Round the result to 3 digits to avoid platform-specific results.
-SELECT avg(b)::numeric(10,3) AS avg_107_943 FROM aggtest;
- avg_107_943
--------------
- 107.943
-(1 row)
-
-SELECT avg(gpa) AS avg_3_4 FROM ONLY student;
- avg_3_4
----------
- 3.4
-(1 row)
-
-SELECT sum(four) AS sum_1500 FROM onek;
- sum_1500
-----------
- 1500
-(1 row)
-
-SELECT sum(a) AS sum_198 FROM aggtest;
- sum_198
----------
- 198
-(1 row)
-
-SELECT sum(b) AS avg_431_773 FROM aggtest;
- avg_431_773
--------------
- 431.773
-(1 row)
-
-SELECT sum(gpa) AS avg_6_8 FROM ONLY student;
- avg_6_8
----------
- 6.8
-(1 row)
-
-SELECT max(four) AS max_3 FROM onek;
- max_3
--------
- 3
-(1 row)
-
-SELECT max(a) AS max_100 FROM aggtest;
- max_100
----------
- 100
-(1 row)
-
-SELECT max(aggtest.b) AS max_324_78 FROM aggtest;
- max_324_78
-------------
- 324.78
-(1 row)
-
-SELECT max(student.gpa) AS max_3_7 FROM student;
- max_3_7
----------
- 3.7
-(1 row)
-
-SELECT stddev_pop(b) FROM aggtest;
- stddev_pop
-------------------
- 131.107032318951
-(1 row)
-
-SELECT stddev_samp(b) FROM aggtest;
- stddev_samp
-------------------
- 151.389360803998
-(1 row)
-
-SELECT var_pop(b) FROM aggtest;
- var_pop
-------------------
- 17189.0539234824
-(1 row)
-
-SELECT var_samp(b) FROM aggtest;
- var_samp
-------------------
- 22918.7385646432
-(1 row)
-
-SELECT stddev_pop(b::numeric) FROM aggtest;
- stddev_pop
-------------------
- 131.107032862199
-(1 row)
-
-SELECT stddev_samp(b::numeric) FROM aggtest;
- stddev_samp
-------------------
- 151.389361431288
-(1 row)
-
-SELECT var_pop(b::numeric) FROM aggtest;
- var_pop
---------------------
- 17189.054065929769
-(1 row)
-
-SELECT var_samp(b::numeric) FROM aggtest;
- var_samp
---------------------
- 22918.738754573025
-(1 row)
-
--- population variance is defined for a single tuple, sample variance
--- is not
-SELECT var_pop(1.0), var_samp(2.0);
- var_pop | var_samp
----------+----------
- 0 |
-(1 row)
-
-SELECT stddev_pop(3.0::numeric), stddev_samp(4.0::numeric);
- stddev_pop | stddev_samp
-------------+-------------
- 0 |
-(1 row)
-
--- SQL2003 binary aggregates
-SELECT regr_count(b, a) FROM aggtest;
- regr_count
-------------
- 4
-(1 row)
-
-SELECT regr_sxx(b, a) FROM aggtest;
- regr_sxx
-----------
- 5099
-(1 row)
-
-SELECT regr_syy(b, a) FROM aggtest;
- regr_syy
-------------------
- 68756.2156939297
-(1 row)
-
-SELECT regr_sxy(b, a) FROM aggtest;
- regr_sxy
-------------------
- 2614.51582155001
-(1 row)
-
-SELECT regr_avgx(b, a), regr_avgy(b, a) FROM aggtest;
- regr_avgx | regr_avgy
------------+------------------
- 49.5 | 107.943152273074
-(1 row)
-
-SELECT regr_r2(b, a) FROM aggtest;
- regr_r2
---------------------
- 0.0194977982031797
-(1 row)
-
-SELECT regr_slope(b, a), regr_intercept(b, a) FROM aggtest;
- regr_slope | regr_intercept
--------------------+------------------
- 0.512750700441265 | 82.5619926012313
-(1 row)
-
-SELECT covar_pop(b, a), covar_samp(b, a) FROM aggtest;
- covar_pop | covar_samp
-------------------+------------------
- 653.628955387502 | 871.505273850003
-(1 row)
-
-SELECT corr(b, a) FROM aggtest;
- corr
--------------------
- 0.139634516517871
-(1 row)
-
-SELECT count(four) AS cnt_1000 FROM onek;
- cnt_1000
-----------
- 1000
-(1 row)
-
-SELECT count(DISTINCT four) AS cnt_4 FROM onek;
- cnt_4
--------
- 4
-(1 row)
-
-select ten, count(*), sum(four) from onek
-group by ten order by ten;
- ten | count | sum
------+-------+-----
- 0 | 100 | 100
- 1 | 100 | 200
- 2 | 100 | 100
- 3 | 100 | 200
- 4 | 100 | 100
- 5 | 100 | 200
- 6 | 100 | 100
- 7 | 100 | 200
- 8 | 100 | 100
- 9 | 100 | 200
-(10 rows)
-
-select ten, count(four), sum(DISTINCT four) from onek
-group by ten order by ten;
- ten | count | sum
------+-------+-----
- 0 | 100 | 2
- 1 | 100 | 4
- 2 | 100 | 2
- 3 | 100 | 4
- 4 | 100 | 2
- 5 | 100 | 4
- 6 | 100 | 2
- 7 | 100 | 4
- 8 | 100 | 2
- 9 | 100 | 4
-(10 rows)
-
--- user-defined aggregates
-SELECT newavg(four) AS avg_1 FROM onek;
- avg_1
---------------------
- 1.5000000000000000
-(1 row)
-
-SELECT newsum(four) AS sum_1500 FROM onek;
- sum_1500
-----------
- 1500
-(1 row)
-
-SELECT newcnt(four) AS cnt_1000 FROM onek;
- cnt_1000
-----------
- 1000
-(1 row)
-
-SELECT newcnt(*) AS cnt_1000 FROM onek;
- cnt_1000
-----------
- 1000
-(1 row)
-
-SELECT oldcnt(*) AS cnt_1000 FROM onek;
- cnt_1000
-----------
- 1000
-(1 row)
-
-SELECT sum2(q1,q2) FROM int8_tbl;
- sum2
--------------------
- 18271560493827981
-(1 row)
-
--- test for outer-level aggregates
--- this should work
-select ten, sum(distinct four) from onek a
-group by ten
-having exists (select 1 from onek b where sum(distinct a.four) = b.four)
-order by ten;
- ten | sum
------+-----
- 0 | 2
- 2 | 2
- 4 | 2
- 6 | 2
- 8 | 2
-(5 rows)
-
--- this should fail because subquery has an agg of its own in WHERE
-select ten, sum(distinct four) from onek a
-group by ten
-having exists (select 1 from onek b
- where sum(distinct a.four + b.four) = b.four);
-ERROR: aggregates not allowed in WHERE clause
-LINE 4: where sum(distinct a.four + b.four) = b.four)...
- ^
--- Test handling of sublinks within outer-level aggregates.
--- Per bug report from Daniel Grace.
-select
- (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)))
-from tenk1 o;
- max
-------
- 9999
-(1 row)
-
---
--- test for bitwise integer aggregates
---
-CREATE TEMPORARY TABLE bitwise_test(
- i2 INT2,
- i4 INT4,
- i8 INT8,
- i INTEGER,
- x INT2,
- y BIT(4)
-);
--- empty case
-SELECT
- BIT_AND(i2) AS "?",
- BIT_OR(i4) AS "?"
-FROM bitwise_test;
- ? | ?
----+---
- |
-(1 row)
-
-COPY bitwise_test FROM STDIN NULL 'null';
-SELECT
- BIT_AND(i2) AS "1",
- BIT_AND(i4) AS "1",
- BIT_AND(i8) AS "1",
- BIT_AND(i) AS "?",
- BIT_AND(x) AS "0",
- BIT_AND(y) AS "0100",
- BIT_OR(i2) AS "7",
- BIT_OR(i4) AS "7",
- BIT_OR(i8) AS "7",
- BIT_OR(i) AS "?",
- BIT_OR(x) AS "7",
- BIT_OR(y) AS "1101"
-FROM bitwise_test;
- 1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101
----+---+---+---+---+------+---+---+---+---+---+------
- 1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101
-(1 row)
-
---
--- test boolean aggregates
---
--- first test all possible transition and final states
-SELECT
- -- boolean and transitions
- -- null because strict
- booland_statefunc(NULL, NULL) IS NULL AS "t",
- booland_statefunc(TRUE, NULL) IS NULL AS "t",
- booland_statefunc(FALSE, NULL) IS NULL AS "t",
- booland_statefunc(NULL, TRUE) IS NULL AS "t",
- booland_statefunc(NULL, FALSE) IS NULL AS "t",
- -- and actual computations
- booland_statefunc(TRUE, TRUE) AS "t",
- NOT booland_statefunc(TRUE, FALSE) AS "t",
- NOT booland_statefunc(FALSE, TRUE) AS "t",
- NOT booland_statefunc(FALSE, FALSE) AS "t";
- t | t | t | t | t | t | t | t | t
----+---+---+---+---+---+---+---+---
- t | t | t | t | t | t | t | t | t
-(1 row)
-
-SELECT
- -- boolean or transitions
- -- null because strict
- boolor_statefunc(NULL, NULL) IS NULL AS "t",
- boolor_statefunc(TRUE, NULL) IS NULL AS "t",
- boolor_statefunc(FALSE, NULL) IS NULL AS "t",
- boolor_statefunc(NULL, TRUE) IS NULL AS "t",
- boolor_statefunc(NULL, FALSE) IS NULL AS "t",
- -- actual computations
- boolor_statefunc(TRUE, TRUE) AS "t",
- boolor_statefunc(TRUE, FALSE) AS "t",
- boolor_statefunc(FALSE, TRUE) AS "t",
- NOT boolor_statefunc(FALSE, FALSE) AS "t";
- t | t | t | t | t | t | t | t | t
----+---+---+---+---+---+---+---+---
- t | t | t | t | t | t | t | t | t
-(1 row)
-
-CREATE TEMPORARY TABLE bool_test(
- b1 BOOL,
- b2 BOOL,
- b3 BOOL,
- b4 BOOL);
--- empty case
-SELECT
- BOOL_AND(b1) AS "n",
- BOOL_OR(b3) AS "n"
-FROM bool_test;
- n | n
----+---
- |
-(1 row)
-
-COPY bool_test FROM STDIN NULL 'null';
-SELECT
- BOOL_AND(b1) AS "f",
- BOOL_AND(b2) AS "t",
- BOOL_AND(b3) AS "f",
- BOOL_AND(b4) AS "n",
- BOOL_AND(NOT b2) AS "f",
- BOOL_AND(NOT b3) AS "t"
-FROM bool_test;
- f | t | f | n | f | t
----+---+---+---+---+---
- f | t | f | | f | t
-(1 row)
-
-SELECT
- EVERY(b1) AS "f",
- EVERY(b2) AS "t",
- EVERY(b3) AS "f",
- EVERY(b4) AS "n",
- EVERY(NOT b2) AS "f",
- EVERY(NOT b3) AS "t"
-FROM bool_test;
- f | t | f | n | f | t
----+---+---+---+---+---
- f | t | f | | f | t
-(1 row)
-
-SELECT
- BOOL_OR(b1) AS "t",
- BOOL_OR(b2) AS "t",
- BOOL_OR(b3) AS "f",
- BOOL_OR(b4) AS "n",
- BOOL_OR(NOT b2) AS "f",
- BOOL_OR(NOT b3) AS "t"
-FROM bool_test;
- t | t | f | n | f | t
----+---+---+---+---+---
- t | t | f | | f | t
-(1 row)
-
---
--- Test cases that should be optimized into indexscans instead of
--- the generic aggregate implementation.
--- In Postgres-XL, plans printed by explain are the ones created on the
--- coordinator. Coordinator does not generate index scan plans.
---
-analyze tenk1; -- ensure we get consistent plans here
--- Basic cases
-explain (costs off, nodes off)
- select min(unique1) from tenk1;
- QUERY PLAN
---------------------------------------------------
- Aggregate
- -> Data Node Scan on "__REMOTE_GROUP_QUERY__"
-(2 rows)
-
-select min(unique1) from tenk1;
- min
------
- 0
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique1) from tenk1;
- QUERY PLAN
---------------------------------------------------
- Aggregate
- -> Data Node Scan on "__REMOTE_GROUP_QUERY__"
-(2 rows)
-
-select max(unique1) from tenk1;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique1) from tenk1 where unique1 < 42;
- QUERY PLAN
---------------------------------------------------
- Aggregate
- -> Data Node Scan on "__REMOTE_GROUP_QUERY__"
-(2 rows)
-
-select max(unique1) from tenk1 where unique1 < 42;
- max
------
- 41
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique1) from tenk1 where unique1 > 42;
- QUERY PLAN
---------------------------------------------------
- Aggregate
- -> Data Node Scan on "__REMOTE_GROUP_QUERY__"
-(2 rows)
-
-select max(unique1) from tenk1 where unique1 > 42;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique1) from tenk1 where unique1 > 42000;
- QUERY PLAN
---------------------------------------------------
- Aggregate
- -> Data Node Scan on "__REMOTE_GROUP_QUERY__"
-(2 rows)
-
-select max(unique1) from tenk1 where unique1 > 42000;
- max
------
-
-(1 row)
-
--- multi-column index (uses tenk1_thous_tenthous)
-explain (costs off, nodes off)
- select max(tenthous) from tenk1 where thousand = 33;
- QUERY PLAN
---------------------------------------------------
- Aggregate
- -> Data Node Scan on "__REMOTE_GROUP_QUERY__"
-(2 rows)
-
-select max(tenthous) from tenk1 where thousand = 33;
- max
-------
- 9033
-(1 row)
-
-explain (costs off, nodes off)
- select min(tenthous) from tenk1 where thousand = 33;
- QUERY PLAN
---------------------------------------------------
- Aggregate
- -> Data Node Scan on "__REMOTE_GROUP_QUERY__"
-(2 rows)
-
-select min(tenthous) from tenk1 where thousand = 33;
- min
------
- 33
-(1 row)
-
--- check parameter propagation into an indexscan subquery
-explain (costs off, nodes off)
- select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt
- from int4_tbl;
- QUERY PLAN
---------------------------------------------------------------
- Data Node Scan on int4_tbl "_REMOTE_TABLE_QUERY_"
- SubPlan 1
- -> Aggregate
- -> Data Node Scan on tenk1 "_REMOTE_TABLE_QUERY_"
- Coordinator quals: (unique1 > int4_tbl.f1)
-(5 rows)
-
-select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt
-from int4_tbl
-order by f1;
- f1 | gt
--------------+----
- -2147483647 | 0
- -123456 | 0
- 0 | 1
- 123456 |
- 2147483647 |
-(5 rows)
-
--- check some cases that were handled incorrectly in 8.3.0
-explain (costs off, nodes off)
- select distinct max(unique2) from tenk1;
- QUERY PLAN
-------------------------------------------------------------
- HashAggregate
- -> Aggregate
- -> Data Node Scan on tenk1 "_REMOTE_TABLE_QUERY_"
-(3 rows)
-
-select distinct max(unique2) from tenk1;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique2) from tenk1 order by 1;
- QUERY PLAN
-------------------------------------------------------------
- Sort
- Sort Key: (max(tenk1.unique2))
- -> Aggregate
- -> Data Node Scan on tenk1 "_REMOTE_TABLE_QUERY_"
-(4 rows)
-
-select max(unique2) from tenk1 order by 1;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique2) from tenk1 order by max(unique2);
- QUERY PLAN
-------------------------------------------------------------
- Sort
- Sort Key: (max(tenk1.unique2))
- -> Aggregate
- -> Data Node Scan on tenk1 "_REMOTE_TABLE_QUERY_"
-(4 rows)
-
-select max(unique2) from tenk1 order by max(unique2);
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique2) from tenk1 order by max(unique2)+1;
- QUERY PLAN
-------------------------------------------------------------
- Sort
- Sort Key: ((max(tenk1.unique2) + 1))
- -> Aggregate
- -> Data Node Scan on tenk1 "_REMOTE_TABLE_QUERY_"
-(4 rows)
-
-select max(unique2) from tenk1 order by max(unique2)+1;
- max
-------
- 9999
-(1 row)
-
-explain (costs off, nodes off)
- select max(unique2), generate_series(1,3) as g from tenk1 order by g desc;
- QUERY PLAN
-------------------------------------------------------------
- Sort
- Sort Key: (generate_series(1, 3))
- -> Aggregate
- -> Data Node Scan on tenk1 "_REMOTE_TABLE_QUERY_"
-(4 rows)
-
-select max(unique2), generate_series(1,3) as g from tenk1 order by g desc;
- max | g
-------+---
- 9999 | 3
- 9999 | 2
- 9999 | 1
-(3 rows)
-
--- try it on an inheritance tree
-create table minmaxtest(f1 int);
-create table minmaxtest1() inherits (minmaxtest);
-create table minmaxtest2() inherits (minmaxtest);
-create table minmaxtest3() inherits (minmaxtest);
-create index minmaxtesti on minmaxtest(f1);
-create index minmaxtest1i on minmaxtest1(f1);
-create index minmaxtest2i on minmaxtest2(f1 desc);
-create index minmaxtest3i on minmaxtest3(f1) where f1 is not null;
-insert into minmaxtest values(11), (12);
-insert into minmaxtest1 values(13), (14);
-insert into minmaxtest2 values(15), (16);
-insert into minmaxtest3 values(17), (18);
-explain (costs off, nodes off)
- select min(f1), max(f1) from minmaxtest;
- QUERY PLAN
-------------------------------------------------------------------
- Aggregate
- -> Append
- -> Data Node Scan on minmaxtest "_REMOTE_TABLE_QUERY_"
- -> Data Node Scan on minmaxtest1 "_REMOTE_TABLE_QUERY_"
- -> Data Node Scan on minmaxtest2 "_REMOTE_TABLE_QUERY_"
- -> Data Node Scan on minmaxtest3 "_REMOTE_TABLE_QUERY_"
-(6 rows)
-
-select min(f1), max(f1) from minmaxtest;
- min | max
------+-----
- 11 | 18
-(1 row)
-
-drop table minmaxtest cascade;
-NOTICE: drop cascades to 3 other objects
-DETAIL: drop cascades to table minmaxtest1
-drop cascades to table minmaxtest2
-drop cascades to table minmaxtest3
---
--- Test combinations of DISTINCT and/or ORDER BY
---
-select array_agg(a order by b)
- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b);
- array_agg
------------
- {3,4,2,1}
-(1 row)
-
-select array_agg(a order by a)
- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b);
- array_agg
------------
- {1,2,3,4}
-(1 row)
-
-select array_agg(a order by a desc)
- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b);
- array_agg
------------
- {4,3,2,1}
-(1 row)
-
-select array_agg(b order by a desc)
- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b);
- array_agg
------------
- {2,1,3,4}
-(1 row)
-
-select array_agg(distinct a)
- from (values (1),(2),(1),(3),(null),(2)) v(a);
- array_agg
---------------
- {1,2,3,NULL}
-(1 row)
-
-select array_agg(distinct a order by a)
- from (values (1),(2),(1),(3),(null),(2)) v(a);
- array_agg
---------------
- {1,2,3,NULL}
-(1 row)
-
-select array_agg(distinct a order by a desc)
- from (values (1),(2),(1),(3),(null),(2)) v(a);
- array_agg
---------------
- {NULL,3,2,1}
-(1 row)
-
-select array_agg(distinct a order by a desc nulls last)
- from (values (1),(2),(1),(3),(null),(2)) v(a);
- array_agg
---------------
- {3,2,1,NULL}
-(1 row)
-
--- multi-arg aggs, strict/nonstrict, distinct/order by
-select aggfstr(a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
- aggfstr
----------------------------------------
- {"(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select aggfns(a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
- aggfns
------------------------------------------------
- {"(1,3,foo)","(0,,)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select aggfstr(distinct a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
- aggfstr
----------------------------------------
- {"(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select aggfns(distinct a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
- aggfns
------------------------------------------------
- {"(0,,)","(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select aggfstr(distinct a,b,c order by b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
- aggfstr
----------------------------------------
- {"(3,1,baz)","(2,2,bar)","(1,3,foo)"}
-(1 row)
-
-select aggfns(distinct a,b,c order by b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
- aggfns
------------------------------------------------
- {"(3,1,baz)","(2,2,bar)","(1,3,foo)","(0,,)"}
-(1 row)
-
--- test specific code paths
-select aggfns(distinct a,a,c order by c using ~<~,a)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
- aggfns
-------------------------------------------------
- {"(2,2,bar)","(3,3,baz)","(1,1,foo)","(0,0,)"}
-(1 row)
-
-select aggfns(distinct a,a,c order by c using ~<~)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
- aggfns
-------------------------------------------------
- {"(2,2,bar)","(3,3,baz)","(1,1,foo)","(0,0,)"}
-(1 row)
-
-select aggfns(distinct a,a,c order by a)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
- aggfns
-------------------------------------------------
- {"(0,0,)","(1,1,foo)","(2,2,bar)","(3,3,baz)"}
-(1 row)
-
-select aggfns(distinct a,b,c order by a,c using ~<~,b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
- aggfns
------------------------------------------------
- {"(0,,)","(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
--- check node I/O via view creation and usage, also deparsing logic
-create view agg_view1 as
- select aggfns(a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(1,3,foo)","(0,,)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
---------------------------------------------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(v.a, v.b, v.c) AS aggfns FROM (VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(distinct a,b,c)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(0,,)","(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(DISTINCT v.a, v.b, v.c) AS aggfns FROM (VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c), generate_series(1, 3) i(i);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(distinct a,b,c order by b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,3) i;
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(3,1,baz)","(2,2,bar)","(1,3,foo)","(0,,)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(DISTINCT v.a, v.b, v.c ORDER BY v.b) AS aggfns FROM (VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c), generate_series(1, 3) i(i);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(a,b,c order by b+1)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(3,1,baz)","(2,2,bar)","(1,3,foo)","(0,,)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(v.a, v.b, v.c ORDER BY (v.b + 1)) AS aggfns FROM (VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(a,a,c order by b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
-select * from agg_view1;
- aggfns
-------------------------------------------------
- {"(3,3,baz)","(2,2,bar)","(1,1,foo)","(0,0,)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(v.a, v.a, v.c ORDER BY v.b) AS aggfns FROM (VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(a,b,c order by c using ~<~)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c);
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(2,2,bar)","(3,1,baz)","(1,3,foo)","(0,,)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(v.a, v.b, v.c ORDER BY v.c USING ~<~ NULLS LAST) AS aggfns FROM (VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c);
-(1 row)
-
-create or replace view agg_view1 as
- select aggfns(distinct a,b,c order by a,c using ~<~,b)
- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c),
- generate_series(1,2) i;
-select * from agg_view1;
- aggfns
------------------------------------------------
- {"(0,,)","(1,3,foo)","(2,2,bar)","(3,1,baz)"}
-(1 row)
-
-select pg_get_viewdef('agg_view1'::regclass);
- pg_get_viewdef
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- SELECT aggfns(DISTINCT v.a, v.b, v.c ORDER BY v.a, v.c USING ~<~ NULLS LAST, v.b) AS aggfns FROM (VALUES (1,3,'foo'::text), (0,NULL::integer,NULL::text), (2,2,'bar'::text), (3,1,'baz'::text)) v(a, b, c), generate_series(1, 2) i(i);
-(1 row)
-
-drop view agg_view1;
--- incorrect DISTINCT usage errors
-select aggfns(distinct a,b,c order by i)
- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i;
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select aggfns(distinct a,b,c order by i)
- ^
-select aggfns(distinct a,b,c order by a,b+1)
- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i;
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select aggfns(distinct a,b,c order by a,b+1)
- ^
-select aggfns(distinct a,b,c order by a,b,i,c)
- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i;
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select aggfns(distinct a,b,c order by a,b,i,c)
- ^
-select aggfns(distinct a,a,c order by a,b)
- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i;
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select aggfns(distinct a,a,c order by a,b)
- ^
--- string_agg tests
-select string_agg(a,',') from (values('aaaa'),('bbbb'),('cccc')) g(a);
- string_agg
-----------------
- aaaa,bbbb,cccc
-(1 row)
-
-select string_agg(a,',') from (values('aaaa'),(null),('bbbb'),('cccc')) g(a);
- string_agg
-----------------
- aaaa,bbbb,cccc
-(1 row)
-
-select string_agg(a,'AB') from (values(null),(null),('bbbb'),('cccc')) g(a);
- string_agg
-------------
- bbbbABcccc
-(1 row)
-
-select string_agg(a,',') from (values(null),(null)) g(a);
- string_agg
-------------
-
-(1 row)
-
--- check some implicit casting cases, as per bug #5564
-select string_agg(distinct f1, ',' order by f1) from varchar_tbl; -- ok
- string_agg
-------------
- a,ab,abcd
-(1 row)
-
-select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl; -- not ok
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select string_agg(distinct f1::text, ',' order by f1) from v...
- ^
-select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; -- not ok
-ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
-LINE 1: select string_agg(distinct f1, ',' order by f1::text) from v...
- ^
-select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -- ok
- string_agg
-------------
- a,ab,abcd
-(1 row)
-
--- string_agg bytea tests
-create table bytea_test_table(v bytea);
-select string_agg(v, '') from bytea_test_table;
- string_agg
-------------
-
-(1 row)
-
-insert into bytea_test_table values(decode('ff','hex'));
-select string_agg(v, '') from bytea_test_table;
- string_agg
-------------
- \xff
-(1 row)
-
-insert into bytea_test_table values(decode('aa','hex'));
-select string_agg(v, '') from bytea_test_table;
- string_agg
-------------
- \xaaff
-(1 row)
-
-select string_agg(v, NULL) from bytea_test_table;
- string_agg
-------------
- \xaaff
-(1 row)
-
-select string_agg(v, decode('ee', 'hex')) from bytea_test_table;
- string_agg
-------------
- \xaaeeff
-(1 row)
-
-drop table bytea_test_table;
-- 0 1 2 3
--
-- boxes are specified by two points, given by four floats x1,y1,x2,y2
-CREATE TABLE BOX_TBL (f1 box);
+-- Postgres-XL case: box type cannot use ORDER BY so its table
+-- is replicated for regression tests
+CREATE TABLE BOX_TBL (f1 box) DISTRIBUTE BY REPLICATION;
INSERT INTO BOX_TBL (f1) VALUES ('(2.0,2.0,0.0,0.0)');
INSERT INTO BOX_TBL (f1) VALUES ('(1.0,1.0,3.0,3.0)');
-- degenerate cases where the box is a line or a point
--
-- Test the SP-GiST index
--
-CREATE TEMPORARY TABLE box_temp (f1 box);
+CREATE TEMPORARY TABLE box_temp (f1 box) DISTRIBUTE BY REPLICATION;
INSERT INTO box_temp
SELECT box(point(i, i), point(i * 2, i * 2))
FROM generate_series(1, 50) AS i;
(7 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)';
- QUERY PLAN
-----------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 << '(30,40),(10,20)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 << '(30,40),(10,20)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
f1
(8 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
- QUERY PLAN
-----------------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 &< '(10,100),(5,4.333334)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 &< '(10,100),(5,4.333334)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
f1
(17 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
- QUERY PLAN
-----------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 && '(25,30),(15,20)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 && '(25,30),(15,20)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
f1
(11 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
- QUERY PLAN
-----------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 &> '(45,50),(40,30)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 &> '(45,50),(40,30)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
f1
(10 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
- QUERY PLAN
-----------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 >> '(40,40),(30,30)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 >> '(40,40),(30,30)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
f1
(3 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
- QUERY PLAN
-----------------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 <<| '(10,100),(5,4.33334)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 <<| '(10,100),(5,4.33334)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
f1
(3 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
- QUERY PLAN
-----------------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 &<| '(10,4.3333334),(5,1)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 &<| '(10,4.3333334),(5,1)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
f1
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
- QUERY PLAN
------------------------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 |&> '(49.99,49.99),(49.99,49.99)'::box)
-(2 rows)
+ QUERY PLAN
+-----------------------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 |&> '(49.99,49.99),(49.99,49.99)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
f1
(11 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
- QUERY PLAN
------------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 |>> '(39,40),(37,38)'::box)
-(2 rows)
+ QUERY PLAN
+-----------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 |>> '(39,40),(37,38)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)';
f1
(4 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)';
- QUERY PLAN
-----------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 @> '(15,15),(10,11)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 @> '(15,15),(10,11)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
f1
(1 row)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
- QUERY PLAN
-----------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 <@ '(30,35),(10,15)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 <@ '(30,35),(10,15)'::box)
+(4 rows)
SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
f1
(1 row)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
- QUERY PLAN
-----------------------------------------------
- Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 ~= '(40,40),(20,20)'::box)
-(2 rows)
+ QUERY PLAN
+----------------------------------------------------
+ Remote Fast Query Execution
+ Node/s: datanode_1
+ -> Index Only Scan using box_spgist on box_temp
+ Index Cond: (f1 ~= '(40,40),(20,20)'::box)
+(4 rows)
RESET enable_seqscan;
DROP INDEX box_spgist;
+++ /dev/null
---
--- BOX
---
---
--- box logic
--- o
--- 3 o--|X
--- | o|
--- 2 +-+-+ |
--- | | | |
--- 1 | o-+-o
--- | |
--- 0 +---+
---
--- 0 1 2 3
---
--- boxes are specified by two points, given by four floats x1,y1,x2,y2
--- Postgres-XL case: box type cannot use ORDER BY so its table
--- is replicated for regression tests
-CREATE TABLE BOX_TBL (f1 box) DISTRIBUTE BY REPLICATION;
-INSERT INTO BOX_TBL (f1) VALUES ('(2.0,2.0,0.0,0.0)');
-INSERT INTO BOX_TBL (f1) VALUES ('(1.0,1.0,3.0,3.0)');
--- degenerate cases where the box is a line or a point
--- note that lines and points boxes all have zero area
-INSERT INTO BOX_TBL (f1) VALUES ('(2.5, 2.5, 2.5,3.5)');
-INSERT INTO BOX_TBL (f1) VALUES ('(3.0, 3.0,3.0,3.0)');
--- badly formatted box inputs
-INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)');
-ERROR: invalid input syntax for type box: "(2.3, 4.5)"
-LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)');
- ^
-INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad');
-ERROR: invalid input syntax for type box: "asdfasdf(ad"
-LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad');
- ^
-SELECT '' AS four, * FROM BOX_TBL;
- four | f1
-------+---------------------
- | (2,2),(0,0)
- | (3,3),(1,1)
- | (2.5,3.5),(2.5,2.5)
- | (3,3),(3,3)
-(4 rows)
-
-SELECT '' AS four, b.*, area(b.f1) as barea
- FROM BOX_TBL b ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- four | f1 | barea
-------+---------------------+-------
- | (2,2),(0,0) | 4
- | (2.5,3.5),(2.5,2.5) | 0
- | (3,3),(1,1) | 4
- | (3,3),(3,3) | 0
-(4 rows)
-
--- overlap
-SELECT '' AS three, b.f1
- FROM BOX_TBL b
- WHERE b.f1 && box '(2.5,2.5,1.0,1.0)' ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- three | f1
--------+---------------------
- | (2,2),(0,0)
- | (2.5,3.5),(2.5,2.5)
- | (3,3),(1,1)
-(3 rows)
-
--- left-or-overlap (x only)
-SELECT '' AS two, b1.*
- FROM BOX_TBL b1
- WHERE b1.f1 &< box '(2.0,2.0,2.5,2.5)' ORDER BY (b1.f1[0])[0], (b1.f1[0])[1], (b1.f1[2])[0], (b1.f1[2])[1];
- two | f1
------+---------------------
- | (2,2),(0,0)
- | (2.5,3.5),(2.5,2.5)
-(2 rows)
-
--- right-or-overlap (x only)
-SELECT '' AS two, b1.*
- FROM BOX_TBL b1
- WHERE b1.f1 &> box '(2.0,2.0,2.5,2.5)' ORDER BY (b1.f1[0])[0], (b1.f1[0])[1], (b1.f1[2])[0], (b1.f1[2])[1];
- two | f1
------+---------------------
- | (2.5,3.5),(2.5,2.5)
- | (3,3),(3,3)
-(2 rows)
-
--- left of
-SELECT '' AS two, b.f1
- FROM BOX_TBL b
- WHERE b.f1 << box '(3.0,3.0,5.0,5.0)' ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- two | f1
------+---------------------
- | (2,2),(0,0)
- | (2.5,3.5),(2.5,2.5)
-(2 rows)
-
--- area <=
-SELECT '' AS four, b.f1
- FROM BOX_TBL b
- WHERE b.f1 <= box '(3.0,3.0,5.0,5.0)' ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- four | f1
-------+---------------------
- | (2,2),(0,0)
- | (2.5,3.5),(2.5,2.5)
- | (3,3),(1,1)
- | (3,3),(3,3)
-(4 rows)
-
--- area <
-SELECT '' AS two, b.f1
- FROM BOX_TBL b
- WHERE b.f1 < box '(3.0,3.0,5.0,5.0)' ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- two | f1
------+---------------------
- | (2.5,3.5),(2.5,2.5)
- | (3,3),(3,3)
-(2 rows)
-
--- area =
-SELECT '' AS two, b.f1
- FROM BOX_TBL b
- WHERE b.f1 = box '(3.0,3.0,5.0,5.0)' ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- two | f1
------+-------------
- | (2,2),(0,0)
- | (3,3),(1,1)
-(2 rows)
-
--- area >
-SELECT '' AS two, b.f1
- FROM BOX_TBL b -- zero area
- WHERE b.f1 > box '(3.5,3.0,4.5,3.0)' ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- two | f1
------+-------------
- | (2,2),(0,0)
- | (3,3),(1,1)
-(2 rows)
-
--- area >=
-SELECT '' AS four, b.f1
- FROM BOX_TBL b -- zero area
- WHERE b.f1 >= box '(3.5,3.0,4.5,3.0)' ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- four | f1
-------+---------------------
- | (2,2),(0,0)
- | (2.5,3.5),(2.5,2.5)
- | (3,3),(1,1)
- | (3,3),(3,3)
-(4 rows)
-
--- right of
-SELECT '' AS two, b.f1
- FROM BOX_TBL b
- WHERE box '(3.0,3.0,5.0,5.0)' >> b.f1 ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- two | f1
------+---------------------
- | (2,2),(0,0)
- | (2.5,3.5),(2.5,2.5)
-(2 rows)
-
--- contained in
-SELECT '' AS three, b.f1
- FROM BOX_TBL b
- WHERE b.f1 <@ box '(0,0,3,3)' ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- three | f1
--------+-------------
- | (2,2),(0,0)
- | (3,3),(1,1)
- | (3,3),(3,3)
-(3 rows)
-
--- contains
-SELECT '' AS three, b.f1
- FROM BOX_TBL b
- WHERE box '(0,0,3,3)' @> b.f1 ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- three | f1
--------+-------------
- | (2,2),(0,0)
- | (3,3),(1,1)
- | (3,3),(3,3)
-(3 rows)
-
--- box equality
-SELECT '' AS one, b.f1
- FROM BOX_TBL b
- WHERE box '(1,1,3,3)' ~= b.f1 ORDER BY (b.f1[0])[0], (b.f1[0])[1], (b.f1[2])[0], (b.f1[2])[1];
- one | f1
------+-------------
- | (3,3),(1,1)
-(1 row)
-
--- center of box, left unary operator
-SELECT '' AS four, @@(b1.f1) AS p
- FROM BOX_TBL b1 ORDER BY (b1.f1[0])[0], (b1.f1[0])[1], (b1.f1[2])[0], (b1.f1[2])[1];
- four | p
-------+---------
- | (1,1)
- | (2.5,3)
- | (2,2)
- | (3,3)
-(4 rows)
-
--- wholly-contained
-SELECT '' AS one, b1.*, b2.*
- FROM BOX_TBL b1, BOX_TBL b2
- WHERE b1.f1 @> b2.f1 and not b1.f1 ~= b2.f1
- ORDER BY (b1.f1[0])[0], (b1.f1[0])[1], (b1.f1[2])[0], (b1.f1[2])[1], (b2.f1[0])[0], (b2.f1[0])[1], (b2.f1[2])[0], (b2.f1[2])[1];
- one | f1 | f1
------+-------------+-------------
- | (3,3),(1,1) | (3,3),(3,3)
-(1 row)
-
-SELECT '' AS four, height(f1), width(f1) FROM BOX_TBL ORDER BY (f1[0])[0], (f1[0])[1], (f1[2])[0], (f1[2])[1];
- four | height | width
-------+--------+-------
- | 2 | 2
- | 1 | 0
- | 2 | 2
- | 0 | 0
-(4 rows)
-
---
--- Test the SP-GiST index
---
-CREATE TEMPORARY TABLE box_temp (f1 box) DISTRIBUTE BY REPLICATION;
-INSERT INTO box_temp
- SELECT box(point(i, i), point(i * 2, i * 2))
- FROM generate_series(1, 50) AS i;
-CREATE INDEX box_spgist ON box_temp USING spgist (f1);
-INSERT INTO box_temp
- VALUES (NULL),
- ('(0,0)(0,100)'),
- ('(-3,4.3333333333)(40,1)'),
- ('(0,100)(0,infinity)'),
- ('(-infinity,0)(0,infinity)'),
- ('(-infinity,-infinity)(infinity,infinity)');
-SET enable_seqscan = false;
-SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)';
- f1
-----------------------------
- (2,2),(1,1)
- (4,4),(2,2)
- (6,6),(3,3)
- (8,8),(4,4)
- (0,100),(0,0)
- (0,Infinity),(0,100)
- (0,Infinity),(-Infinity,0)
-(7 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)';
- QUERY PLAN
-----------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 << '(30,40),(10,20)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
- f1
-----------------------------
- (2,2),(1,1)
- (4,4),(2,2)
- (6,6),(3,3)
- (8,8),(4,4)
- (10,10),(5,5)
- (0,100),(0,0)
- (0,Infinity),(0,100)
- (0,Infinity),(-Infinity,0)
-(8 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
- QUERY PLAN
-----------------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 &< '(10,100),(5,4.333334)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
- f1
--------------------------------------------
- (20,20),(10,10)
- (22,22),(11,11)
- (24,24),(12,12)
- (26,26),(13,13)
- (28,28),(14,14)
- (30,30),(15,15)
- (32,32),(16,16)
- (34,34),(17,17)
- (36,36),(18,18)
- (38,38),(19,19)
- (40,40),(20,20)
- (42,42),(21,21)
- (44,44),(22,22)
- (46,46),(23,23)
- (48,48),(24,24)
- (50,50),(25,25)
- (Infinity,Infinity),(-Infinity,-Infinity)
-(17 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
- QUERY PLAN
-----------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 && '(25,30),(15,20)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
- f1
--------------------
- (80,80),(40,40)
- (82,82),(41,41)
- (84,84),(42,42)
- (86,86),(43,43)
- (88,88),(44,44)
- (90,90),(45,45)
- (92,92),(46,46)
- (94,94),(47,47)
- (96,96),(48,48)
- (98,98),(49,49)
- (100,100),(50,50)
-(11 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
- QUERY PLAN
-----------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 &> '(45,50),(40,30)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
- f1
--------------------
- (82,82),(41,41)
- (84,84),(42,42)
- (86,86),(43,43)
- (88,88),(44,44)
- (90,90),(45,45)
- (92,92),(46,46)
- (94,94),(47,47)
- (96,96),(48,48)
- (98,98),(49,49)
- (100,100),(50,50)
-(10 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
- QUERY PLAN
-----------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 >> '(40,40),(30,30)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
- f1
---------------------------
- (2,2),(1,1)
- (4,4),(2,2)
- (40,4.3333333333),(-3,1)
-(3 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
- QUERY PLAN
-----------------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 <<| '(10,100),(5,4.33334)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
- f1
---------------------------
- (2,2),(1,1)
- (4,4),(2,2)
- (40,4.3333333333),(-3,1)
-(3 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
- QUERY PLAN
-----------------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 &<| '(10,4.3333334),(5,1)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
- f1
-----------------------
- (100,100),(50,50)
- (0,Infinity),(0,100)
-(2 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
- QUERY PLAN
------------------------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 |&> '(49.99,49.99),(49.99,49.99)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
- f1
-----------------------
- (82,82),(41,41)
- (84,84),(42,42)
- (86,86),(43,43)
- (88,88),(44,44)
- (90,90),(45,45)
- (92,92),(46,46)
- (94,94),(47,47)
- (96,96),(48,48)
- (98,98),(49,49)
- (100,100),(50,50)
- (0,Infinity),(0,100)
-(11 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
- QUERY PLAN
------------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 |>> '(39,40),(37,38)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)';
- f1
--------------------------------------------
- (16,16),(8,8)
- (18,18),(9,9)
- (20,20),(10,10)
- (Infinity,Infinity),(-Infinity,-Infinity)
-(4 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)';
- QUERY PLAN
-----------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 @> '(15,15),(10,11)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
- f1
------------------
- (30,30),(15,15)
-(1 row)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
- QUERY PLAN
-----------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 <@ '(30,35),(10,15)'::box)
-(4 rows)
-
-SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
- f1
------------------
- (40,40),(20,20)
-(1 row)
-
-EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
- QUERY PLAN
-----------------------------------------------------
- Remote Fast Query Execution
- Node/s: datanode_1
- -> Index Only Scan using box_spgist on box_temp
- Index Cond: (f1 ~= '(40,40),(20,20)'::box)
-(4 rows)
-
-RESET enable_seqscan;
-DROP INDEX box_spgist;
+++ /dev/null
---
--- CASE
--- Test the case statement
---
-CREATE TABLE CASE_TBL (
- i integer,
- f double precision
-);
-CREATE TABLE CASE2_TBL (
- i integer,
- j integer
-);
-INSERT INTO CASE_TBL VALUES (1, 10.1);
-INSERT INTO CASE_TBL VALUES (2, 20.2);
-INSERT INTO CASE_TBL VALUES (3, -30.3);
-INSERT INTO CASE_TBL VALUES (4, NULL);
-INSERT INTO CASE2_TBL VALUES (1, -1);
-INSERT INTO CASE2_TBL VALUES (2, -2);
-INSERT INTO CASE2_TBL VALUES (3, -3);
-INSERT INTO CASE2_TBL VALUES (2, -4);
-INSERT INTO CASE2_TBL VALUES (1, NULL);
-INSERT INTO CASE2_TBL VALUES (NULL, -6);
---
--- Simplest examples without tables
---
-SELECT '3' AS "One",
- CASE
- WHEN 1 < 2 THEN 3
- END AS "Simple WHEN";
- One | Simple WHEN
------+-------------
- 3 | 3
-(1 row)
-
-SELECT '<NULL>' AS "One",
- CASE
- WHEN 1 > 2 THEN 3
- END AS "Simple default";
- One | Simple default
---------+----------------
- <NULL> |
-(1 row)
-
-SELECT '3' AS "One",
- CASE
- WHEN 1 < 2 THEN 3
- ELSE 4
- END AS "Simple ELSE";
- One | Simple ELSE
------+-------------
- 3 | 3
-(1 row)
-
-SELECT '4' AS "One",
- CASE
- WHEN 1 > 2 THEN 3
- ELSE 4
- END AS "ELSE default";
- One | ELSE default
------+--------------
- 4 | 4
-(1 row)
-
-SELECT '6' AS "One",
- CASE
- WHEN 1 > 2 THEN 3
- WHEN 4 < 5 THEN 6
- ELSE 7
- END AS "Two WHEN with default";
- One | Two WHEN with default
------+-----------------------
- 6 | 6
-(1 row)
-
--- Constant-expression folding shouldn't evaluate unreachable subexpressions
-SELECT CASE WHEN 1=0 THEN 1/0 WHEN 1=1 THEN 1 ELSE 2/0 END;
- case
-------
- 1
-(1 row)
-
-SELECT CASE 1 WHEN 0 THEN 1/0 WHEN 1 THEN 1 ELSE 2/0 END;
- case
-------
- 1
-(1 row)
-
--- However we do not currently suppress folding of potentially
--- reachable subexpressions
-SELECT CASE WHEN i > 100 THEN 1/0 ELSE 0 END FROM case_tbl;
-ERROR: division by zero
--- Test for cases involving untyped literals in test expression
-SELECT CASE 'a' WHEN 'a' THEN 1 ELSE 2 END;
- case
-------
- 1
-(1 row)
-
---
--- Examples of targets involving tables
---
-SELECT '' AS "Five",
- CASE
- WHEN i >= 3 THEN i
- END AS ">= 3 or Null"
- FROM CASE_TBL
- ORDER BY 2;
- Five | >= 3 or Null
-------+--------------
- | 3
- | 4
- |
- |
-(4 rows)
-
-SELECT '' AS "Five",
- CASE WHEN i >= 3 THEN (i + i)
- ELSE i
- END AS "Simplest Math"
- FROM CASE_TBL
- ORDER BY 2;
- Five | Simplest Math
-------+---------------
- | 1
- | 2
- | 6
- | 8
-(4 rows)
-
-SELECT '' AS "Five", i AS "Value",
- CASE WHEN (i < 0) THEN 'small'
- WHEN (i = 0) THEN 'zero'
- WHEN (i = 1) THEN 'one'
- WHEN (i = 2) THEN 'two'
- ELSE 'big'
- END AS "Category"
- FROM CASE_TBL
- ORDER BY 2, 3;
- Five | Value | Category
-------+-------+----------
- | 1 | one
- | 2 | two
- | 3 | big
- | 4 | big
-(4 rows)
-
-SELECT '' AS "Five",
- CASE WHEN ((i < 0) or (i < 0)) THEN 'small'
- WHEN ((i = 0) or (i = 0)) THEN 'zero'
- WHEN ((i = 1) or (i = 1)) THEN 'one'
- WHEN ((i = 2) or (i = 2)) THEN 'two'
- ELSE 'big'
- END AS "Category"
- FROM CASE_TBL
- ORDER BY 2;
- Five | Category
-------+----------
- | big
- | big
- | one
- | two
-(4 rows)
-
---
--- Examples of qualifications involving tables
---
---
--- NULLIF() and COALESCE()
--- Shorthand forms for typical CASE constructs
--- defined in the SQL standard.
---
-SELECT * FROM CASE_TBL WHERE COALESCE(f,i) = 4;
- i | f
----+---
- 4 |
-(1 row)
-
-SELECT * FROM CASE_TBL WHERE NULLIF(f,i) = 2;
- i | f
----+---
-(0 rows)
-
-SELECT COALESCE(a.f, b.i, b.j)
- FROM CASE_TBL a, CASE2_TBL b
- ORDER BY coalesce;
- coalesce
-----------
- -30.3
- -30.3
- -30.3
- -30.3
- -30.3
- -30.3
- -6
- 1
- 1
- 2
- 2
- 3
- 10.1
- 10.1
- 10.1
- 10.1
- 10.1
- 10.1
- 20.2
- 20.2
- 20.2
- 20.2
- 20.2
- 20.2
-(24 rows)
-
-SELECT *
- FROM CASE_TBL a, CASE2_TBL b
- WHERE COALESCE(a.f, b.i, b.j) = 2
- ORDER BY a.i, a.f, b.i, b.j;
- i | f | i | j
----+---+---+----
- 4 | | 2 | -4
- 4 | | 2 | -2
-(2 rows)
-
-SELECT '' AS Five, NULLIF(a.i,b.i) AS "NULLIF(a.i,b.i)",
- NULLIF(b.i, 4) AS "NULLIF(b.i,4)"
- FROM CASE_TBL a, CASE2_TBL b
- ORDER BY 2, 3;
- five | NULLIF(a.i,b.i) | NULLIF(b.i,4)
-------+-----------------+---------------
- | 1 | 2
- | 1 | 2
- | 1 | 3
- | 1 |
- | 2 | 1
- | 2 | 1
- | 2 | 3
- | 2 |
- | 3 | 1
- | 3 | 1
- | 3 | 2
- | 3 | 2
- | 3 |
- | 4 | 1
- | 4 | 1
- | 4 | 2
- | 4 | 2
- | 4 | 3
- | 4 |
- | | 1
- | | 1
- | | 2
- | | 2
- | | 3
-(24 rows)
-
-SELECT '' AS "Two", *
- FROM CASE_TBL a, CASE2_TBL b
- WHERE COALESCE(f,b.i) = 2
- ORDER BY a.i, a.f, b.i, b.j;
- Two | i | f | i | j
------+---+---+---+----
- | 4 | | 2 | -4
- | 4 | | 2 | -2
-(2 rows)
-
---
--- Examples of updates involving tables
---
-UPDATE CASE_TBL
- SET i = CASE WHEN i >= 3 THEN (- i)
- ELSE (2 * i) END;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM CASE_TBL ORDER BY i, f;
- i | f
----+-------
- 1 | 10.1
- 2 | 20.2
- 3 | -30.3
- 4 |
-(4 rows)
-
-UPDATE CASE_TBL
- SET i = CASE WHEN i >= 2 THEN (2 * i)
- ELSE (3 * i) END;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM CASE_TBL ORDER BY i, f;
- i | f
----+-------
- 1 | 10.1
- 2 | 20.2
- 3 | -30.3
- 4 |
-(4 rows)
-
-UPDATE CASE_TBL
- SET i = CASE WHEN b.i >= 2 THEN (2 * j)
- ELSE (3 * j) END
- FROM CASE2_TBL b
- WHERE j = -CASE_TBL.i;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM CASE_TBL ORDER BY i, f;
- i | f
----+-------
- 1 | 10.1
- 2 | 20.2
- 3 | -30.3
- 4 |
-(4 rows)
-
---
--- Clean up
---
-DROP TABLE CASE_TBL;
-DROP TABLE CASE2_TBL;
+++ /dev/null
-/*
- * This test is intended to pass on all platforms supported by Postgres.
- * We can therefore only assume that the default, C, and POSIX collations
- * are available --- and since the regression tests are often run in a
- * C-locale database, these may well all have the same behavior. But
- * fortunately, the system doesn't know that and will treat them as
- * incompatible collations. It is therefore at least possible to test
- * parser behaviors such as collation conflict resolution. This test will,
- * however, be more revealing when run in a database with non-C locale,
- * since any departure from C sorting behavior will show as a failure.
- */
-CREATE SCHEMA collate_tests;
-SET search_path = collate_tests;
-CREATE TABLE collate_test1 (
- a int,
- b text COLLATE "C" NOT NULL
-);
-\d collate_test1
- Table "collate_tests.collate_test1"
- Column | Type | Modifiers
---------+---------+--------------------
- a | integer |
- b | text | collate C not null
-
-CREATE TABLE collate_test_fail (
- a int COLLATE "C",
- b text
-);
-ERROR: collations are not supported by type integer
-LINE 2: a int COLLATE "C",
- ^
-CREATE TABLE collate_test_like (
- LIKE collate_test1
-);
-\d collate_test_like
-Table "collate_tests.collate_test_like"
- Column | Type | Modifiers
---------+---------+--------------------
- a | integer |
- b | text | collate C not null
-
-CREATE TABLE collate_test2 (
- a int,
- b text COLLATE "POSIX"
-);
-INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'Abc'), (3, 'bbc'), (4, 'ABD');
-INSERT INTO collate_test2 SELECT * FROM collate_test1;
-SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc' ORDER BY a;
- a | b
----+-----
- 1 | abc
- 3 | bbc
-(2 rows)
-
-SELECT * FROM collate_test1 WHERE b >= 'abc' COLLATE "C" ORDER BY a;
- a | b
----+-----
- 1 | abc
- 3 | bbc
-(2 rows)
-
-SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc' COLLATE "C" ORDER BY a;
- a | b
----+-----
- 1 | abc
- 3 | bbc
-(2 rows)
-
-SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "POSIX" ORDER BY a; -- fail
-ERROR: collation mismatch between explicit collations "C" and "POSIX"
-LINE 1: ...* FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "P...
- ^
-CREATE DOMAIN testdomain_p AS text COLLATE "POSIX";
-CREATE DOMAIN testdomain_i AS int COLLATE "POSIX"; -- fail
-ERROR: collations are not supported by type integer
-CREATE TABLE collate_test4 (
- a int,
- b testdomain_p
-);
-INSERT INTO collate_test4 SELECT * FROM collate_test1;
-SELECT a, b FROM collate_test4 ORDER BY b;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-CREATE TABLE collate_test5 (
- a int,
- b testdomain_p COLLATE "C"
-);
-INSERT INTO collate_test5 SELECT * FROM collate_test1;
-SELECT a, b FROM collate_test5 ORDER BY b;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, b FROM collate_test1 ORDER BY b;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, b FROM collate_test2 ORDER BY b;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C";
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
--- star expansion
-SELECT * FROM collate_test1 ORDER BY b;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT * FROM collate_test2 ORDER BY b;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
--- constant expression folding
-SELECT 'bbc' COLLATE "C" > 'Abc' COLLATE "C" AS "true";
- true
-------
- t
-(1 row)
-
-SELECT 'bbc' COLLATE "POSIX" < 'Abc' COLLATE "POSIX" AS "false";
- false
--------
- f
-(1 row)
-
--- upper/lower
-CREATE TABLE collate_test10 (
- a int,
- x text COLLATE "C",
- y text COLLATE "POSIX"
-);
-INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ');
-SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10 ORDER BY a;
- a | lower | lower | upper | upper | initcap | initcap
----+-------+-------+-------+-------+---------+---------
- 1 | hij | hij | HIJ | HIJ | Hij | Hij
- 2 | hij | hij | HIJ | HIJ | Hij | Hij
-(2 rows)
-
-SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10 ORDER BY a;
- a | lower | lower
----+-------+-------
- 1 | hij | hij
- 2 | hij | hij
-(2 rows)
-
-SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a;
- a | x | y
----+-----+-----
- 1 | hij | hij
- 2 | HIJ | HIJ
-(2 rows)
-
--- backwards parsing
-CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc';
-CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C";
-CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "POSIX") FROM collate_test10;
-SELECT table_name, view_definition FROM information_schema.views
- WHERE table_name LIKE 'collview%' ORDER BY 1;
- table_name | view_definition
-------------+------------------------------------------------------------------------------------------------------------------------
- collview1 | SELECT collate_test1.a, collate_test1.b FROM collate_test1 WHERE ((collate_test1.b COLLATE "C") >= 'bbc'::text);
- collview2 | SELECT collate_test1.a, collate_test1.b FROM collate_test1 ORDER BY (collate_test1.b COLLATE "C");
- collview3 | SELECT collate_test10.a, lower(((collate_test10.x || collate_test10.x) COLLATE "POSIX")) AS lower FROM collate_test10;
-(3 rows)
-
--- collation propagation in various expression type
-SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2;
- a | coalesce
----+----------
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2;
- a | coalesce
----+----------
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10 ORDER BY a;
- a | lower | lower
----+-------+-------
- 1 | hij | hij
- 2 | hij | hij
-(2 rows)
-
-SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3,1;
- a | b | greatest
----+-----+----------
- 2 | Abc | CCC
- 4 | ABD | CCC
- 1 | abc | abc
- 3 | bbc | bbc
-(4 rows)
-
-SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3,1;
- a | b | greatest
----+-----+----------
- 2 | Abc | CCC
- 4 | ABD | CCC
- 1 | abc | abc
- 3 | bbc | bbc
-(4 rows)
-
-SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10 ORDER BY a;
- a | x | y | lower | lower
----+-----+-----+-------+-------
- 1 | hij | hij | hij | hij
- 2 | HIJ | HIJ | foo | foo
-(2 rows)
-
-SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2;
- a | nullif
----+--------
- 4 | ABD
- 2 | Abc
- 3 | bbc
- 1 |
-(4 rows)
-
-SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2;
- a | nullif
----+--------
- 4 | ABD
- 2 | Abc
- 3 | bbc
- 1 |
-(4 rows)
-
-SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10 ORDER BY a;
- a | lower | lower
----+-------+-------
- 1 | hij | hij
- 2 | hij | hij
-(2 rows)
-
-SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2;
- a | b
----+------
- 4 | ABD
- 2 | Abc
- 1 | abcd
- 3 | bbc
-(4 rows)
-
-SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2;
- a | b
----+------
- 4 | ABD
- 2 | Abc
- 1 | abcd
- 3 | bbc
-(4 rows)
-
-CREATE DOMAIN testdomain AS text;
-SELECT a, b::testdomain FROM collate_test1 ORDER BY 2;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, b::testdomain FROM collate_test2 ORDER BY 2;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, b::testdomain_p FROM collate_test2 ORDER BY 2;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10 ORDER BY 2;
- a | lower | lower
----+-------+-------
- 1 | hij | hij
- 2 | hij | hij
-(2 rows)
-
-SELECT min(b), max(b) FROM collate_test1;
- min | max
------+-----
- ABD | bbc
-(1 row)
-
-SELECT min(b), max(b) FROM collate_test2;
- min | max
------+-----
- ABD | bbc
-(1 row)
-
-SELECT array_agg(b ORDER BY b) FROM collate_test1;
- array_agg
--------------------
- {ABD,Abc,abc,bbc}
-(1 row)
-
-SELECT array_agg(b ORDER BY b) FROM collate_test2;
- array_agg
--------------------
- {ABD,Abc,abc,bbc}
-(1 row)
-
-SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2;
- a | b
----+-----
- 4 | ABD
- 4 | ABD
- 2 | Abc
- 2 | Abc
- 1 | abc
- 1 | abc
- 3 | bbc
- 3 | bbc
-(8 rows)
-
-SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, b FROM collate_test2 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test2 WHERE a > 1 ORDER BY 2;
- a | b
----+-----
- 2 | Abc
- 3 | bbc
-(2 rows)
-
-SELECT a, b FROM collate_test2 EXCEPT SELECT a, b FROM collate_test2 WHERE a < 2 ORDER BY 2;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 3 | bbc
-(3 rows)
-
-SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
-ERROR: could not determine which collation to use for string comparison
-HINT: Use the COLLATE clause to set the collation explicitly.
-(SELECT a, b FROM collate_test1 ORDER BY 1) UNION ALL (SELECT a, b FROM collate_test2 ORDER BY 1); -- ok
- a | b
----+-----
- 1 | abc
- 2 | Abc
- 3 | bbc
- 4 | ABD
- 1 | abc
- 2 | Abc
- 3 | bbc
- 4 | ABD
-(8 rows)
-
-SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
-ERROR: collation mismatch between implicit collations "C" and "POSIX"
-LINE 1: SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collat...
- ^
-HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
-SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; -- ok
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
-ERROR: collation mismatch between implicit collations "C" and "POSIX"
-LINE 1: ...ELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM col...
- ^
-HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
-SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
-ERROR: collation mismatch between implicit collations "C" and "POSIX"
-LINE 1: SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM colla...
- ^
-HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
-CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; -- fail
--- ideally this would be a parse-time error, but for now it must be run-time:
-select x < y from collate_test10; -- fail
-ERROR: could not determine which collation to use for string comparison
-select x || y from collate_test10; -- ok, because || is not collation aware
- ?column?
-----------
- hijhij
- HIJHIJ
-(2 rows)
-
-select x, y from collate_test10 order by x || y; -- not so ok
-ERROR: collation mismatch between implicit collations "C" and "POSIX"
-LINE 1: select x, y from collate_test10 order by x || y;
- ^
-HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
--- collation mismatch between recursive and non-recursive term
-WITH RECURSIVE foo(x) AS
- (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x)
- UNION ALL
- SELECT (x || 'c') COLLATE "POSIX" FROM foo WHERE length(x) < 10)
-SELECT * FROM foo;
-ERROR: recursive query "foo" column 1 has collation "C" in non-recursive term but collation "POSIX" overall
-LINE 2: (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x)
- ^
-HINT: Use the COLLATE clause to set the collation of the non-recursive term.
-SELECT a, b, a < b as lt FROM
- (VALUES ('a', 'B'), ('A', 'b' COLLATE "C")) v(a,b) ORDER BY a;
- a | b | lt
----+---+----
- A | b | t
- a | B | f
-(2 rows)
-
--- casting
-SELECT CAST('42' AS text COLLATE "C");
-ERROR: syntax error at or near "COLLATE"
-LINE 1: SELECT CAST('42' AS text COLLATE "C");
- ^
-SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2;
- a | b
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
--- polymorphism
-SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1;
- unnest
---------
- ABD
- Abc
- abc
- bbc
-(4 rows)
-
-SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1;
- unnest
---------
- ABD
- Abc
- abc
- bbc
-(4 rows)
-
-CREATE FUNCTION dup (anyelement) RETURNS anyelement
- AS 'select $1' LANGUAGE sql;
-SELECT a, dup(b) FROM collate_test1 ORDER BY 2;
- a | dup
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
-SELECT a, dup(b) FROM collate_test2 ORDER BY 2;
- a | dup
----+-----
- 4 | ABD
- 2 | Abc
- 1 | abc
- 3 | bbc
-(4 rows)
-
--- indexes
-CREATE INDEX collate_test1_idx1 ON collate_test1 (b);
-CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "POSIX");
-CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "POSIX")); -- this is different grammatically
-CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX"));
-CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "POSIX"); -- fail
-ERROR: collations are not supported by type integer
-CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "POSIX")); -- fail
-ERROR: collations are not supported by type integer
-LINE 1: ...ATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "P...
- ^
-SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1;
- relname | pg_get_indexdef
---------------------+-----------------------------------------------------------------------------------------------------
- collate_test1_idx1 | CREATE INDEX collate_test1_idx1 ON collate_test1 USING btree (b)
- collate_test1_idx2 | CREATE INDEX collate_test1_idx2 ON collate_test1 USING btree (b COLLATE "POSIX")
- collate_test1_idx3 | CREATE INDEX collate_test1_idx3 ON collate_test1 USING btree (b COLLATE "POSIX")
- collate_test1_idx4 | CREATE INDEX collate_test1_idx4 ON collate_test1 USING btree (((b || 'foo'::text)) COLLATE "POSIX")
-(4 rows)
-
--- foreign keys
--- force indexes and mergejoins to be used for FK checking queries,
--- else they might not exercise collation-dependent operators
-SET enable_seqscan TO 0;
-SET enable_hashjoin TO 0;
-SET enable_nestloop TO 0;
-CREATE TABLE collate_test20 (f1 text COLLATE "C" PRIMARY KEY);
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "collate_test20_pkey" for table "collate_test20"
-INSERT INTO collate_test20 VALUES ('foo'), ('bar');
-CREATE TABLE collate_test21 (f2 text COLLATE "POSIX" REFERENCES collate_test20);
-INSERT INTO collate_test21 VALUES ('foo'), ('bar');
-INSERT INTO collate_test21 VALUES ('baz'); -- fail
-ERROR: insert or update on table "collate_test21" violates foreign key constraint "collate_test21_f2_fkey"
-DETAIL: Key (f2)=(baz) is not present in table "collate_test20".
-CREATE TABLE collate_test22 (f2 text COLLATE "POSIX");
-INSERT INTO collate_test22 VALUES ('foo'), ('bar'), ('baz');
-ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20; -- fail
-ERROR: insert or update on table "collate_test22" violates foreign key constraint "collate_test22_f2_fkey"
-DETAIL: Key (f2)=(baz) is not present in table "collate_test20".
-DELETE FROM collate_test22 WHERE f2 = 'baz';
-ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20;
-RESET enable_seqscan;
-RESET enable_hashjoin;
-RESET enable_nestloop;
---
--- Clean up. Many of these table names will be re-used if the user is
--- trying to run any platform-specific collation tests later, so we
--- must get rid of them.
---
-DROP SCHEMA collate_tests CASCADE;
-NOTICE: drop cascades to 16 other objects
-DETAIL: drop cascades to table collate_test1
-drop cascades to table collate_test_like
-drop cascades to table collate_test2
-drop cascades to type testdomain_p
-drop cascades to table collate_test4
-drop cascades to table collate_test5
-drop cascades to table collate_test10
-drop cascades to view collview1
-drop cascades to view collview2
-drop cascades to view collview3
-drop cascades to type testdomain
-drop cascades to table test_u
-drop cascades to function dup(anyelement)
-drop cascades to table collate_test20
-drop cascades to table collate_test21
-drop cascades to table collate_test22
+++ /dev/null
---
--- Tests for some likely failure cases with combo cmin/cmax mechanism
---
-CREATE TEMP TABLE combocidtest (foobar int);
-BEGIN;
--- a few dummy ops to push up the CommandId counter
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest VALUES (1);
-INSERT INTO combocidtest VALUES (2);
-SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
- ctid | cmin | foobar
--------+------+--------
- (0,1) | 10 | 1
- (0,2) | 11 | 2
-(2 rows)
-
-SAVEPOINT s1;
-ERROR: SAVEPOINT is not yet supported.
-UPDATE combocidtest SET foobar = foobar + 10;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
--- here we should see only updated tuples
-SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK TO s1;
-ERROR: no such savepoint
--- now we should see old tuples, but with combo CIDs starting at 0
-SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-COMMIT;
--- combo data is not there anymore, but should still see tuples
-SELECT ctid,cmin,* FROM combocidtest;
- ctid | cmin | foobar
-------+------+--------
-(0 rows)
-
--- Test combo cids with portals
-BEGIN;
-INSERT INTO combocidtest VALUES (333);
-DECLARE c CURSOR FOR SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
-DELETE FROM combocidtest;
-FETCH ALL FROM c;
- ctid | cmin | foobar
--------+------+--------
- (0,3) | 0 | 333
-(1 row)
-
-ROLLBACK;
-SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
- ctid | cmin | foobar
-------+------+--------
-(0 rows)
-
--- check behavior with locked tuples
-BEGIN;
--- a few dummy ops to push up the CommandId counter
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest SELECT 1 LIMIT 0;
-INSERT INTO combocidtest VALUES (444);
-SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
- ctid | cmin | foobar
--------+------+--------
- (0,4) | 10 | 444
-(1 row)
-
-SAVEPOINT s1;
-ERROR: SAVEPOINT is not yet supported.
--- this doesn't affect cmin
-SELECT ctid,cmin,* FROM combocidtest FOR UPDATE;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
--- but this does
-UPDATE combocidtest SET foobar = foobar + 10;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK TO s1;
-ERROR: no such savepoint
-SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-COMMIT;
-SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid;
- ctid | cmin | foobar
-------+------+--------
-(0 rows)
-
+++ /dev/null
-CREATE TEMP TABLE x (
- a serial,
- b int,
- c text not null default 'stuff',
- d text,
- e text
-) WITH OIDS;
-CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS '
- BEGIN
- NEW.e := ''before trigger fired''::text;
- return NEW;
- END;
-' LANGUAGE plpgsql;
-CREATE FUNCTION fn_x_after () RETURNS TRIGGER AS '
- BEGIN
- UPDATE x set e=''after trigger fired'' where c=''stuff'';
- return NULL;
- END;
-' LANGUAGE plpgsql;
-CREATE TRIGGER trg_x_after AFTER INSERT ON x
-FOR EACH ROW EXECUTE PROCEDURE fn_x_after();
-ERROR: Postgres-XL does not support TRIGGER yet
-DETAIL: The feature is not currently supported
-CREATE TRIGGER trg_x_before BEFORE INSERT ON x
-FOR EACH ROW EXECUTE PROCEDURE fn_x_before();
-ERROR: Postgres-XL does not support TRIGGER yet
-DETAIL: The feature is not currently supported
-COPY x (a, b, c, d, e) from stdin;
-COPY x (b, d) from stdin;
-COPY x (b, d) from stdin;
-COPY x (a, b, c, d, e) from stdin;
--- non-existent column in column list: should fail
-COPY x (xyz) from stdin;
-ERROR: column "xyz" of relation "x" does not exist
--- too many columns in column list: should fail
-COPY x (a, b, c, d, e, d, c) from stdin;
-ERROR: column "d" specified more than once
--- missing data: should fail
-COPY x from stdin;
-ERROR: invalid input syntax for integer: ""
-CONTEXT: COPY x, line 1, column a: ""
-COPY x from stdin;
-ERROR: missing data for column "e"
-CONTEXT: COPY x, line 1: "2000 230 23 23"
-COPY x from stdin;
-ERROR: missing data for column "e"
-CONTEXT: COPY x, line 1: "2001 231 \N \N"
--- extra data: should fail
-COPY x from stdin;
-ERROR: extra data after last expected column
-CONTEXT: COPY x, line 1: "2002 232 40 50 60 70 80"
--- various COPY options: delimiters, oids, NULL string, encoding
-COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x';
-COPY x from stdin WITH DELIMITER AS ';' NULL AS '';
-COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X' ENCODING 'sql_ascii';
--- check results of copy in
-SELECT * FROM x ORDER BY a, b;
- a | b | c | d | e
--------+----+------------+--------+----
- 1 | 1 | stuff | test_1 |
- 2 | 2 | stuff | test_2 |
- 3 | 3 | stuff | test_3 |
- 4 | 4 | stuff | test_4 |
- 5 | 5 | stuff | test_5 |
- 6 | | 45 | 80 | 90
- 7 | | x | \x | \x
- 8 | | , | \, | \
- 3000 | | c | |
- 4000 | | C | |
- 4001 | 1 | empty | |
- 4002 | 2 | null | |
- 4003 | 3 | Backslash | \ | \
- 4004 | 4 | BackslashX | \X | \X
- 4005 | 5 | N | N | N
- 4006 | 6 | BackslashN | \N | \N
- 4007 | 7 | XX | XX | XX
- 4008 | 8 | Delimiter | : | :
- 9999 | | \N | NN |
- 10000 | 21 | 31 | 41 | 51
- 10001 | 22 | 32 | 42 | 52
- 10002 | 23 | 33 | 43 | 53
- 10003 | 24 | 34 | 44 | 54
- 10004 | 25 | 35 | 45 | 55
- 10005 | 26 | 36 | 46 | 56
-(25 rows)
-
--- COPY w/ oids on a table w/o oids should fail
-CREATE TABLE no_oids (
- a int,
- b int
-) WITHOUT OIDS;
-INSERT INTO no_oids (a, b) VALUES (5, 10);
-INSERT INTO no_oids (a, b) VALUES (20, 30);
--- should fail
-COPY no_oids FROM stdin WITH OIDS;
-ERROR: table "no_oids" does not have OIDs
-COPY no_oids TO stdout WITH OIDS;
-ERROR: table "no_oids" does not have OIDs
--- check copy out
-COPY x TO stdout;
-9999 \N \\N NN \N
-1 1 stuff test_1 \N
-2 2 stuff test_2 \N
-5 5 stuff test_5 \N
-10001 22 32 42 52
-10002 23 33 43 53
-10004 25 35 45 55
-6 \N 45 80 90
-8 \N , \\, \\
-4000 \N C \N \N
-4002 2 null \N \N
-4003 3 Backslash \\ \\
-4005 5 N N N
-4007 7 XX XX XX
-4008 8 Delimiter : :
-10000 21 31 41 51
-3 3 stuff test_3 \N
-4 4 stuff test_4 \N
-10003 24 34 44 54
-10005 26 36 46 56
-7 \N x \\x \\x
-3000 \N c \N \N
-4001 1 empty
-4004 4 BackslashX \\X \\X
-4006 6 BackslashN \\N \\N
-COPY x (c, e) TO stdout;
-\\N \N
-stuff \N
-stuff \N
-stuff \N
-32 52
-33 53
-35 55
-45 90
-, \\
-C \N
-null \N
-Backslash \\
-N N
-XX XX
-Delimiter :
-31 51
-stuff \N
-stuff \N
-34 54
-36 56
-x \\x
-c \N
-empty
-BackslashX \\X
-BackslashN \\N
-COPY x (b, e) TO stdout WITH NULL 'I''m null';
-I'm null I'm null
-1 I'm null
-2 I'm null
-5 I'm null
-22 52
-23 53
-25 55
-I'm null 90
-I'm null \\
-I'm null I'm null
-2 I'm null
-3 \\
-5 N
-7 XX
-8 :
-21 51
-3 I'm null
-4 I'm null
-24 54
-26 56
-I'm null \\x
-I'm null I'm null
-1
-4 \\X
-6 \\N
-CREATE TEMP TABLE y (
- col1 text,
- col2 text
-);
-INSERT INTO y VALUES ('Jackson, Sam', E'\\h');
-INSERT INTO y VALUES ('It is "perfect".',E'\t');
-INSERT INTO y VALUES ('', NULL);
-COPY y TO stdout WITH CSV;
-"Jackson, Sam",\h
-"It is ""perfect"".",
-"",
-COPY y TO stdout WITH CSV QUOTE '''' DELIMITER '|';
-Jackson, Sam|\h
-It is "perfect".|
-''|
-COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE E'\\' ENCODING 'sql_ascii';
-"Jackson, Sam","\\h"
-"It is \"perfect\"."," "
-"",
-COPY y TO stdout WITH CSV FORCE QUOTE *;
-"Jackson, Sam",\h
-"It is ""perfect"".",
-"",
--- Repeat above tests with new 9.0 option syntax
-COPY y TO stdout (FORMAT CSV);
-"Jackson, Sam",\h
-"It is ""perfect"".",
-"",
-COPY y TO stdout (FORMAT CSV, QUOTE '''', DELIMITER '|');
-Jackson, Sam|\h
-It is "perfect".|
-''|
-COPY y TO stdout (FORMAT CSV, FORCE_QUOTE (col2), ESCAPE E'\\');
-"Jackson, Sam","\\h"
-"It is \"perfect\"."," "
-"",
-COPY y TO stdout (FORMAT CSV, FORCE_QUOTE *);
-"Jackson, Sam",\h
-"It is ""perfect"".",
-"",
-\copy y TO stdout (FORMAT CSV)
-"Jackson, Sam",\h
-"It is ""perfect"".",
-"",
-\copy y TO stdout (FORMAT CSV, QUOTE '''', DELIMITER '|')
-Jackson, Sam|\h
-It is "perfect".|
-''|
-\copy y TO stdout (FORMAT CSV, FORCE_QUOTE (col2), ESCAPE E'\\')
-"Jackson, Sam","\\h"
-"It is \"perfect\"."," "
-"",
-\copy y TO stdout (FORMAT CSV, FORCE_QUOTE *)
-"Jackson, Sam",\h
-"It is ""perfect"".",
-"",
---test that we read consecutive LFs properly
-CREATE TEMP TABLE testnl (a int, b text, c int);
-COPY testnl FROM stdin CSV;
--- test end of copy marker
-CREATE TEMP TABLE testeoc (a text);
-COPY testeoc FROM stdin CSV;
-COPY testeoc TO stdout CSV;
-"\."
-a\.
-\.b
-c\.d
--- test handling of nonstandard null marker that violates escaping rules
-CREATE TEMP TABLE testnull(a int, b text);
-INSERT INTO testnull VALUES (1, E'\\0'), (NULL, NULL);
-COPY testnull TO stdout WITH NULL AS E'\\0';
-1 \\0
-\0 \0
-COPY testnull FROM stdin WITH NULL AS E'\\0';
-SELECT * FROM testnull ORDER BY 1,2;
- a | b
-----+----
- 1 | \0
- 42 | \0
- |
- |
-(4 rows)
-
-BEGIN;
-CREATE TABLE vistest (LIKE testeoc);
-ERROR: relation "testeoc" does not exist
-COPY vistest FROM stdin CSV;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-a0
-b
-\.
-invalid command \.
-COMMIT;
-ERROR: syntax error at or near "a0"
-LINE 1: a0
- ^
-SELECT * FROM vistest;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-BEGIN;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-TRUNCATE vistest;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-COPY vistest FROM stdin CSV;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-a1
-b
-\.
-invalid command \.
-SELECT * FROM vistest;
-ERROR: syntax error at or near "a1"
-LINE 1: a1
- ^
-SAVEPOINT s1;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-TRUNCATE vistest;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-COPY vistest FROM stdin CSV;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-d1
-e
-\.
-invalid command \.
-SELECT * FROM vistest;
-ERROR: syntax error at or near "d1"
-LINE 1: d1
- ^
-COMMIT;
-SELECT * FROM vistest;
-ERROR: relation "vistest" does not exist
-LINE 1: SELECT * FROM vistest;
- ^
-BEGIN;
-TRUNCATE vistest;
-ERROR: relation "vistest" does not exist
-COPY vistest FROM stdin CSV FREEZE;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-a2
-b
-\.
-invalid command \.
-SELECT * FROM vistest;
-ERROR: syntax error at or near "a2"
-LINE 1: a2
- ^
-SAVEPOINT s1;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-TRUNCATE vistest;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-COPY vistest FROM stdin CSV FREEZE;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-d2
-e
-\.
-invalid command \.
-SELECT * FROM vistest;
-ERROR: syntax error at or near "d2"
-LINE 1: d2
- ^
-COMMIT;
-SELECT * FROM vistest;
-ERROR: relation "vistest" does not exist
-LINE 1: SELECT * FROM vistest;
- ^
-BEGIN;
-TRUNCATE vistest;
-ERROR: relation "vistest" does not exist
-COPY vistest FROM stdin CSV FREEZE;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-x
-y
-\.
-invalid command \.
-SELECT * FROM vistest;
-ERROR: syntax error at or near "x"
-LINE 1: x
- ^
-COMMIT;
-TRUNCATE vistest;
-ERROR: relation "vistest" does not exist
-COPY vistest FROM stdin CSV FREEZE;
-ERROR: relation "vistest" does not exist
-p
-g
-\.
-invalid command \.
-BEGIN;
-ERROR: syntax error at or near "p"
-LINE 1: p
- ^
-TRUNCATE vistest;
-ERROR: relation "vistest" does not exist
-SAVEPOINT s1;
-ERROR: SAVEPOINT is not yet supported.
-COPY vistest FROM stdin CSV FREEZE;
-ERROR: relation "vistest" does not exist
-m
-k
-\.
-invalid command \.
-COMMIT;
-ERROR: syntax error at or near "m"
-LINE 1: m
- ^
-BEGIN;
-INSERT INTO vistest VALUES ('z');
-ERROR: relation "vistest" does not exist
-LINE 1: INSERT INTO vistest VALUES ('z');
- ^
-SAVEPOINT s1;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-TRUNCATE vistest;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK TO SAVEPOINT s1;
-ERROR: no such savepoint
-COPY vistest FROM stdin CSV FREEZE;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-d3
-e
-\.
-invalid command \.
-COMMIT;
-ERROR: syntax error at or near "d3"
-LINE 1: d3
- ^
-CREATE FUNCTION truncate_in_subxact() RETURNS VOID AS
-$$
-BEGIN
- TRUNCATE vistest;
-EXCEPTION
- WHEN OTHERS THEN
- INSERT INTO vistest VALUES ('subxact failure');
-END;
-$$ language plpgsql;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-BEGIN;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-INSERT INTO vistest VALUES ('z');
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT truncate_in_subxact();
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-COPY vistest FROM stdin CSV FREEZE;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-d4
-e
-\.
-invalid command \.
-SELECT * FROM vistest;
-ERROR: syntax error at or near "d4"
-LINE 1: d4
- ^
-COMMIT;
-SELECT * FROM vistest;
-ERROR: relation "vistest" does not exist
-LINE 1: SELECT * FROM vistest;
- ^
--- Test FORCE_NOT_NULL and FORCE_NULL options
-CREATE TEMP TABLE forcetest (
- a INT NOT NULL,
- b TEXT NOT NULL,
- c TEXT,
- d TEXT,
- e TEXT
-);
-\pset null NULL
--- should succeed with no effect ("b" remains an empty string, "c" remains NULL)
-BEGIN;
-COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(b), FORCE_NULL(c));
-COMMIT;
-SELECT b, c FROM forcetest WHERE a = 1;
- b | c
----+---
- |
-(1 row)
-
--- should succeed, FORCE_NULL and FORCE_NOT_NULL can be both specified
-BEGIN;
-COPY forcetest (a, b, c, d) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(c,d), FORCE_NULL(c,d));
-COMMIT;
-SELECT c, d FROM forcetest WHERE a = 2;
- c | d
----+---
- |
-(1 row)
-
--- should fail with not-null constraint violation
-BEGIN;
-COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b), FORCE_NOT_NULL(c));
-ERROR: null value in column "b" violates not-null constraint
-DETAIL: Failing row contains (3, null, , null, null).
-ROLLBACK;
--- should fail with "not referenced by COPY" error
-BEGIN;
-COPY forcetest (d, e) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(b));
-ERROR: FORCE_NOT_NULL column "b" not referenced by COPY
-ROLLBACK;
--- should fail with "not referenced by COPY" error
-BEGIN;
-COPY forcetest (d, e) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b));
-ERROR: FORCE_NULL column "b" not referenced by COPY
-ROLLBACK;
-\pset null ''
--- test case with whole-row Var in a check constraint
-create table check_con_tbl (f1 int);
-create function check_con_function(check_con_tbl) returns bool as $$
-begin
- raise notice 'input = %', row_to_json($1);
- return $1.f1 > 0;
-end $$ language plpgsql immutable;
-alter table check_con_tbl add check (check_con_function(check_con_tbl.*));
-\d+ check_con_tbl
- Table "public.check_con_tbl"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+---------+-----------+---------+--------------+-------------
- f1 | integer | | plain | |
-Check constraints:
- "check_con_tbl_check" CHECK (check_con_function(check_con_tbl.*))
-Distribute By: HASH(f1)
-Location Nodes: ALL DATANODES
-
-copy check_con_tbl from stdin;
-copy check_con_tbl from stdin;
-ERROR: new row for relation "check_con_tbl" violates check constraint "check_con_tbl_check"
-DETAIL: Failing row contains (0).
-select * from check_con_tbl;
- f1
-----
- 1
-
-(2 rows)
-
-DROP TABLE forcetest;
-DROP TABLE vistest;
-ERROR: table "vistest" does not exist
-DROP FUNCTION truncate_in_subxact();
-ERROR: function truncate_in_subxact() does not exist
-DROP TABLE x, y;
-DROP FUNCTION fn_x_before();
-DROP FUNCTION fn_x_after();
+++ /dev/null
---
--- DEPENDENCIES
---
-CREATE USER regression_user;
-CREATE USER regression_user2;
-CREATE USER regression_user3;
-CREATE GROUP regression_group;
-CREATE TABLE deptest (f1 serial primary key, f2 text);
-ERROR: Postgres-XL does not support SERIAL yet
-DETAIL: The feature is not currently supported
-GRANT SELECT ON TABLE deptest TO GROUP regression_group;
-ERROR: relation "deptest" does not exist
-GRANT ALL ON TABLE deptest TO regression_user, regression_user2;
-ERROR: relation "deptest" does not exist
--- can't drop neither because they have privileges somewhere
-DROP USER regression_user;
-DROP GROUP regression_group;
--- if we revoke the privileges we can drop the group
-REVOKE SELECT ON deptest FROM GROUP regression_group;
-ERROR: relation "deptest" does not exist
-DROP GROUP regression_group;
-ERROR: role "regression_group" does not exist
--- can't drop the user if we revoke the privileges partially
-REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES ON deptest FROM regression_user;
-ERROR: relation "deptest" does not exist
-DROP USER regression_user;
-ERROR: role "regression_user" does not exist
--- now we are OK to drop him
-REVOKE TRIGGER ON deptest FROM regression_user;
-ERROR: relation "deptest" does not exist
-DROP USER regression_user;
-ERROR: role "regression_user" does not exist
--- we are OK too if we drop the privileges all at once
-REVOKE ALL ON deptest FROM regression_user2;
-ERROR: relation "deptest" does not exist
-DROP USER regression_user2;
--- can't drop the owner of an object
--- the error message detail here would include a pg_toast_nnn name that
--- is not constant, so suppress it
-\set VERBOSITY terse
-ALTER TABLE deptest OWNER TO regression_user3;
-ERROR: relation "deptest" does not exist
-DROP USER regression_user3;
-\set VERBOSITY default
--- if we drop the object, we can drop the user too
-DROP TABLE deptest;
-ERROR: table "deptest" does not exist
-DROP USER regression_user3;
-ERROR: role "regression_user3" does not exist
--- Test DROP OWNED
-CREATE USER regression_user0;
-CREATE USER regression_user1;
-CREATE USER regression_user2;
-SET SESSION AUTHORIZATION regression_user0;
--- permission denied
-DROP OWNED BY regression_user1;
-ERROR: permission denied to drop objects
-DROP OWNED BY regression_user0, regression_user2;
-ERROR: permission denied to drop objects
-REASSIGN OWNED BY regression_user0 TO regression_user1;
-ERROR: permission denied to reassign objects
-REASSIGN OWNED BY regression_user1 TO regression_user0;
-ERROR: permission denied to reassign objects
--- this one is allowed
-DROP OWNED BY regression_user0;
-CREATE TABLE deptest1 (f1 int unique);
-NOTICE: CREATE TABLE / UNIQUE will create implicit index "deptest1_f1_key" for table "deptest1"
-GRANT ALL ON deptest1 TO regression_user1 WITH GRANT OPTION;
-SET SESSION AUTHORIZATION regression_user1;
-CREATE TABLE deptest (a serial primary key, b text);
-ERROR: Postgres-XL does not support SERIAL yet
-DETAIL: The feature is not currently supported
-GRANT ALL ON deptest1 TO regression_user2;
-RESET SESSION AUTHORIZATION;
-\z deptest1
- Access privileges
- Schema | Name | Type | Access privileges | Column access privileges
---------+----------+-------+--------------------------------------------------+--------------------------
- public | deptest1 | table | regression_user0=arwdDxt/regression_user0 +|
- | | | regression_user1=a*r*w*d*D*x*t*/regression_user0+|
- | | | regression_user2=arwdDxt/regression_user1 |
-(1 row)
-
-DROP OWNED BY regression_user1;
--- all grants revoked
-\z deptest1
- Access privileges
- Schema | Name | Type | Access privileges | Column access privileges
---------+----------+-------+-------------------------------------------+--------------------------
- public | deptest1 | table | regression_user0=arwdDxt/regression_user0 |
-(1 row)
-
--- table was dropped
-\d deptest
--- Test REASSIGN OWNED
-GRANT ALL ON deptest1 TO regression_user1;
-SET SESSION AUTHORIZATION regression_user1;
-CREATE TABLE deptest (a serial primary key, b text);
-ERROR: Postgres-XL does not support SERIAL yet
-DETAIL: The feature is not currently supported
-CREATE TABLE deptest2 (f1 int);
--- make a serial column the hard way
-CREATE SEQUENCE ss1;
-ALTER TABLE deptest2 ALTER f1 SET DEFAULT nextval('ss1');
-ALTER SEQUENCE ss1 OWNED BY deptest2.f1;
-RESET SESSION AUTHORIZATION;
-REASSIGN OWNED BY regression_user1 TO regression_user2;
-\dt deptest
- List of relations
- Schema | Name | Type | Owner
---------+------+------+-------
-(0 rows)
-
--- doesn't work: grant still exists
-DROP USER regression_user1;
-ERROR: role "regression_user1" cannot be dropped because some objects depend on it
-DETAIL: privileges for table deptest1
-DROP OWNED BY regression_user1;
-DROP USER regression_user1;
-\set VERBOSITY terse
-DROP USER regression_user2;
-ERROR: role "regression_user2" cannot be dropped because some objects depend on it
-DROP OWNED BY regression_user2, regression_user0;
-DROP USER regression_user2;
-DROP USER regression_user0;
+++ /dev/null
---
--- Test domains.
---
--- Test Comment / Drop
-create domain domaindroptest int4;
-comment on domain domaindroptest is 'About to drop this..';
-create domain dependenttypetest domaindroptest;
--- fail because of dependent type
-drop domain domaindroptest;
-ERROR: cannot drop type domaindroptest because other objects depend on it
-DETAIL: type dependenttypetest depends on type domaindroptest
-HINT: Use DROP ... CASCADE to drop the dependent objects too.
-drop domain domaindroptest cascade;
-NOTICE: drop cascades to type dependenttypetest
--- this should fail because already gone
-drop domain domaindroptest cascade;
-ERROR: type "domaindroptest" does not exist
--- Test domain input.
--- Note: the point of checking both INSERT and COPY FROM is that INSERT
--- exercises CoerceToDomain while COPY exercises domain_in.
-create domain domainvarchar varchar(5);
-create domain domainnumeric numeric(8,2);
-create domain domainint4 int4;
-create domain domaintext text;
--- Test explicit coercions --- these should succeed (and truncate)
-SELECT cast('123456' as domainvarchar);
- domainvarchar
----------------
- 12345
-(1 row)
-
-SELECT cast('12345' as domainvarchar);
- domainvarchar
----------------
- 12345
-(1 row)
-
--- Test tables using domains
-create table basictest
- ( testint4 domainint4
- , testtext domaintext
- , testvarchar domainvarchar
- , testnumeric domainnumeric
- );
-INSERT INTO basictest values ('88', 'haha', 'short', '123.12'); -- Good
-INSERT INTO basictest values ('88', 'haha', 'short text', '123.12'); -- Bad varchar
-ERROR: value too long for type character varying(5)
-INSERT INTO basictest values ('88', 'haha', 'short', '123.1212'); -- Truncate numeric
--- Test copy
-COPY basictest (testvarchar) FROM stdin; -- fail
-ERROR: value too long for type character varying(5)
-CONTEXT: COPY basictest, line 1, column testvarchar: "notsoshorttext"
-COPY basictest (testvarchar) FROM stdin;
-select * from basictest order by 1, 2, 3, 4;
- testint4 | testtext | testvarchar | testnumeric
-----------+----------+-------------+-------------
- 88 | haha | short | 123.12
- 88 | haha | short | 123.12
- | | short |
-(3 rows)
-
--- check that domains inherit operations from base types
-select testtext || testvarchar as concat, testnumeric + 42 as sum
-from basictest order by 1,2;
- concat | sum
------------+--------
- hahashort | 165.12
- hahashort | 165.12
- |
-(3 rows)
-
--- check that union/case/coalesce type resolution handles domains properly
-select coalesce(4::domainint4, 7) is of (int4) as t;
- t
----
- t
-(1 row)
-
-select coalesce(4::domainint4, 7) is of (domainint4) as f;
- f
----
- f
-(1 row)
-
-select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
- t
----
- t
-(1 row)
-
-drop table basictest;
-drop domain domainvarchar restrict;
-drop domain domainnumeric restrict;
-drop domain domainint4 restrict;
-drop domain domaintext;
--- Test domains over array types
-create domain domainint4arr int4[1];
-create domain domainchar4arr varchar(4)[2][3];
-create table domarrtest
- ( testint4arr domainint4arr
- , testchar4arr domainchar4arr
- );
-INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"}}');
-INSERT INTO domarrtest values ('{{2,2},{2,2}}', '{{"a","b"}}');
-INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"},{"e","f"}}');
-INSERT INTO domarrtest values ('{2,2}', '{{"a"},{"c"}}');
-INSERT INTO domarrtest values (NULL, '{{"a","b","c"},{"d","e","f"}}');
-INSERT INTO domarrtest values (NULL, '{{"toolong","b","c"},{"d","e","f"}}');
-ERROR: value too long for type character varying(4)
-select * from domarrtest order by 1, 2;
- testint4arr | testchar4arr
----------------+---------------------
- {2,2} | {{a,b},{c,d}}
- {2,2} | {{a,b},{c,d},{e,f}}
- {2,2} | {{a},{c}}
- {{2,2},{2,2}} | {{a,b}}
- | {{a,b,c},{d,e,f}}
-(5 rows)
-
-select testint4arr[1], testchar4arr[2:2] from domarrtest order by 1, 2;
- testint4arr | testchar4arr
--------------+--------------
- 2 | {{c}}
- 2 | {{c,d}}
- 2 | {{c,d}}
- | {}
- | {{d,e,f}}
-(5 rows)
-
-select array_dims(testint4arr), array_dims(testchar4arr) from domarrtest order by 1, 2;
- array_dims | array_dims
-------------+------------
- [1:2] | [1:2][1:1]
- [1:2] | [1:2][1:2]
- [1:2] | [1:3][1:2]
- [1:2][1:2] | [1:1][1:2]
- | [1:2][1:3]
-(5 rows)
-
-COPY domarrtest FROM stdin;
-COPY domarrtest FROM stdin; -- fail
-ERROR: value too long for type character varying(4)
-CONTEXT: COPY domarrtest, line 1, column testchar4arr: "{qwerty,w,e}"
-select * from domarrtest order by 1, 2;
- testint4arr | testchar4arr
----------------+---------------------
- {2,2} | {{a,b},{c,d}}
- {2,2} | {{a,b},{c,d},{e,f}}
- {2,2} | {{a},{c}}
- {{2,2},{2,2}} | {{a,b}}
- {3,4} | {q,w,e}
- | {{a,b,c},{d,e,f}}
- |
-(7 rows)
-
-drop table domarrtest;
-drop domain domainint4arr restrict;
-drop domain domainchar4arr restrict;
-create domain dia as int[];
-select '{1,2,3}'::dia;
- dia
----------
- {1,2,3}
-(1 row)
-
-select array_dims('{1,2,3}'::dia);
- array_dims
-------------
- [1:3]
-(1 row)
-
-select pg_typeof('{1,2,3}'::dia);
- pg_typeof
------------
- dia
-(1 row)
-
-select pg_typeof('{1,2,3}'::dia || 42); -- should be int[] not dia
- pg_typeof
------------
- integer[]
-(1 row)
-
-drop domain dia;
-create domain dnotnull varchar(15) NOT NULL;
-create domain dnull varchar(15);
-create domain dcheck varchar(15) NOT NULL CHECK (VALUE = 'a' OR VALUE = 'c' OR VALUE = 'd');
-create table nulltest
- ( col1 dnotnull
- , col2 dnotnull NULL -- NOT NULL in the domain cannot be overridden
- , col3 dnull NOT NULL
- , col4 dnull
- , col5 dcheck CHECK (col5 IN ('c', 'd'))
- );
-INSERT INTO nulltest DEFAULT VALUES;
-ERROR: domain dnotnull does not allow null values
-INSERT INTO nulltest values ('a', 'b', 'c', 'd', 'c'); -- Good
-insert into nulltest values ('a', 'b', 'c', 'd', NULL);
-ERROR: domain dcheck does not allow null values
-insert into nulltest values ('a', 'b', 'c', 'd', 'a');
-ERROR: new row for relation "nulltest" violates check constraint "nulltest_col5_check"
-DETAIL: Failing row contains (a, b, c, d, a).
-INSERT INTO nulltest values (NULL, 'b', 'c', 'd', 'd');
-ERROR: domain dnotnull does not allow null values
-INSERT INTO nulltest values ('a', NULL, 'c', 'd', 'c');
-ERROR: domain dnotnull does not allow null values
-INSERT INTO nulltest values ('a', 'b', NULL, 'd', 'c');
-ERROR: null value in column "col3" violates not-null constraint
-DETAIL: Failing row contains (a, b, null, d, c).
-INSERT INTO nulltest values ('a', 'b', 'c', NULL, 'd'); -- Good
--- Test copy
-COPY nulltest FROM stdin; --fail
-ERROR: null value in column "col3" violates not-null constraint
-DETAIL: Failing row contains (a, b, null, d, d).
-COPY nulltest FROM stdin; --fail
-ERROR: domain dcheck does not allow null values
-CONTEXT: COPY nulltest, line 1, column col5: null input
--- Last row is bad
-COPY nulltest FROM stdin;
-ERROR: new row for relation "nulltest" violates check constraint "nulltest_col5_check"
-DETAIL: Failing row contains (a, b, c, null, a).
-select * from nulltest order by 1, 2, 3, 4, 5;
- col1 | col2 | col3 | col4 | col5
-------+------+------+------+------
- a | b | c | d | c
- a | b | c | | d
-(2 rows)
-
--- Test out coerced (casted) constraints
-SELECT cast('1' as dnotnull);
- dnotnull
-----------
- 1
-(1 row)
-
-SELECT cast(NULL as dnotnull); -- fail
-ERROR: domain dnotnull does not allow null values
-SELECT cast(cast(NULL as dnull) as dnotnull); -- fail
-ERROR: domain dnotnull does not allow null values
-SELECT cast(col4 as dnotnull) from nulltest; -- fail
-ERROR: domain dnotnull does not allow null values
--- cleanup
-drop table nulltest;
-drop domain dnotnull restrict;
-drop domain dnull restrict;
-drop domain dcheck restrict;
-create domain ddef1 int4 DEFAULT 3;
-create domain ddef2 oid DEFAULT '12';
--- Type mixing, function returns int8
-create domain ddef3 text DEFAULT 5;
-create sequence ddef4_seq;
-create domain ddef4 int4 DEFAULT nextval('ddef4_seq');
-create domain ddef5 numeric(8,2) NOT NULL DEFAULT '12.12';
-create table defaulttest
- ( col1 ddef1
- , col2 ddef2
- , col3 ddef3
- , col4 ddef4 PRIMARY KEY
- , col5 ddef1 NOT NULL DEFAULT NULL
- , col6 ddef2 DEFAULT '88'
- , col7 ddef4 DEFAULT 8000
- , col8 ddef5
- );
-ERROR: Column col4 is not a hash distributable data type
-insert into defaulttest(col4) values(0); -- fails, col5 defaults to null
-ERROR: relation "defaulttest" does not exist
-LINE 1: insert into defaulttest(col4) values(0);
- ^
-alter table defaulttest alter column col5 drop default;
-ERROR: relation "defaulttest" does not exist
-insert into defaulttest default values; -- succeeds, inserts domain default
-ERROR: relation "defaulttest" does not exist
-LINE 1: insert into defaulttest default values;
- ^
--- We used to treat SET DEFAULT NULL as equivalent to DROP DEFAULT; wrong
-alter table defaulttest alter column col5 set default null;
-ERROR: relation "defaulttest" does not exist
-insert into defaulttest(col4) values(0); -- fails
-ERROR: relation "defaulttest" does not exist
-LINE 1: insert into defaulttest(col4) values(0);
- ^
-alter table defaulttest alter column col5 drop default;
-ERROR: relation "defaulttest" does not exist
-insert into defaulttest default values;
-ERROR: relation "defaulttest" does not exist
-LINE 1: insert into defaulttest default values;
- ^
-insert into defaulttest default values;
-ERROR: relation "defaulttest" does not exist
-LINE 1: insert into defaulttest default values;
- ^
--- Test defaults with copy
-COPY defaulttest(col5) FROM stdin;
-ERROR: relation "defaulttest" does not exist
-42
-\.
-invalid command \.
-select * from defaulttest order by 1,2,3,4,5,6,7,8;
-ERROR: syntax error at or near "42"
-LINE 1: 42
- ^
-drop table defaulttest cascade;
-ERROR: table "defaulttest" does not exist
--- Test ALTER DOMAIN .. NOT NULL
-create domain dnotnulltest integer;
-create table domnotnull
-( col1 dnotnulltest
-, col2 dnotnulltest
-);
-insert into domnotnull default values;
-alter domain dnotnulltest set not null; -- fails
-ERROR: column "col1" of table "domnotnull" contains null values
-update domnotnull set col1 = 5;
-alter domain dnotnulltest set not null; -- fails
-ERROR: column "col2" of table "domnotnull" contains null values
-update domnotnull set col2 = 6;
-alter domain dnotnulltest set not null;
-update domnotnull set col1 = null; -- fails
-ERROR: domain dnotnulltest does not allow null values
-alter domain dnotnulltest drop not null;
-update domnotnull set col1 = null;
-drop domain dnotnulltest cascade;
-NOTICE: drop cascades to 2 other objects
-DETAIL: drop cascades to table domnotnull column col1
-drop cascades to table domnotnull column col2
--- Test ALTER DOMAIN .. DEFAULT ..
-create table domdeftest (col1 ddef1);
-insert into domdeftest default values;
-select * from domdeftest order by 1;
- col1
-------
- 3
-(1 row)
-
-alter domain ddef1 set default '42';
-insert into domdeftest default values;
-select * from domdeftest order by 1;
- col1
-------
- 3
- 42
-(2 rows)
-
-alter domain ddef1 drop default;
-insert into domdeftest default values;
-select * from domdeftest order by 1;
- col1
-------
- 3
- 42
-
-(3 rows)
-
-drop table domdeftest;
--- Test ALTER DOMAIN .. CONSTRAINT ..
-create domain con as integer;
-create table domcontest (col1 con);
-insert into domcontest values (1);
-insert into domcontest values (2);
-alter domain con add constraint t check (VALUE < 1); -- fails
-ERROR: column "col1" of table "domcontest" contains values that violate the new constraint
-alter domain con add constraint t check (VALUE < 34);
-alter domain con add check (VALUE > 0);
-insert into domcontest values (-5); -- fails
-ERROR: value for domain con violates check constraint "con_check"
-insert into domcontest values (42); -- fails
-ERROR: value for domain con violates check constraint "t"
-insert into domcontest values (5);
-alter domain con drop constraint t;
-insert into domcontest values (-5); --fails
-ERROR: value for domain con violates check constraint "con_check"
-insert into domcontest values (42);
-alter domain con drop constraint nonexistent;
-ERROR: constraint "nonexistent" of domain "con" does not exist
-alter domain con drop constraint if exists nonexistent;
-NOTICE: constraint "nonexistent" of domain "con" does not exist, skipping
--- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID
-create domain things AS INT;
-CREATE TABLE thethings (stuff things);
-INSERT INTO thethings (stuff) VALUES (55);
-ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11);
-ERROR: column "stuff" of table "thethings" contains values that violate the new constraint
-ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11) NOT VALID;
-ALTER DOMAIN things VALIDATE CONSTRAINT meow;
-ERROR: column "stuff" of table "thethings" contains values that violate the new constraint
-UPDATE thethings SET stuff = 10;
-ALTER DOMAIN things VALIDATE CONSTRAINT meow;
--- Confirm ALTER DOMAIN with RULES.
-create table domtab (col1 integer);
-create domain dom as integer;
-create view domview as select cast(col1 as dom) from domtab;
-insert into domtab (col1) values (null);
-insert into domtab (col1) values (5);
-select * from domview order by 1;
- col1
-------
- 5
-
-(2 rows)
-
-alter domain dom set not null;
-select * from domview; -- fail
-ERROR: domain dom does not allow null values
-alter domain dom drop not null;
-select * from domview order by 1;
- col1
-------
- 5
-
-(2 rows)
-
-alter domain dom add constraint domchkgt6 check(value > 6);
-select * from domview; --fail
-ERROR: value for domain dom violates check constraint "domchkgt6"
-alter domain dom drop constraint domchkgt6 restrict;
-select * from domview order by 1;
- col1
-------
- 5
-
-(2 rows)
-
--- cleanup
-drop domain ddef1 restrict;
-drop domain ddef2 restrict;
-drop domain ddef3 restrict;
-drop domain ddef4 restrict;
-drop domain ddef5 restrict;
-drop sequence ddef4_seq;
--- Test domains over domains
-create domain vchar4 varchar(4);
-create domain dinter vchar4 check (substring(VALUE, 1, 1) = 'x');
-create domain dtop dinter check (substring(VALUE, 2, 1) = '1');
-select 'x123'::dtop;
- dtop
-------
- x123
-(1 row)
-
-select 'x1234'::dtop; -- explicit coercion should truncate
- dtop
-------
- x123
-(1 row)
-
-select 'y1234'::dtop; -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-select 'y123'::dtop; -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-select 'yz23'::dtop; -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-select 'xz23'::dtop; -- fail
-ERROR: value for domain dtop violates check constraint "dtop_check"
-create temp table dtest(f1 dtop);
-insert into dtest values('x123');
-insert into dtest values('x1234'); -- fail, implicit coercion
-ERROR: value too long for type character varying(4)
-insert into dtest values('y1234'); -- fail, implicit coercion
-ERROR: value too long for type character varying(4)
-insert into dtest values('y123'); -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-insert into dtest values('yz23'); -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-insert into dtest values('xz23'); -- fail
-ERROR: value for domain dtop violates check constraint "dtop_check"
-drop table dtest;
-drop domain vchar4 cascade;
-NOTICE: drop cascades to 2 other objects
-DETAIL: drop cascades to type dinter
-drop cascades to type dtop
--- Make sure that constraints of newly-added domain columns are
--- enforced correctly, even if there's no default value for the new
--- column. Per bug #1433
-create domain str_domain as text not null;
-create table domain_test (a int, b int);
-insert into domain_test values (1, 2);
-insert into domain_test values (1, 2);
--- should fail
-alter table domain_test add column c str_domain;
-ERROR: domain str_domain does not allow null values
-create domain str_domain2 as text check (value <> 'foo') default 'foo';
--- should fail
-alter table domain_test add column d str_domain2;
-ERROR: value for domain str_domain2 violates check constraint "str_domain2_check"
--- Check that domain constraints on prepared statement parameters of
--- unknown type are enforced correctly.
-create domain pos_int as int4 check (value > 0) not null;
-prepare s1 as select $1::pos_int = 10 as "is_ten";
-execute s1(10);
- is_ten
---------
- t
-(1 row)
-
-execute s1(0); -- should fail
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-execute s1(NULL); -- should fail
-ERROR: domain pos_int does not allow null values
--- Check that domain constraints on plpgsql function parameters, results,
--- and local variables are enforced correctly.
-create function doubledecrement(p1 pos_int) returns pos_int as $$
-declare v pos_int;
-begin
- return p1;
-end$$ language plpgsql;
-select doubledecrement(3); -- fail because of implicit null assignment
-ERROR: domain pos_int does not allow null values
-CONTEXT: PL/pgSQL function doubledecrement(pos_int) line 3 during statement block local variable initialization
-create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
-declare v pos_int := 0;
-begin
- return p1;
-end$$ language plpgsql;
-select doubledecrement(3); -- fail at initialization assignment
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-CONTEXT: PL/pgSQL function doubledecrement(pos_int) line 3 during statement block local variable initialization
-create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
-declare v pos_int := 1;
-begin
- v := p1 - 1;
- return v - 1;
-end$$ language plpgsql;
-select doubledecrement(null); -- fail before call
-ERROR: domain pos_int does not allow null values
-select doubledecrement(0); -- fail before call
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-select doubledecrement(1); -- fail at assignment to v
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-CONTEXT: PL/pgSQL function doubledecrement(pos_int) line 4 at assignment
-select doubledecrement(2); -- fail at return
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-CONTEXT: PL/pgSQL function doubledecrement(pos_int) while casting return value to function's return type
-select doubledecrement(3); -- good
- doubledecrement
------------------
- 1
-(1 row)
-
--- Check that ALTER DOMAIN tests columns of derived types
-create domain posint as int4;
--- Currently, this doesn't work for composite types, but verify it complains
-create type ddtest1 as (f1 posint);
-create table ddtest2(f1 ddtest1);
-insert into ddtest2 values(row(-1));
-alter domain posint add constraint c1 check(value >= 0);
-ERROR: cannot alter type "posint" because column "ddtest2.f1" uses it
-drop table ddtest2;
-create table ddtest2(f1 ddtest1[]);
-insert into ddtest2 values('{(-1)}');
-alter domain posint add constraint c1 check(value >= 0);
-ERROR: cannot alter type "posint" because column "ddtest2.f1" uses it
-drop table ddtest2;
-alter domain posint add constraint c1 check(value >= 0);
-create domain posint2 as posint check (value % 2 = 0);
-create table ddtest2(f1 posint2);
-insert into ddtest2 values(11); -- fail
-ERROR: value for domain posint2 violates check constraint "posint2_check"
-insert into ddtest2 values(-2); -- fail
-ERROR: value for domain posint2 violates check constraint "c1"
-insert into ddtest2 values(2);
-alter domain posint add constraint c2 check(value >= 10); -- fail
-ERROR: column "f1" of table "ddtest2" contains values that violate the new constraint
-alter domain posint add constraint c2 check(value > 0); -- OK
-drop table ddtest2;
-drop type ddtest1;
-drop domain posint cascade;
-NOTICE: drop cascades to type posint2
---
--- Check enforcement of domain-related typmod in plpgsql (bug #5717)
---
-create or replace function array_elem_check(numeric) returns numeric as $$
-declare
- x numeric(4,2)[1];
-begin
- x[1] := $1;
- return x[1];
-end$$ language plpgsql;
-select array_elem_check(121.00);
-ERROR: numeric field overflow
-DETAIL: A field with precision 4, scale 2 must round to an absolute value less than 10^2.
-CONTEXT: PL/pgSQL function array_elem_check(numeric) line 5 at assignment
-select array_elem_check(1.23456);
- array_elem_check
-------------------
- 1.23
-(1 row)
-
-create domain mynums as numeric(4,2)[1];
-create or replace function array_elem_check(numeric) returns numeric as $$
-declare
- x mynums;
-begin
- x[1] := $1;
- return x[1];
-end$$ language plpgsql;
-select array_elem_check(121.00);
-ERROR: numeric field overflow
-DETAIL: A field with precision 4, scale 2 must round to an absolute value less than 10^2.
-CONTEXT: PL/pgSQL function array_elem_check(numeric) line 5 at assignment
-select array_elem_check(1.23456);
- array_elem_check
-------------------
- 1.23
-(1 row)
-
-create domain mynums2 as mynums;
-create or replace function array_elem_check(numeric) returns numeric as $$
-declare
- x mynums2;
-begin
- x[1] := $1;
- return x[1];
-end$$ language plpgsql;
-select array_elem_check(121.00);
-ERROR: numeric field overflow
-DETAIL: A field with precision 4, scale 2 must round to an absolute value less than 10^2.
-CONTEXT: PL/pgSQL function array_elem_check(numeric) line 5 at assignment
-select array_elem_check(1.23456);
- array_elem_check
-------------------
- 1.23
-(1 row)
-
-drop function array_elem_check(numeric);
---
--- Check enforcement of array-level domain constraints
---
-create domain orderedpair as int[2] check (value[1] < value[2]);
-select array[1,2]::orderedpair;
- array
--------
- {1,2}
-(1 row)
-
-select array[2,1]::orderedpair; -- fail
-ERROR: value for domain orderedpair violates check constraint "orderedpair_check"
-create temp table op (f1 orderedpair);
-insert into op values (array[1,2]);
-insert into op values (array[2,1]); -- fail
-ERROR: value for domain orderedpair violates check constraint "orderedpair_check"
-update op set f1[2] = 3;
-update op set f1[2] = 0; -- fail
-ERROR: value for domain orderedpair violates check constraint "orderedpair_check"
-select * from op;
- f1
--------
- {1,3}
-(1 row)
-
-create or replace function array_elem_check(int) returns int as $$
-declare
- x orderedpair := '{1,2}';
-begin
- x[2] := $1;
- return x[2];
-end$$ language plpgsql;
-select array_elem_check(3);
- array_elem_check
-------------------
- 3
-(1 row)
-
-select array_elem_check(-1);
-ERROR: value for domain orderedpair violates check constraint "orderedpair_check"
-CONTEXT: PL/pgSQL function array_elem_check(integer) line 5 at assignment
-drop function array_elem_check(int);
---
--- Renaming
---
-create domain testdomain1 as int;
-alter domain testdomain1 rename to testdomain2;
-alter type testdomain2 rename to testdomain3; -- alter type also works
-drop domain testdomain3;
---
--- Renaming domain constraints
---
-create domain testdomain1 as int constraint unsigned check (value > 0);
-alter domain testdomain1 rename constraint unsigned to unsigned_foo;
-alter domain testdomain1 drop constraint unsigned_foo;
-drop domain testdomain1;
+++ /dev/null
---
--- Test domains.
---
--- Test Comment / Drop
-create domain domaindroptest int4;
-comment on domain domaindroptest is 'About to drop this..';
-create domain dependenttypetest domaindroptest;
--- fail because of dependent type
-drop domain domaindroptest;
-ERROR: cannot drop type domaindroptest because other objects depend on it
-DETAIL: type dependenttypetest depends on type domaindroptest
-HINT: Use DROP ... CASCADE to drop the dependent objects too.
-drop domain domaindroptest cascade;
-NOTICE: drop cascades to type dependenttypetest
--- this should fail because already gone
-drop domain domaindroptest cascade;
-ERROR: type "domaindroptest" does not exist
--- Test domain input.
--- Note: the point of checking both INSERT and COPY FROM is that INSERT
--- exercises CoerceToDomain while COPY exercises domain_in.
-create domain domainvarchar varchar(5);
-create domain domainnumeric numeric(8,2);
-create domain domainint4 int4;
-create domain domaintext text;
--- Test explicit coercions --- these should succeed (and truncate)
-SELECT cast('123456' as domainvarchar);
- domainvarchar
----------------
- 12345
-(1 row)
-
-SELECT cast('12345' as domainvarchar);
- domainvarchar
----------------
- 12345
-(1 row)
-
--- Test tables using domains
-create table basictest
- ( testint4 domainint4
- , testtext domaintext
- , testvarchar domainvarchar
- , testnumeric domainnumeric
- );
-INSERT INTO basictest values ('88', 'haha', 'short', '123.12'); -- Good
-INSERT INTO basictest values ('88', 'haha', 'short text', '123.12'); -- Bad varchar
-ERROR: value too long for type character varying(5)
-INSERT INTO basictest values ('88', 'haha', 'short', '123.1212'); -- Truncate numeric
--- Test copy
-COPY basictest (testvarchar) FROM stdin; -- fail
-ERROR: value too long for type character varying(5)
-CONTEXT: COPY basictest, line 1, column testvarchar: "notsoshorttext"
-COPY basictest (testvarchar) FROM stdin;
-select * from basictest order by 1, 2, 3, 4;
- testint4 | testtext | testvarchar | testnumeric
-----------+----------+-------------+-------------
- 88 | haha | short | 123.12
- 88 | haha | short | 123.12
- | | short |
-(3 rows)
-
--- check that domains inherit operations from base types
-select testtext || testvarchar as concat, testnumeric + 42 as sum
-from basictest order by 1,2;
- concat | sum
------------+--------
- hahashort | 165.12
- hahashort | 165.12
- |
-(3 rows)
-
--- check that union/case/coalesce type resolution handles domains properly
-select coalesce(4::domainint4, 7) is of (int4) as t;
- t
----
- t
-(1 row)
-
-select coalesce(4::domainint4, 7) is of (domainint4) as f;
- f
----
- f
-(1 row)
-
-select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
- t
----
- t
-(1 row)
-
-drop table basictest;
-drop domain domainvarchar restrict;
-drop domain domainnumeric restrict;
-drop domain domainint4 restrict;
-drop domain domaintext;
--- Test domains over array types
-create domain domainint4arr int4[1];
-create domain domainchar4arr varchar(4)[2][3];
-create table domarrtest
- ( testint4arr domainint4arr
- , testchar4arr domainchar4arr
- );
-INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"}}');
-INSERT INTO domarrtest values ('{{2,2},{2,2}}', '{{"a","b"}}');
-INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"},{"e","f"}}');
-INSERT INTO domarrtest values ('{2,2}', '{{"a"},{"c"}}');
-INSERT INTO domarrtest values (NULL, '{{"a","b","c"},{"d","e","f"}}');
-INSERT INTO domarrtest values (NULL, '{{"toolong","b","c"},{"d","e","f"}}');
-ERROR: value too long for type character varying(4)
-select * from domarrtest order by 1, 2;
- testint4arr | testchar4arr
----------------+---------------------
- {2,2} | {{a,b},{c,d}}
- {2,2} | {{a,b},{c,d},{e,f}}
- {2,2} | {{a},{c}}
- {{2,2},{2,2}} | {{a,b}}
- | {{a,b,c},{d,e,f}}
-(5 rows)
-
-select testint4arr[1], testchar4arr[2:2] from domarrtest order by 1, 2;
- testint4arr | testchar4arr
--------------+--------------
- 2 | {{c}}
- 2 | {{c,d}}
- 2 | {{c,d}}
- | {}
- | {{d,e,f}}
-(5 rows)
-
-select array_dims(testint4arr), array_dims(testchar4arr) from domarrtest order by 1, 2;
- array_dims | array_dims
-------------+------------
- [1:2] | [1:2][1:1]
- [1:2] | [1:2][1:2]
- [1:2] | [1:3][1:2]
- [1:2][1:2] | [1:1][1:2]
- | [1:2][1:3]
-(5 rows)
-
-COPY domarrtest FROM stdin;
-COPY domarrtest FROM stdin; -- fail
-ERROR: value too long for type character varying(4)
-CONTEXT: COPY domarrtest, line 1, column testchar4arr: "{qwerty,w,e}"
-select * from domarrtest order by 1, 2;
- testint4arr | testchar4arr
----------------+---------------------
- {2,2} | {{a,b},{c,d}}
- {2,2} | {{a,b},{c,d},{e,f}}
- {2,2} | {{a},{c}}
- {{2,2},{2,2}} | {{a,b}}
- {3,4} | {q,w,e}
- | {{a,b,c},{d,e,f}}
- |
-(7 rows)
-
-drop table domarrtest;
-drop domain domainint4arr restrict;
-drop domain domainchar4arr restrict;
-create domain dia as int[];
-select '{1,2,3}'::dia;
- dia
----------
- {1,2,3}
-(1 row)
-
-select array_dims('{1,2,3}'::dia);
- array_dims
-------------
- [1:3]
-(1 row)
-
-select pg_typeof('{1,2,3}'::dia);
- pg_typeof
------------
- dia
-(1 row)
-
-select pg_typeof('{1,2,3}'::dia || 42); -- should be int[] not dia
- pg_typeof
------------
- integer[]
-(1 row)
-
-drop domain dia;
-create domain dnotnull varchar(15) NOT NULL;
-create domain dnull varchar(15);
-create domain dcheck varchar(15) NOT NULL CHECK (VALUE = 'a' OR VALUE = 'c' OR VALUE = 'd');
-create table nulltest
- ( col1 dnotnull
- , col2 dnotnull NULL -- NOT NULL in the domain cannot be overridden
- , col3 dnull NOT NULL
- , col4 dnull
- , col5 dcheck CHECK (col5 IN ('c', 'd'))
- );
-INSERT INTO nulltest DEFAULT VALUES;
-ERROR: domain dnotnull does not allow null values
-INSERT INTO nulltest values ('a', 'b', 'c', 'd', 'c'); -- Good
-insert into nulltest values ('a', 'b', 'c', 'd', NULL);
-ERROR: domain dcheck does not allow null values
-insert into nulltest values ('a', 'b', 'c', 'd', 'a');
-ERROR: new row for relation "nulltest" violates check constraint "nulltest_col5_check"
-DETAIL: Failing row contains (a, b, c, d, a).
-INSERT INTO nulltest values (NULL, 'b', 'c', 'd', 'd');
-ERROR: domain dnotnull does not allow null values
-INSERT INTO nulltest values ('a', NULL, 'c', 'd', 'c');
-ERROR: domain dnotnull does not allow null values
-INSERT INTO nulltest values ('a', 'b', NULL, 'd', 'c');
-ERROR: null value in column "col3" violates not-null constraint
-DETAIL: Failing row contains (a, b, null, d, c).
-INSERT INTO nulltest values ('a', 'b', 'c', NULL, 'd'); -- Good
--- Test copy
-COPY nulltest FROM stdin; --fail
-ERROR: null value in column "col3" violates not-null constraint
-DETAIL: Failing row contains (a, b, null, d, d).
-COPY nulltest FROM stdin; --fail
-ERROR: domain dcheck does not allow null values
-CONTEXT: COPY nulltest, line 1, column col5: null input
--- Last row is bad
-COPY nulltest FROM stdin;
-ERROR: new row for relation "nulltest" violates check constraint "nulltest_col5_check"
-DETAIL: Failing row contains (a, b, c, null, a).
-select * from nulltest order by 1, 2, 3, 4, 5;
- col1 | col2 | col3 | col4 | col5
-------+------+------+------+------
- a | b | c | d | c
- a | b | c | | d
-(2 rows)
-
--- Test out coerced (casted) constraints
-SELECT cast('1' as dnotnull);
- dnotnull
-----------
- 1
-(1 row)
-
-SELECT cast(NULL as dnotnull); -- fail
-ERROR: domain dnotnull does not allow null values
-SELECT cast(cast(NULL as dnull) as dnotnull); -- fail
-ERROR: domain dnotnull does not allow null values
-SELECT cast(col4 as dnotnull) from nulltest; -- fail
-ERROR: domain dnotnull does not allow null values
--- cleanup
-drop table nulltest;
-drop domain dnotnull restrict;
-drop domain dnull restrict;
-drop domain dcheck restrict;
-create domain ddef1 int4 DEFAULT 3;
-create domain ddef2 oid DEFAULT '12';
--- Type mixing, function returns int8
-create domain ddef3 text DEFAULT 5;
-create sequence ddef4_seq;
-create domain ddef4 int4 DEFAULT nextval('ddef4_seq');
-create domain ddef5 numeric(8,2) NOT NULL DEFAULT '12.12';
-create table defaulttest
- ( col1 ddef1
- , col2 ddef2
- , col3 ddef3
- , col4 ddef4 PRIMARY KEY
- , col5 ddef1 NOT NULL DEFAULT NULL
- , col6 ddef2 DEFAULT '88'
- , col7 ddef4 DEFAULT 8000
- , col8 ddef5
- );
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "defaulttest_pkey" for table "defaulttest"
-insert into defaulttest(col4) values(0); -- fails, col5 defaults to null
-ERROR: null value in column "col5" violates not-null constraint
-DETAIL: Failing row contains (3, 12, 5, 0, null, 88, 8000, 12.12).
-alter table defaulttest alter column col5 drop default;
-insert into defaulttest default values; -- succeeds, inserts domain default
--- We used to treat SET DEFAULT NULL as equivalent to DROP DEFAULT; wrong
-alter table defaulttest alter column col5 set default null;
-insert into defaulttest(col4) values(0); -- fails
-ERROR: null value in column "col5" violates not-null constraint
-DETAIL: Failing row contains (3, 12, 5, 0, null, 88, 8000, 12.12).
-alter table defaulttest alter column col5 drop default;
-insert into defaulttest default values;
-insert into defaulttest default values;
--- Test defaults with copy
-COPY defaulttest(col5) FROM stdin;
-select * from defaulttest order by 1,2,3,4,5,6,7,8;
- col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8
-------+------+------+------+------+------+------+-------
- 3 | 12 | 5 | 1 | 3 | 88 | 8000 | 12.12
- 3 | 12 | 5 | 2 | 3 | 88 | 8000 | 12.12
- 3 | 12 | 5 | 3 | 3 | 88 | 8000 | 12.12
- 3 | 12 | 5 | 4 | 42 | 88 | 8000 | 12.12
-(4 rows)
-
-drop table defaulttest cascade;
--- Test ALTER DOMAIN .. NOT NULL
-create domain dnotnulltest integer;
-create table domnotnull
-( col1 dnotnulltest
-, col2 dnotnulltest
-);
-insert into domnotnull default values;
-alter domain dnotnulltest set not null; -- fails
-ERROR: column "col1" of table "domnotnull" contains null values
-update domnotnull set col1 = 5;
-alter domain dnotnulltest set not null; -- fails
-ERROR: column "col2" of table "domnotnull" contains null values
-update domnotnull set col2 = 6;
-alter domain dnotnulltest set not null;
-update domnotnull set col1 = null; -- fails
-ERROR: domain dnotnulltest does not allow null values
-alter domain dnotnulltest drop not null;
-update domnotnull set col1 = null;
-drop domain dnotnulltest cascade;
-NOTICE: drop cascades to 2 other objects
-DETAIL: drop cascades to table domnotnull column col1
-drop cascades to table domnotnull column col2
--- Test ALTER DOMAIN .. DEFAULT ..
-create table domdeftest (col1 ddef1);
-insert into domdeftest default values;
-select * from domdeftest order by 1;
- col1
-------
- 3
-(1 row)
-
-alter domain ddef1 set default '42';
-insert into domdeftest default values;
-select * from domdeftest order by 1;
- col1
-------
- 3
- 42
-(2 rows)
-
-alter domain ddef1 drop default;
-insert into domdeftest default values;
-select * from domdeftest order by 1;
- col1
-------
- 3
- 42
-
-(3 rows)
-
-drop table domdeftest;
--- Test ALTER DOMAIN .. CONSTRAINT ..
-create domain con as integer;
-create table domcontest (col1 con);
-insert into domcontest values (1);
-insert into domcontest values (2);
-alter domain con add constraint t check (VALUE < 1); -- fails
-ERROR: column "col1" of table "domcontest" contains values that violate the new constraint
-alter domain con add constraint t check (VALUE < 34);
-alter domain con add check (VALUE > 0);
-insert into domcontest values (-5); -- fails
-ERROR: value for domain con violates check constraint "con_check"
-insert into domcontest values (42); -- fails
-ERROR: value for domain con violates check constraint "t"
-insert into domcontest values (5);
-alter domain con drop constraint t;
-insert into domcontest values (-5); --fails
-ERROR: value for domain con violates check constraint "con_check"
-insert into domcontest values (42);
-alter domain con drop constraint nonexistent;
-ERROR: constraint "nonexistent" of domain "con" does not exist
-alter domain con drop constraint if exists nonexistent;
-NOTICE: constraint "nonexistent" of domain "con" does not exist, skipping
--- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID
-create domain things AS INT;
-CREATE TABLE thethings (stuff things);
-INSERT INTO thethings (stuff) VALUES (55);
-ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11);
-ERROR: column "stuff" of table "thethings" contains values that violate the new constraint
-ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11) NOT VALID;
-ALTER DOMAIN things VALIDATE CONSTRAINT meow;
-ERROR: column "stuff" of table "thethings" contains values that violate the new constraint
-UPDATE thethings SET stuff = 10;
-ALTER DOMAIN things VALIDATE CONSTRAINT meow;
--- Confirm ALTER DOMAIN with RULES.
-create table domtab (col1 integer);
-create domain dom as integer;
-create view domview as select cast(col1 as dom) from domtab;
-insert into domtab (col1) values (null);
-insert into domtab (col1) values (5);
-select * from domview order by 1;
- col1
-------
- 5
-
-(2 rows)
-
-alter domain dom set not null;
-select * from domview; -- fail
-ERROR: domain dom does not allow null values
-alter domain dom drop not null;
-select * from domview order by 1;
- col1
-------
- 5
-
-(2 rows)
-
-alter domain dom add constraint domchkgt6 check(value > 6);
-select * from domview; --fail
-ERROR: value for domain dom violates check constraint "domchkgt6"
-alter domain dom drop constraint domchkgt6 restrict;
-select * from domview order by 1;
- col1
-------
- 5
-
-(2 rows)
-
--- cleanup
-drop domain ddef1 restrict;
-drop domain ddef2 restrict;
-drop domain ddef3 restrict;
-drop domain ddef4 restrict;
-drop domain ddef5 restrict;
-drop sequence ddef4_seq;
--- Test domains over domains
-create domain vchar4 varchar(4);
-create domain dinter vchar4 check (substring(VALUE, 1, 1) = 'x');
-create domain dtop dinter check (substring(VALUE, 2, 1) = '1');
-select 'x123'::dtop;
- dtop
-------
- x123
-(1 row)
-
-select 'x1234'::dtop; -- explicit coercion should truncate
- dtop
-------
- x123
-(1 row)
-
-select 'y1234'::dtop; -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-select 'y123'::dtop; -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-select 'yz23'::dtop; -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-select 'xz23'::dtop; -- fail
-ERROR: value for domain dtop violates check constraint "dtop_check"
-create temp table dtest(f1 dtop);
-insert into dtest values('x123');
-insert into dtest values('x1234'); -- fail, implicit coercion
-ERROR: value too long for type character varying(4)
-insert into dtest values('y1234'); -- fail, implicit coercion
-ERROR: value too long for type character varying(4)
-insert into dtest values('y123'); -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-insert into dtest values('yz23'); -- fail
-ERROR: value for domain dtop violates check constraint "dinter_check"
-insert into dtest values('xz23'); -- fail
-ERROR: value for domain dtop violates check constraint "dtop_check"
-drop table dtest;
-drop domain vchar4 cascade;
-NOTICE: drop cascades to 2 other objects
-DETAIL: drop cascades to type dinter
-drop cascades to type dtop
--- Make sure that constraints of newly-added domain columns are
--- enforced correctly, even if there's no default value for the new
--- column. Per bug #1433
-create domain str_domain as text not null;
-create table domain_test (a int, b int);
-insert into domain_test values (1, 2);
-insert into domain_test values (1, 2);
--- should fail
-alter table domain_test add column c str_domain;
-ERROR: domain str_domain does not allow null values
-create domain str_domain2 as text check (value <> 'foo') default 'foo';
--- should fail
-alter table domain_test add column d str_domain2;
-ERROR: value for domain str_domain2 violates check constraint "str_domain2_check"
--- Check that domain constraints on prepared statement parameters of
--- unknown type are enforced correctly.
-create domain pos_int as int4 check (value > 0) not null;
-prepare s1 as select $1::pos_int = 10 as "is_ten";
-execute s1(10);
- is_ten
---------
- t
-(1 row)
-
-execute s1(0); -- should fail
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-execute s1(NULL); -- should fail
-ERROR: domain pos_int does not allow null values
--- Check that domain constraints on plpgsql function parameters, results,
--- and local variables are enforced correctly.
-create function doubledecrement(p1 pos_int) returns pos_int as $$
-declare v pos_int;
-begin
- return p1;
-end$$ language plpgsql;
-select doubledecrement(3); -- fail because of implicit null assignment
-ERROR: domain pos_int does not allow null values
-CONTEXT: PL/pgSQL function doubledecrement(pos_int) line 3 during statement block local variable initialization
-create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
-declare v pos_int := 0;
-begin
- return p1;
-end$$ language plpgsql;
-select doubledecrement(3); -- fail at initialization assignment
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-CONTEXT: PL/pgSQL function doubledecrement(pos_int) line 3 during statement block local variable initialization
-create or replace function doubledecrement(p1 pos_int) returns pos_int as $$
-declare v pos_int := 1;
-begin
- v := p1 - 1;
- return v - 1;
-end$$ language plpgsql;
-select doubledecrement(null); -- fail before call
-ERROR: domain pos_int does not allow null values
-select doubledecrement(0); -- fail before call
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-select doubledecrement(1); -- fail at assignment to v
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-CONTEXT: PL/pgSQL function doubledecrement(pos_int) line 4 at assignment
-select doubledecrement(2); -- fail at return
-ERROR: value for domain pos_int violates check constraint "pos_int_check"
-CONTEXT: PL/pgSQL function doubledecrement(pos_int) while casting return value to function's return type
-select doubledecrement(3); -- good
- doubledecrement
------------------
- 1
-(1 row)
-
--- Check that ALTER DOMAIN tests columns of derived types
-create domain posint as int4;
--- Currently, this doesn't work for composite types, but verify it complains
-create type ddtest1 as (f1 posint);
-create table ddtest2(f1 ddtest1);
-insert into ddtest2 values(row(-1));
-alter domain posint add constraint c1 check(value >= 0);
-ERROR: cannot alter type "posint" because column "ddtest2.f1" uses it
-drop table ddtest2;
-create table ddtest2(f1 ddtest1[]);
-insert into ddtest2 values('{(-1)}');
-alter domain posint add constraint c1 check(value >= 0);
-ERROR: cannot alter type "posint" because column "ddtest2.f1" uses it
-drop table ddtest2;
-alter domain posint add constraint c1 check(value >= 0);
-create domain posint2 as posint check (value % 2 = 0);
-create table ddtest2(f1 posint2);
-insert into ddtest2 values(11); -- fail
-ERROR: value for domain posint2 violates check constraint "posint2_check"
-insert into ddtest2 values(-2); -- fail
-ERROR: value for domain posint2 violates check constraint "c1"
-insert into ddtest2 values(2);
-alter domain posint add constraint c2 check(value >= 10); -- fail
-ERROR: column "f1" of table "ddtest2" contains values that violate the new constraint
-alter domain posint add constraint c2 check(value > 0); -- OK
-drop table ddtest2;
-drop type ddtest1;
-drop domain posint cascade;
-NOTICE: drop cascades to type posint2
---
--- Check enforcement of domain-related typmod in plpgsql (bug #5717)
---
-create or replace function array_elem_check(numeric) returns numeric as $$
-declare
- x numeric(4,2)[1];
-begin
- x[1] := $1;
- return x[1];
-end$$ language plpgsql;
-select array_elem_check(121.00);
-ERROR: numeric field overflow
-DETAIL: A field with precision 4, scale 2 must round to an absolute value less than 10^2.
-CONTEXT: PL/pgSQL function array_elem_check(numeric) line 5 at assignment
-select array_elem_check(1.23456);
- array_elem_check
-------------------
- 1.23
-(1 row)
-
-create domain mynums as numeric(4,2)[1];
-create or replace function array_elem_check(numeric) returns numeric as $$
-declare
- x mynums;
-begin
- x[1] := $1;
- return x[1];
-end$$ language plpgsql;
-select array_elem_check(121.00);
-ERROR: numeric field overflow
-DETAIL: A field with precision 4, scale 2 must round to an absolute value less than 10^2.
-CONTEXT: PL/pgSQL function array_elem_check(numeric) line 5 at assignment
-select array_elem_check(1.23456);
- array_elem_check
-------------------
- 1.23
-(1 row)
-
-create domain mynums2 as mynums;
-create or replace function array_elem_check(numeric) returns numeric as $$
-declare
- x mynums2;
-begin
- x[1] := $1;
- return x[1];
-end$$ language plpgsql;
-select array_elem_check(121.00);
-ERROR: numeric field overflow
-DETAIL: A field with precision 4, scale 2 must round to an absolute value less than 10^2.
-CONTEXT: PL/pgSQL function array_elem_check(numeric) line 5 at assignment
-select array_elem_check(1.23456);
- array_elem_check
-------------------
- 1.23
-(1 row)
-
-drop function array_elem_check(numeric);
---
--- Check enforcement of array-level domain constraints
---
-create domain orderedpair as int[2] check (value[1] < value[2]);
-select array[1,2]::orderedpair;
- array
--------
- {1,2}
-(1 row)
-
-select array[2,1]::orderedpair; -- fail
-ERROR: value for domain orderedpair violates check constraint "orderedpair_check"
-create temp table op (f1 orderedpair);
-insert into op values (array[1,2]);
-insert into op values (array[2,1]); -- fail
-ERROR: value for domain orderedpair violates check constraint "orderedpair_check"
-update op set f1[2] = 3;
-update op set f1[2] = 0; -- fail
-ERROR: value for domain orderedpair violates check constraint "orderedpair_check"
-select * from op;
- f1
--------
- {1,3}
-(1 row)
-
-create or replace function array_elem_check(int) returns int as $$
-declare
- x orderedpair := '{1,2}';
-begin
- x[2] := $1;
- return x[2];
-end$$ language plpgsql;
-select array_elem_check(3);
- array_elem_check
-------------------
- 3
-(1 row)
-
-select array_elem_check(-1);
-ERROR: value for domain orderedpair violates check constraint "orderedpair_check"
-CONTEXT: PL/pgSQL function array_elem_check(integer) line 5 at assignment
-drop function array_elem_check(int);
---
--- Renaming
---
-create domain testdomain1 as int;
-alter domain testdomain1 rename to testdomain2;
-alter type testdomain2 rename to testdomain3; -- alter type also works
-drop domain testdomain3;
---
--- Renaming domain constraints
---
-create domain testdomain1 as int constraint unsigned check (value > 0);
-alter domain testdomain1 rename constraint unsigned to unsigned_foo;
-alter domain testdomain1 drop constraint unsigned_foo;
-drop domain testdomain1;
+++ /dev/null
---
--- FLOAT4
---
-CREATE TABLE FLOAT4_TBL (f1 float4);
-INSERT INTO FLOAT4_TBL(f1) VALUES (' 0.0');
-INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30 ');
-INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 ');
-INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
-INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
--- test for over and under flow
-INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
-ERROR: value out of range: overflow
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
-ERROR: value out of range: overflow
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
-ERROR: value out of range: underflow
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
-ERROR: value out of range: underflow
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
- ^
--- bad input
-INSERT INTO FLOAT4_TBL(f1) VALUES ('');
-ERROR: invalid input syntax for type real: ""
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES (' ');
-ERROR: invalid input syntax for type real: " "
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' ');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz');
-ERROR: invalid input syntax for type real: "xyz"
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0');
-ERROR: invalid input syntax for type real: "5.0.0"
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0');
-ERROR: invalid input syntax for type real: "5 . 0"
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0');
-ERROR: invalid input syntax for type real: "5. 0"
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0');
-ERROR: invalid input syntax for type real: " - 3.0"
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0');
- ^
-INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5');
-ERROR: invalid input syntax for type real: "123 5"
-LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5');
- ^
--- special inputs
-SELECT 'NaN'::float4;
- float4
---------
- NaN
-(1 row)
-
-SELECT 'nan'::float4;
- float4
---------
- NaN
-(1 row)
-
-SELECT ' NAN '::float4;
- float4
---------
- NaN
-(1 row)
-
-SELECT 'infinity'::float4;
- float4
-----------
- Infinity
-(1 row)
-
-SELECT ' -INFINiTY '::float4;
- float4
------------
- -Infinity
-(1 row)
-
--- bad special inputs
-SELECT 'N A N'::float4;
-ERROR: invalid input syntax for type real: "N A N"
-LINE 1: SELECT 'N A N'::float4;
- ^
-SELECT 'NaN x'::float4;
-ERROR: invalid input syntax for type real: "NaN x"
-LINE 1: SELECT 'NaN x'::float4;
- ^
-SELECT ' INFINITY x'::float4;
-ERROR: invalid input syntax for type real: " INFINITY x"
-LINE 1: SELECT ' INFINITY x'::float4;
- ^
-SELECT 'Infinity'::float4 + 100.0;
- ?column?
-----------
- Infinity
-(1 row)
-
-SELECT 'Infinity'::float4 / 'Infinity'::float4;
- ?column?
-----------
- NaN
-(1 row)
-
-SELECT 'nan'::float4 / 'nan'::float4;
- ?column?
-----------
- NaN
-(1 row)
-
-SELECT 'nan'::numeric::float4;
- float4
---------
- NaN
-(1 row)
-
-SELECT '' AS five, * FROM FLOAT4_TBL ORDER BY f1;
- five | f1
-------+-------------
- | -34.84
- | 0
- | 1.23457e-20
- | 1004.3
- | 1.23457e+20
-(5 rows)
-
-SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <> '1004.3' ORDER BY f1;
- four | f1
-------+-------------
- | -34.84
- | 0
- | 1.23457e-20
- | 1.23457e+20
-(4 rows)
-
-SELECT '' AS one, f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3';
- one | f1
------+--------
- | 1004.3
-(1 row)
-
-SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE '1004.3' > f.f1 ORDER BY f1;
- three | f1
--------+-------------
- | -34.84
- | 0
- | 1.23457e-20
-(3 rows)
-
-SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE f.f1 < '1004.3' ORDER BY f1;
- three | f1
--------+-------------
- | -34.84
- | 0
- | 1.23457e-20
-(3 rows)
-
-SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE '1004.3' >= f.f1 ORDER BY f1;
- four | f1
-------+-------------
- | -34.84
- | 0
- | 1.23457e-20
- | 1004.3
-(4 rows)
-
-SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <= '1004.3' ORDER BY f1;
- four | f1
-------+-------------
- | -34.84
- | 0
- | 1.23457e-20
- | 1004.3
-(4 rows)
-
-SELECT '' AS three, f.f1, f.f1 * '-10' AS x FROM FLOAT4_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | x
--------+-------------+--------------
- | 1.23457e-20 | -1.23457e-19
- | 1004.3 | -10043
- | 1.23457e+20 | -1.23457e+21
-(3 rows)
-
-SELECT '' AS three, f.f1, f.f1 + '-10' AS x FROM FLOAT4_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | x
--------+-------------+-------------
- | 1.23457e-20 | -10
- | 1004.3 | 994.3
- | 1.23457e+20 | 1.23457e+20
-(3 rows)
-
-SELECT '' AS three, f.f1, f.f1 / '-10' AS x FROM FLOAT4_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | x
--------+-------------+--------------
- | 1.23457e-20 | -1.23457e-21
- | 1004.3 | -100.43
- | 1.23457e+20 | -1.23457e+19
-(3 rows)
-
-SELECT '' AS three, f.f1, f.f1 - '-10' AS x FROM FLOAT4_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | x
--------+-------------+-------------
- | 1.23457e-20 | 10
- | 1004.3 | 1014.3
- | 1.23457e+20 | 1.23457e+20
-(3 rows)
-
--- test divide by zero
-SELECT '' AS bad, f.f1 / '0.0' from FLOAT4_TBL f;
-ERROR: division by zero
-SELECT '' AS five, * FROM FLOAT4_TBL ORDER BY f1;
- five | f1
-------+-------------
- | -34.84
- | 0
- | 1.23457e-20
- | 1004.3
- | 1.23457e+20
-(5 rows)
-
--- test the unary float4abs operator
-SELECT '' AS five, f.f1, @f.f1 AS abs_f1 FROM FLOAT4_TBL f ORDER BY f1;
- five | f1 | abs_f1
-------+-------------+-------------
- | -34.84 | 34.84
- | 0 | 0
- | 1.23457e-20 | 1.23457e-20
- | 1004.3 | 1004.3
- | 1.23457e+20 | 1.23457e+20
-(5 rows)
-
-UPDATE FLOAT4_TBL
- SET f1 = FLOAT4_TBL.f1 * '-1'
- WHERE FLOAT4_TBL.f1 > '0.0';
-ERROR: Partition column can't be updated in current version
-SELECT '' AS five, * FROM FLOAT4_TBL ORDER BY f1;
- five | f1
-------+-------------
- | -34.84
- | 0
- | 1.23457e-20
- | 1004.3
- | 1.23457e+20
-(5 rows)
-
+++ /dev/null
---
--- FLOAT8
---
-CREATE TABLE FLOAT8_TBL(f1 float8);
-INSERT INTO FLOAT8_TBL(f1) VALUES (' 0.0 ');
-INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30 ');
-INSERT INTO FLOAT8_TBL(f1) VALUES (' -34.84');
-INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200');
-INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200');
--- test for underflow and overflow handling
-SELECT '10e400'::float8;
-ERROR: "10e400" is out of range for type double precision
-LINE 1: SELECT '10e400'::float8;
- ^
-SELECT '-10e400'::float8;
-ERROR: "-10e400" is out of range for type double precision
-LINE 1: SELECT '-10e400'::float8;
- ^
-SELECT '10e-400'::float8;
-ERROR: "10e-400" is out of range for type double precision
-LINE 1: SELECT '10e-400'::float8;
- ^
-SELECT '-10e-400'::float8;
-ERROR: "-10e-400" is out of range for type double precision
-LINE 1: SELECT '-10e-400'::float8;
- ^
--- bad input
-INSERT INTO FLOAT8_TBL(f1) VALUES ('');
-ERROR: invalid input syntax for type double precision: ""
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
-ERROR: invalid input syntax for type double precision: " "
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
-ERROR: invalid input syntax for type double precision: "xyz"
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
-ERROR: invalid input syntax for type double precision: "5.0.0"
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
-ERROR: invalid input syntax for type double precision: "5 . 0"
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
-ERROR: invalid input syntax for type double precision: "5. 0"
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
-ERROR: invalid input syntax for type double precision: " - 3"
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
-ERROR: invalid input syntax for type double precision: "123 5"
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
- ^
--- special inputs
-SELECT 'NaN'::float8;
- float8
---------
- NaN
-(1 row)
-
-SELECT 'nan'::float8;
- float8
---------
- NaN
-(1 row)
-
-SELECT ' NAN '::float8;
- float8
---------
- NaN
-(1 row)
-
-SELECT 'infinity'::float8;
- float8
-----------
- Infinity
-(1 row)
-
-SELECT ' -INFINiTY '::float8;
- float8
------------
- -Infinity
-(1 row)
-
--- bad special inputs
-SELECT 'N A N'::float8;
-ERROR: invalid input syntax for type double precision: "N A N"
-LINE 1: SELECT 'N A N'::float8;
- ^
-SELECT 'NaN x'::float8;
-ERROR: invalid input syntax for type double precision: "NaN x"
-LINE 1: SELECT 'NaN x'::float8;
- ^
-SELECT ' INFINITY x'::float8;
-ERROR: invalid input syntax for type double precision: " INFINITY x"
-LINE 1: SELECT ' INFINITY x'::float8;
- ^
-SELECT 'Infinity'::float8 + 100.0;
- ?column?
-----------
- Infinity
-(1 row)
-
-SELECT 'Infinity'::float8 / 'Infinity'::float8;
- ?column?
-----------
- NaN
-(1 row)
-
-SELECT 'nan'::float8 / 'nan'::float8;
- ?column?
-----------
- NaN
-(1 row)
-
-SELECT 'nan'::numeric::float8;
- float8
---------
- NaN
-(1 row)
-
-SELECT '' AS five, * FROM FLOAT8_TBL ORDER BY f1;
- five | f1
-------+----------------------
- | -34.84
- | 0
- | 1.2345678901234e-200
- | 1004.3
- | 1.2345678901234e+200
-(5 rows)
-
-SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <> '1004.3' ORDER BY f1;
- four | f1
-------+----------------------
- | -34.84
- | 0
- | 1.2345678901234e-200
- | 1.2345678901234e+200
-(4 rows)
-
-SELECT '' AS one, f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3';
- one | f1
------+--------
- | 1004.3
-(1 row)
-
-SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1 ORDER BY f1;
- three | f1
--------+----------------------
- | -34.84
- | 0
- | 1.2345678901234e-200
-(3 rows)
-
-SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3' ORDER BY f1;
- three | f1
--------+----------------------
- | -34.84
- | 0
- | 1.2345678901234e-200
-(3 rows)
-
-SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1 ORDER BY f1;
- four | f1
-------+----------------------
- | -34.84
- | 0
- | 1.2345678901234e-200
- | 1004.3
-(4 rows)
-
-SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3' ORDER BY f1;
- four | f1
-------+----------------------
- | -34.84
- | 0
- | 1.2345678901234e-200
- | 1004.3
-(4 rows)
-
-SELECT '' AS three, f.f1, f.f1 * '-10' AS x
- FROM FLOAT8_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | x
--------+----------------------+-----------------------
- | 1.2345678901234e-200 | -1.2345678901234e-199
- | 1004.3 | -10043
- | 1.2345678901234e+200 | -1.2345678901234e+201
-(3 rows)
-
-SELECT '' AS three, f.f1, f.f1 + '-10' AS x
- FROM FLOAT8_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | x
--------+----------------------+----------------------
- | 1.2345678901234e-200 | -10
- | 1004.3 | 994.3
- | 1.2345678901234e+200 | 1.2345678901234e+200
-(3 rows)
-
-SELECT '' AS three, f.f1, f.f1 / '-10' AS x
- FROM FLOAT8_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | x
--------+----------------------+-----------------------
- | 1.2345678901234e-200 | -1.2345678901234e-201
- | 1004.3 | -100.43
- | 1.2345678901234e+200 | -1.2345678901234e+199
-(3 rows)
-
-SELECT '' AS three, f.f1, f.f1 - '-10' AS x
- FROM FLOAT8_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | x
--------+----------------------+----------------------
- | 1.2345678901234e-200 | 10
- | 1004.3 | 1014.3
- | 1.2345678901234e+200 | 1.2345678901234e+200
-(3 rows)
-
-SELECT '' AS one, f.f1 ^ '2.0' AS square_f1
- FROM FLOAT8_TBL f where f.f1 = '1004.3';
- one | square_f1
------+------------
- | 1008618.49
-(1 row)
-
--- absolute value
-SELECT '' AS five, f.f1, @f.f1 AS abs_f1
- FROM FLOAT8_TBL f ORDER BY f1;
- five | f1 | abs_f1
-------+----------------------+----------------------
- | -34.84 | 34.84
- | 0 | 0
- | 1.2345678901234e-200 | 1.2345678901234e-200
- | 1004.3 | 1004.3
- | 1.2345678901234e+200 | 1.2345678901234e+200
-(5 rows)
-
--- truncate
-SELECT '' AS five, f.f1, trunc(f.f1) AS trunc_f1
- FROM FLOAT8_TBL f ORDER BY f1;
- five | f1 | trunc_f1
-------+----------------------+----------------------
- | -34.84 | -34
- | 0 | 0
- | 1.2345678901234e-200 | 0
- | 1004.3 | 1004
- | 1.2345678901234e+200 | 1.2345678901234e+200
-(5 rows)
-
--- round
-SELECT '' AS five, f.f1, round(f.f1) AS round_f1
- FROM FLOAT8_TBL f ORDER BY f1;
- five | f1 | round_f1
-------+----------------------+----------------------
- | -34.84 | -35
- | 0 | 0
- | 1.2345678901234e-200 | 0
- | 1004.3 | 1004
- | 1.2345678901234e+200 | 1.2345678901234e+200
-(5 rows)
-
--- ceil / ceiling
-select ceil(f1) as ceil_f1 from float8_tbl f ORDER BY f1;
- ceil_f1
-----------------------
- -34
- 0
- 1
- 1005
- 1.2345678901234e+200
-(5 rows)
-
-select ceiling(f1) as ceiling_f1 from float8_tbl f ORDER BY f1;
- ceiling_f1
-----------------------
- -34
- 0
- 1
- 1005
- 1.2345678901234e+200
-(5 rows)
-
--- floor
-select floor(f1) as floor_f1 from float8_tbl f ORDER BY f1;
- floor_f1
-----------------------
- -35
- 0
- 0
- 1004
- 1.2345678901234e+200
-(5 rows)
-
--- sign
-select sign(f1) as sign_f1 from float8_tbl f ORDER BY f1;
- sign_f1
----------
- -1
- 0
- 1
- 1
- 1
-(5 rows)
-
--- square root
-SELECT sqrt(float8 '64') AS eight;
- eight
--------
- 8
-(1 row)
-
-SELECT |/ float8 '64' AS eight;
- eight
--------
- 8
-(1 row)
-
-SELECT '' AS three, f.f1, |/f.f1 AS sqrt_f1
- FROM FLOAT8_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | sqrt_f1
--------+----------------------+-----------------------
- | 1.2345678901234e-200 | 1.11111110611109e-100
- | 1004.3 | 31.6906926399535
- | 1.2345678901234e+200 | 1.11111110611109e+100
-(3 rows)
-
--- power
-SELECT power(float8 '144', float8 '0.5');
- power
--------
- 12
-(1 row)
-
--- take exp of ln(f.f1)
-SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1
- FROM FLOAT8_TBL f
- WHERE f.f1 > '0.0' ORDER BY f1;
- three | f1 | exp_ln_f1
--------+----------------------+-----------------------
- | 1.2345678901234e-200 | 1.23456789012339e-200
- | 1004.3 | 1004.3
- | 1.2345678901234e+200 | 1.23456789012338e+200
-(3 rows)
-
--- cube root
-SELECT ||/ float8 '27' AS three;
- three
--------
- 3
-(1 row)
-
-SELECT '' AS five, f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f ORDER BY f1;
- five | f1 | cbrt_f1
-------+----------------------+----------------------
- | -34.84 | -3.26607421344208
- | 0 | 0
- | 1.2345678901234e-200 | 2.3112042409018e-67
- | 1004.3 | 10.014312837827
- | 1.2345678901234e+200 | 4.97933859234765e+66
-(5 rows)
-
-SELECT '' AS five, * FROM FLOAT8_TBL ORDER BY f1;
- five | f1
-------+----------------------
- | -34.84
- | 0
- | 1.2345678901234e-200
- | 1004.3
- | 1.2345678901234e+200
-(5 rows)
-
-UPDATE FLOAT8_TBL
- SET f1 = FLOAT8_TBL.f1 * '-1'
- WHERE FLOAT8_TBL.f1 > '0.0';
-ERROR: Partition column can't be updated in current version
-
-SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f ORDER BY f1;
-ERROR: value out of range: overflow
-SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f ORDER BY f1;
-ERROR: value out of range: overflow
-SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5;
- ?column?
-----------
- 2
-(1 row)
-
-SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
-ERROR: cannot take logarithm of zero
-SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0';
-ERROR: cannot take logarithm of a negative number
-SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f ORDER BY f1;
-ERROR: value out of range: overflow
-SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f;
-ERROR: division by zero
-SELECT '' AS five, * FROM FLOAT8_TBL ORDER BY f1;
- five | f1
-------+----------------------
- | -34.84
- | 0
- | 1.2345678901234e-200
- | 1004.3
- | 1.2345678901234e+200
-(5 rows)
-
--- test for over- and underflow
-INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
-ERROR: "10e400" is out of range for type double precision
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
-ERROR: "-10e400" is out of range for type double precision
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
-ERROR: "10e-400" is out of range for type double precision
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
- ^
-INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
-ERROR: "-10e-400" is out of range for type double precision
-LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
- ^
--- maintain external table consistency across platforms
--- delete all values and reinsert well-behaved ones
-DELETE FROM FLOAT8_TBL;
-INSERT INTO FLOAT8_TBL(f1) VALUES ('0.0');
-INSERT INTO FLOAT8_TBL(f1) VALUES ('-34.84');
-INSERT INTO FLOAT8_TBL(f1) VALUES ('-1004.30');
-INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e+200');
-INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e-200');
-SELECT '' AS five, * FROM FLOAT8_TBL ORDER BY f1;
- five | f1
-------+-----------------------
- | -1.2345678901234e+200
- | -1004.3
- | -34.84
- | -1.2345678901234e-200
- | 0
-(5 rows)
-
+++ /dev/null
--- from http://www.depesz.com/index.php/2010/04/19/getting-unique-elements/
-CREATE TEMP TABLE articles (
- id int CONSTRAINT articles_pkey PRIMARY KEY,
- keywords text,
- title text UNIQUE NOT NULL,
- body text UNIQUE,
- created date
-);
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "articles_pkey" for table "articles"
-ERROR: Unique index of partitioned table must contain the hash/modulo distribution column.
-CREATE TEMP TABLE articles_in_category (
- article_id int,
- category_id int,
- changed date,
- PRIMARY KEY (article_id, category_id)
-);
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "articles_in_category_pkey" for table "articles_in_category"
--- test functional dependencies based on primary keys/unique constraints
--- base tables
--- group by primary key (OK)
-SELECT id, keywords, title, body, created
-FROM articles
-GROUP BY id;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles
- ^
--- group by unique not null (fail/todo)
-SELECT id, keywords, title, body, created
-FROM articles
-GROUP BY title;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles
- ^
--- group by unique nullable (fail)
-SELECT id, keywords, title, body, created
-FROM articles
-GROUP BY body;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles
- ^
--- group by something else (fail)
-SELECT id, keywords, title, body, created
-FROM articles
-GROUP BY keywords;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles
- ^
--- multiple tables
--- group by primary key (OK)
-SELECT a.id, a.keywords, a.title, a.body, a.created
-FROM articles AS a, articles_in_category AS aic
-WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138)
-GROUP BY a.id;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles AS a, articles_in_category AS aic
- ^
--- group by something else (fail)
-SELECT a.id, a.keywords, a.title, a.body, a.created
-FROM articles AS a, articles_in_category AS aic
-WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138)
-GROUP BY aic.article_id, aic.category_id;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles AS a, articles_in_category AS aic
- ^
--- JOIN syntax
--- group by left table's primary key (OK)
-SELECT a.id, a.keywords, a.title, a.body, a.created
-FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
-WHERE aic.category_id in (14,62,70,53,138)
-GROUP BY a.id;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles AS a JOIN articles_in_category AS aic ON a.id ...
- ^
--- group by something else (fail)
-SELECT a.id, a.keywords, a.title, a.body, a.created
-FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
-WHERE aic.category_id in (14,62,70,53,138)
-GROUP BY aic.article_id, aic.category_id;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles AS a JOIN articles_in_category AS aic ON a.id ...
- ^
--- group by right table's (composite) primary key (OK)
-SELECT aic.changed
-FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
-WHERE aic.category_id in (14,62,70,53,138)
-GROUP BY aic.category_id, aic.article_id;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles AS a JOIN articles_in_category AS aic ON a.id ...
- ^
--- group by right table's partial primary key (fail)
-SELECT aic.changed
-FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
-WHERE aic.category_id in (14,62,70,53,138)
-GROUP BY aic.article_id;
-ERROR: relation "articles" does not exist
-LINE 2: FROM articles AS a JOIN articles_in_category AS aic ON a.id ...
- ^
--- example from documentation
-CREATE TEMP TABLE products (product_id int, name text, price numeric);
-CREATE TEMP TABLE sales (product_id int, units int);
--- OK
-SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
- FROM products p LEFT JOIN sales s USING (product_id)
- GROUP BY product_id, p.name, p.price;
- product_id | name | sales
-------------+------+-------
-(0 rows)
-
--- fail
-SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
- FROM products p LEFT JOIN sales s USING (product_id)
- GROUP BY product_id;
-ERROR: column "p.name" must appear in the GROUP BY clause or be used in an aggregate function
-LINE 1: SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
- ^
-ALTER TABLE products ADD PRIMARY KEY (product_id);
-NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "products_pkey" for table "products"
--- OK now
-SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
- FROM products p LEFT JOIN sales s USING (product_id)
- GROUP BY product_id;
- product_id | name | sales
-------------+------+-------
-(0 rows)
-
--- Drupal example, http://drupal.org/node/555530
-CREATE TEMP TABLE node (
- nid SERIAL,
- vid integer NOT NULL default '0',
- type varchar(32) NOT NULL default '',
- title varchar(128) NOT NULL default '',
- uid integer NOT NULL default '0',
- status integer NOT NULL default '1',
- created integer NOT NULL default '0',
- -- snip
- PRIMARY KEY (nid, vid)
-);
-NOTICE: CREATE TABLE will create implicit sequence "node_nid_seq" for serial column "node.nid"
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "node_pkey" for table "node"
-CREATE TEMP TABLE users (
- uid integer NOT NULL default '0',
- name varchar(60) NOT NULL default '',
- pass varchar(32) NOT NULL default '',
- -- snip
- PRIMARY KEY (uid),
- UNIQUE (name)
-);
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "users_pkey" for table "users"
-ERROR: Unique index of partitioned table must contain the hash/modulo distribution column.
--- OK
-SELECT u.uid, u.name FROM node n
-INNER JOIN users u ON u.uid = n.uid
-WHERE n.type = 'blog' AND n.status = 1
-GROUP BY u.uid, u.name;
-ERROR: relation "users" does not exist
-LINE 2: INNER JOIN users u ON u.uid = n.uid
- ^
--- OK
-SELECT u.uid, u.name FROM node n
-INNER JOIN users u ON u.uid = n.uid
-WHERE n.type = 'blog' AND n.status = 1
-GROUP BY u.uid;
-ERROR: relation "users" does not exist
-LINE 2: INNER JOIN users u ON u.uid = n.uid
- ^
--- Check views and dependencies
--- fail
-CREATE TEMP VIEW fdv1 AS
-SELECT id, keywords, title, body, created
-FROM articles
-GROUP BY body;
-ERROR: relation "articles" does not exist
-LINE 3: FROM articles
- ^
--- OK
-CREATE TEMP VIEW fdv1 AS
-SELECT id, keywords, title, body, created
-FROM articles
-GROUP BY id;
-ERROR: relation "articles" does not exist
-LINE 3: FROM articles
- ^
--- fail
-ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT;
-ERROR: relation "articles" does not exist
-DROP VIEW fdv1;
-ERROR: view "fdv1" does not exist
--- multiple dependencies
-CREATE TEMP VIEW fdv2 AS
-SELECT a.id, a.keywords, a.title, aic.category_id, aic.changed
-FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id
-WHERE aic.category_id in (14,62,70,53,138)
-GROUP BY a.id, aic.category_id, aic.article_id;
-ERROR: relation "articles" does not exist
-LINE 3: FROM articles AS a JOIN articles_in_category AS aic ON a.id ...
- ^
-ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail
-ERROR: relation "articles" does not exist
-ALTER TABLE articles_in_category DROP CONSTRAINT articles_in_category_pkey RESTRICT; --fail
-DROP VIEW fdv2;
-ERROR: view "fdv2" does not exist
--- nested queries
-CREATE TEMP VIEW fdv3 AS
-SELECT id, keywords, title, body, created
-FROM articles
-GROUP BY id
-UNION
-SELECT id, keywords, title, body, created
-FROM articles
-GROUP BY id;
-ERROR: relation "articles" does not exist
-LINE 3: FROM articles
- ^
-ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail
-ERROR: relation "articles" does not exist
-DROP VIEW fdv3;
-ERROR: view "fdv3" does not exist
-CREATE TEMP VIEW fdv4 AS
-SELECT * FROM articles WHERE title IN (SELECT title FROM articles GROUP BY id);
-ERROR: relation "articles" does not exist
-LINE 2: SELECT * FROM articles WHERE title IN (SELECT title FROM art...
- ^
-ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail
-ERROR: relation "articles" does not exist
-DROP VIEW fdv4;
-ERROR: view "fdv4" does not exist
--- prepared query plans: this results in failure on reuse
-PREPARE foo AS
- SELECT id, keywords, title, body, created
- FROM articles
- GROUP BY id;
-ERROR: relation "articles" does not exist
-LINE 3: FROM articles
- ^
-EXECUTE foo;
-ERROR: prepared statement "foo" does not exist
-ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT;
-ERROR: relation "articles" does not exist
-EXECUTE foo; -- fail
-ERROR: prepared statement "foo" does not exist
+++ /dev/null
--- pg_regress should ensure that this default value applies; however
--- we can't rely on any specific default value of vacuum_cost_delay
-SHOW datestyle;
- DateStyle
----------------
- Postgres, MDY
-(1 row)
-
--- SET to some nondefault value
-SET vacuum_cost_delay TO 40;
-SET datestyle = 'ISO, YMD';
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
--- SET LOCAL has no effect outside of a transaction
-SET LOCAL vacuum_cost_delay TO 50;
-WARNING: SET LOCAL can only be used in transaction blocks
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SET LOCAL datestyle = 'SQL';
-WARNING: SET LOCAL can only be used in transaction blocks
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
--- SET LOCAL within a transaction that commits
-BEGIN;
-SET LOCAL vacuum_cost_delay TO 50;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 50ms
-(1 row)
-
-SET LOCAL datestyle = 'SQL';
-SHOW datestyle;
- DateStyle
------------
- SQL, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
--------------------------
- 08/13/2006 12:34:56 PDT
-(1 row)
-
-COMMIT;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
--- SET should be reverted after ROLLBACK
-BEGIN;
-SET vacuum_cost_delay TO 60;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 60ms
-(1 row)
-
-SET datestyle = 'German';
-SHOW datestyle;
- DateStyle
--------------
- German, DMY
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
--------------------------
- 13.08.2006 12:34:56 PDT
-(1 row)
-
-ROLLBACK;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
--- Some tests with subtransactions
-BEGIN;
-SET vacuum_cost_delay TO 70;
-SET datestyle = 'MDY';
-SHOW datestyle;
- DateStyle
------------
- ISO, MDY
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
-SAVEPOINT first_sp;
-ERROR: SAVEPOINT is not yet supported.
-SET vacuum_cost_delay TO 80;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW vacuum_cost_delay;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SET datestyle = 'German, DMY';
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK TO first_sp;
-ERROR: no such savepoint
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SAVEPOINT second_sp;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SET vacuum_cost_delay TO 90;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SET datestyle = 'SQL, YMD';
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SAVEPOINT third_sp;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SET vacuum_cost_delay TO 100;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW vacuum_cost_delay;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SET datestyle = 'Postgres, MDY';
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK TO third_sp;
-ERROR: no such savepoint
-SHOW vacuum_cost_delay;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK TO second_sp;
-ERROR: no such savepoint
-SHOW vacuum_cost_delay;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
--- SET LOCAL with Savepoints
-BEGIN;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
-SAVEPOINT sp;
-ERROR: SAVEPOINT is not yet supported.
-SET LOCAL vacuum_cost_delay TO 30;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW vacuum_cost_delay;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SET LOCAL datestyle = 'Postgres, MDY';
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK TO sp;
-ERROR: no such savepoint
-SHOW vacuum_cost_delay;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
--- SET LOCAL persists through RELEASE (which was not true in 8.0-8.2)
-BEGIN;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
-SAVEPOINT sp;
-ERROR: SAVEPOINT is not yet supported.
-SET LOCAL vacuum_cost_delay TO 30;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW vacuum_cost_delay;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SET LOCAL datestyle = 'Postgres, MDY';
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-RELEASE SAVEPOINT sp;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW vacuum_cost_delay;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SHOW datestyle;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT '2006-08-13 12:34:56'::timestamptz;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
--- SET followed by SET LOCAL
-BEGIN;
-SET vacuum_cost_delay TO 40;
-SET LOCAL vacuum_cost_delay TO 50;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 50ms
-(1 row)
-
-SET datestyle = 'ISO, DMY';
-SET LOCAL datestyle = 'Postgres, MDY';
-SHOW datestyle;
- DateStyle
----------------
- Postgres, MDY
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------------
- Sun Aug 13 12:34:56 2006 PDT
-(1 row)
-
-COMMIT;
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 40ms
-(1 row)
-
-SHOW datestyle;
- DateStyle
------------
- ISO, DMY
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
---
--- Test RESET. We use datestyle because the reset value is forced by
--- pg_regress, so it doesn't depend on the installation's configuration.
---
-SET datestyle = iso, ymd;
-SHOW datestyle;
- DateStyle
------------
- ISO, YMD
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------
- 2006-08-13 12:34:56-07
-(1 row)
-
-RESET datestyle;
-SHOW datestyle;
- DateStyle
----------------
- Postgres, MDY
-(1 row)
-
-SELECT '2006-08-13 12:34:56'::timestamptz;
- timestamptz
-------------------------------
- Sun Aug 13 12:34:56 2006 PDT
-(1 row)
-
---
--- Test DISCARD TEMP
---
-CREATE TEMP TABLE reset_test ( data text ) ON COMMIT DELETE ROWS;
-SELECT relname FROM pg_class WHERE relname = 'reset_test';
- relname
-------------
- reset_test
-(1 row)
-
-DISCARD TEMP;
-SELECT relname FROM pg_class WHERE relname = 'reset_test';
- relname
----------
-(0 rows)
-
---
--- Test DISCARD ALL
---
--- do changes
-DECLARE foo CURSOR WITH HOLD FOR SELECT 1;
-PREPARE foo AS SELECT 1;
-LISTEN foo_event;
-SET vacuum_cost_delay = 13;
-CREATE TEMP TABLE tmp_foo (data text) ON COMMIT DELETE ROWS;
-CREATE ROLE temp_reset_user;
-SET SESSION AUTHORIZATION temp_reset_user;
--- look changes
-SELECT pg_listening_channels();
- pg_listening_channels
------------------------
- foo_event
-(1 row)
-
-SELECT name FROM pg_prepared_statements;
- name
-------
- foo
-(1 row)
-
-SELECT name FROM pg_cursors;
- name
-------
- foo
-(1 row)
-
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 13ms
-(1 row)
-
-SELECT relname from pg_class where relname = 'tmp_foo';
- relname
----------
- tmp_foo
-(1 row)
-
-SELECT current_user = 'temp_reset_user';
- ?column?
-----------
- t
-(1 row)
-
-RESET SESSION AUTHORIZATION;
-DROP TABLE tmp_foo; -- Need to release the ON COMMIT actions
-SET SESSION AUTHORIZATION temp_reset_user;
--- discard everything
-DISCARD ALL;
--- look again
-SELECT pg_listening_channels();
- pg_listening_channels
------------------------
-(0 rows)
-
-SELECT name FROM pg_prepared_statements;
- name
-------
-(0 rows)
-
-SELECT name FROM pg_cursors;
- name
-------
-(0 rows)
-
-SHOW vacuum_cost_delay;
- vacuum_cost_delay
--------------------
- 0
-(1 row)
-
-SELECT relname from pg_class where relname = 'tmp_foo';
- relname
----------
-(0 rows)
-
-SELECT current_user = 'temp_reset_user';
- ?column?
-----------
- f
-(1 row)
-
-DROP ROLE temp_reset_user;
---
--- search_path should react to changes in pg_namespace
---
-set search_path = foo, public, not_there_initially;
-select current_schemas(false);
- current_schemas
------------------
- {public}
-(1 row)
-
-create schema not_there_initially;
-select current_schemas(false);
- current_schemas
-------------------------------
- {public,not_there_initially}
-(1 row)
-
-drop schema not_there_initially;
-select current_schemas(false);
- current_schemas
------------------
- {public}
-(1 row)
-
-reset search_path;
---
--- Tests for function-local GUC settings
---
-set work_mem = '3MB';
-create function report_guc(text) returns text as
-$$ select current_setting($1) $$ language sql
-set work_mem = '1MB';
-select report_guc('work_mem'), current_setting('work_mem');
- report_guc | current_setting
-------------+-----------------
- 1MB | 3MB
-(1 row)
-
-alter function report_guc(text) set work_mem = '2MB';
-select report_guc('work_mem'), current_setting('work_mem');
- report_guc | current_setting
-------------+-----------------
- 2MB | 3MB
-(1 row)
-
-alter function report_guc(text) reset all;
-select report_guc('work_mem'), current_setting('work_mem');
- report_guc | current_setting
-------------+-----------------
- 3MB | 3MB
-(1 row)
-
--- SET LOCAL is restricted by a function SET option
-create or replace function myfunc(int) returns text as $$
-begin
- set local work_mem = '2MB';
- return current_setting('work_mem');
-end $$
-language plpgsql
-set work_mem = '1MB';
-select myfunc(0), current_setting('work_mem');
- myfunc | current_setting
---------+-----------------
- 2MB | 3MB
-(1 row)
-
-alter function myfunc(int) reset all;
-select myfunc(0), current_setting('work_mem');
- myfunc | current_setting
---------+-----------------
- 2MB | 2MB
-(1 row)
-
-set work_mem = '3MB';
--- but SET isn't
-create or replace function myfunc(int) returns text as $$
-begin
- set work_mem = '2MB';
- return current_setting('work_mem');
-end $$
-language plpgsql
-set work_mem = '1MB';
-select myfunc(0), current_setting('work_mem');
- myfunc | current_setting
---------+-----------------
- 2MB | 2MB
-(1 row)
-
-set work_mem = '3MB';
--- it should roll back on error, though
-create or replace function myfunc(int) returns text as $$
-begin
- set work_mem = '2MB';
- perform 1/$1;
- return current_setting('work_mem');
-end $$
-language plpgsql
-set work_mem = '1MB';
-select myfunc(0);
-ERROR: division by zero
-CONTEXT: SQL statement "SELECT 1/$1"
-PL/pgSQL function myfunc(integer) line 4 at PERFORM
-select current_setting('work_mem');
- current_setting
------------------
- 3MB
-(1 row)
-
-select myfunc(1), current_setting('work_mem');
- myfunc | current_setting
---------+-----------------
- 2MB | 2MB
-(1 row)
-
--- Normally, CREATE FUNCTION should complain about invalid values in
--- function SET options; but not if check_function_bodies is off,
--- because that creates ordering hazards for pg_dump
-create function func_with_bad_set() returns int as $$ select 1 $$
-language sql
-set default_text_search_config = no_such_config;
-NOTICE: text search configuration "no_such_config" does not exist
-ERROR: invalid value for parameter "default_text_search_config": "no_such_config"
-set check_function_bodies = off;
-create function func_with_bad_set() returns int as $$ select 1 $$
-language sql
-set default_text_search_config = no_such_config;
-NOTICE: text search configuration "no_such_config" does not exist
-select func_with_bad_set();
-ERROR: invalid value for parameter "default_text_search_config": "no_such_config"
-reset check_function_bodies;
+++ /dev/null
---
--- HASH_INDEX
--- grep 843938989 hash.data
---
-SELECT * FROM hash_i4_heap
- WHERE hash_i4_heap.random = 843938989;
- seqno | random
--------+-----------
- 15 | 843938989
-(1 row)
-
---
--- hash index
--- grep 66766766 hash.data
---
-SELECT * FROM hash_i4_heap
- WHERE hash_i4_heap.random = 66766766;
- seqno | random
--------+--------
-(0 rows)
-
---
--- hash index
--- grep 1505703298 hash.data
---
-SELECT * FROM hash_name_heap
- WHERE hash_name_heap.random = '1505703298'::name;
- seqno | random
--------+------------
- 9838 | 1505703298
-(1 row)
-
---
--- hash index
--- grep 7777777 hash.data
---
-SELECT * FROM hash_name_heap
- WHERE hash_name_heap.random = '7777777'::name;
- seqno | random
--------+--------
-(0 rows)
-
---
--- hash index
--- grep 1351610853 hash.data
---
-SELECT * FROM hash_txt_heap
- WHERE hash_txt_heap.random = '1351610853'::text;
- seqno | random
--------+------------
- 5677 | 1351610853
-(1 row)
-
---
--- hash index
--- grep 111111112222222233333333 hash.data
---
-SELECT * FROM hash_txt_heap
- WHERE hash_txt_heap.random = '111111112222222233333333'::text;
- seqno | random
--------+--------
-(0 rows)
-
---
--- hash index
--- grep 444705537 hash.data
---
-SELECT * FROM hash_f8_heap
- WHERE hash_f8_heap.random = '444705537'::float8;
- seqno | random
--------+-----------
- 7853 | 444705537
-(1 row)
-
---
--- hash index
--- grep 88888888 hash.data
---
-SELECT * FROM hash_f8_heap
- WHERE hash_f8_heap.random = '88888888'::float8;
- seqno | random
--------+--------
-(0 rows)
-
---
--- hash index
--- grep '^90[^0-9]' hashovfl.data
---
--- SELECT count(*) AS i988 FROM hash_ovfl_heap
--- WHERE x = 90;
---
--- hash index
--- grep '^1000[^0-9]' hashovfl.data
---
--- SELECT count(*) AS i0 FROM hash_ovfl_heap
--- WHERE x = 1000;
---
--- HASH
---
-UPDATE hash_i4_heap
- SET random = 1
- WHERE hash_i4_heap.seqno = 1492;
-SELECT h.seqno AS i1492, h.random AS i1
- FROM hash_i4_heap h
- WHERE h.random = 1;
- i1492 | i1
--------+----
- 1492 | 1
-(1 row)
-
-UPDATE hash_i4_heap
- SET seqno = 20000
- WHERE hash_i4_heap.random = 1492795354;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT h.seqno AS i20000
- FROM hash_i4_heap h
- WHERE h.random = 1492795354;
- i20000
---------
- 6866
-(1 row)
-
-UPDATE hash_name_heap
- SET random = '0123456789abcdef'::name
- WHERE hash_name_heap.seqno = 6543;
-SELECT h.seqno AS i6543, h.random AS c0_to_f
- FROM hash_name_heap h
- WHERE h.random = '0123456789abcdef'::name;
- i6543 | c0_to_f
--------+------------------
- 6543 | 0123456789abcdef
-(1 row)
-
-UPDATE hash_name_heap
- SET seqno = 20000
- WHERE hash_name_heap.random = '76652222'::name;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
---
--- this is the row we just replaced; index scan should return zero rows
---
-SELECT h.seqno AS emptyset
- FROM hash_name_heap h
- WHERE h.random = '76652222'::name;
- emptyset
-----------
-(0 rows)
-
-UPDATE hash_txt_heap
- SET random = '0123456789abcdefghijklmnop'::text
- WHERE hash_txt_heap.seqno = 4002;
-SELECT h.seqno AS i4002, h.random AS c0_to_p
- FROM hash_txt_heap h
- WHERE h.random = '0123456789abcdefghijklmnop'::text;
- i4002 | c0_to_p
--------+----------------------------
- 4002 | 0123456789abcdefghijklmnop
-(1 row)
-
-UPDATE hash_txt_heap
- SET seqno = 20000
- WHERE hash_txt_heap.random = '959363399'::text;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT h.seqno AS t20000
- FROM hash_txt_heap h
- WHERE h.random = '959363399'::text;
- t20000
---------
- 5489
-(1 row)
-
-UPDATE hash_f8_heap
- SET random = '-1234.1234'::float8
- WHERE hash_f8_heap.seqno = 8906;
-SELECT h.seqno AS i8096, h.random AS f1234_1234
- FROM hash_f8_heap h
- WHERE h.random = '-1234.1234'::float8;
- i8096 | f1234_1234
--------+------------
- 8906 | -1234.1234
-(1 row)
-
-UPDATE hash_f8_heap
- SET seqno = 20000
- WHERE hash_f8_heap.random = '488912369'::float8;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT h.seqno AS f20000
- FROM hash_f8_heap h
- WHERE h.random = '488912369'::float8;
- f20000
---------
- 8932
-(1 row)
-
--- UPDATE hash_ovfl_heap
--- SET x = 1000
--- WHERE x = 90;
--- this vacuums the index as well
--- VACUUM hash_ovfl_heap;
--- SELECT count(*) AS i0 FROM hash_ovfl_heap
--- WHERE x = 90;
--- SELECT count(*) AS i988 FROM hash_ovfl_heap
--- WHERE x = 1000;
+++ /dev/null
---
--- Test inheritance features
---
-CREATE TABLE a (aa TEXT) distribute by roundrobin;
-CREATE TABLE b (bb TEXT) INHERITS (a) distribute by roundrobin;
-CREATE TABLE c (cc TEXT) INHERITS (a) distribute by roundrobin;
-CREATE TABLE d (dd TEXT) INHERITS (b,c,a) distribute by roundrobin;
-NOTICE: merging multiple inherited definitions of column "aa"
-NOTICE: merging multiple inherited definitions of column "aa"
-INSERT INTO a(aa) VALUES('aaa');
-INSERT INTO a(aa) VALUES('aaaa');
-INSERT INTO a(aa) VALUES('aaaaa');
-INSERT INTO a(aa) VALUES('aaaaaa');
-INSERT INTO a(aa) VALUES('aaaaaaa');
-INSERT INTO a(aa) VALUES('aaaaaaaa');
-INSERT INTO b(aa) VALUES('bbb');
-INSERT INTO b(aa) VALUES('bbbb');
-INSERT INTO b(aa) VALUES('bbbbb');
-INSERT INTO b(aa) VALUES('bbbbbb');
-INSERT INTO b(aa) VALUES('bbbbbbb');
-INSERT INTO b(aa) VALUES('bbbbbbbb');
-INSERT INTO c(aa) VALUES('ccc');
-INSERT INTO c(aa) VALUES('cccc');
-INSERT INTO c(aa) VALUES('ccccc');
-INSERT INTO c(aa) VALUES('cccccc');
-INSERT INTO c(aa) VALUES('ccccccc');
-INSERT INTO c(aa) VALUES('cccccccc');
-INSERT INTO d(aa) VALUES('ddd');
-INSERT INTO d(aa) VALUES('dddd');
-INSERT INTO d(aa) VALUES('ddddd');
-INSERT INTO d(aa) VALUES('dddddd');
-INSERT INTO d(aa) VALUES('ddddddd');
-INSERT INTO d(aa) VALUES('dddddddd');
-SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
-SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
--- In Postgres-XL OIDs are not consistent across the cluster. Hence above
--- queries do not show any result. Hence in order to ensure data consistency, we
--- add following SQLs. In case above set of queries start producing valid
--- results in XC, we should remove the following set
-SELECT * FROM a ORDER BY a.aa;
- aa
-----------
- aaa
- aaaa
- aaaaa
- aaaaaa
- aaaaaaa
- aaaaaaaa
- bbb
- bbbb
- bbbbb
- bbbbbb
- bbbbbbb
- bbbbbbbb
- ccc
- cccc
- ccccc
- cccccc
- ccccccc
- cccccccc
- ddd
- dddd
- ddddd
- dddddd
- ddddddd
- dddddddd
-(24 rows)
-
-SELECT * from b ORDER BY b.aa;
- aa | bb
-----------+----
- bbb |
- bbbb |
- bbbbb |
- bbbbbb |
- bbbbbbb |
- bbbbbbbb |
- ddd |
- dddd |
- ddddd |
- dddddd |
- ddddddd |
- dddddddd |
-(12 rows)
-
-SELECT * FROM c ORDER BY c.aa;
- aa | cc
-----------+----
- ccc |
- cccc |
- ccccc |
- cccccc |
- ccccccc |
- cccccccc |
- ddd |
- dddd |
- ddddd |
- dddddd |
- ddddddd |
- dddddddd |
-(12 rows)
-
-SELECT * from d ORDER BY d.aa;
- aa | bb | cc | dd
-----------+----+----+----
- ddd | | |
- dddd | | |
- ddddd | | |
- dddddd | | |
- ddddddd | | |
- dddddddd | | |
-(6 rows)
-
-SELECT * FROM ONLY a ORDER BY a.aa;
- aa
-----------
- aaa
- aaaa
- aaaaa
- aaaaaa
- aaaaaaa
- aaaaaaaa
-(6 rows)
-
-SELECT * from ONLY b ORDER BY b.aa;
- aa | bb
-----------+----
- bbb |
- bbbb |
- bbbbb |
- bbbbbb |
- bbbbbbb |
- bbbbbbbb |
-(6 rows)
-
-SELECT * FROM ONLY c ORDER BY c.aa;
- aa | cc
-----------+----
- ccc |
- cccc |
- ccccc |
- cccccc |
- ccccccc |
- cccccccc |
-(6 rows)
-
-SELECT * from ONLY d ORDER BY d.aa;
- aa | bb | cc | dd
-----------+----+----+----
- ddd | | |
- dddd | | |
- ddddd | | |
- dddddd | | |
- ddddddd | | |
- dddddddd | | |
-(6 rows)
-
-UPDATE a SET aa='zzzz' WHERE aa='aaaa';
-UPDATE ONLY a SET aa='zzzzz' WHERE aa='aaaaa';
-UPDATE b SET aa='zzz' WHERE aa='aaa';
-UPDATE ONLY b SET aa='zzz' WHERE aa='aaa';
-UPDATE a SET aa='zzzzzz' WHERE aa LIKE 'aaa%';
-SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
-SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
--- In Postgres-XL OIDs are not consistent across the cluster. Hence above
--- queries do not show any result. Hence in order to ensure data consistency, we
--- add following SQLs. In case above set of queries start producing valid
--- results in XC, we should remove the following set
-SELECT * FROM a ORDER BY a.aa;
- aa
-----------
- bbb
- bbbb
- bbbbb
- bbbbbb
- bbbbbbb
- bbbbbbbb
- ccc
- cccc
- ccccc
- cccccc
- ccccccc
- cccccccc
- ddd
- dddd
- ddddd
- dddddd
- ddddddd
- dddddddd
- zzzz
- zzzzz
- zzzzzz
- zzzzzz
- zzzzzz
- zzzzzz
-(24 rows)
-
-SELECT * from b ORDER BY b.aa;
- aa | bb
-----------+----
- bbb |
- bbbb |
- bbbbb |
- bbbbbb |
- bbbbbbb |
- bbbbbbbb |
- ddd |
- dddd |
- ddddd |
- dddddd |
- ddddddd |
- dddddddd |
-(12 rows)
-
-SELECT * FROM c ORDER BY c.aa;
- aa | cc
-----------+----
- ccc |
- cccc |
- ccccc |
- cccccc |
- ccccccc |
- cccccccc |
- ddd |
- dddd |
- ddddd |
- dddddd |
- ddddddd |
- dddddddd |
-(12 rows)
-
-SELECT * from d ORDER BY d.aa;
- aa | bb | cc | dd
-----------+----+----+----
- ddd | | |
- dddd | | |
- ddddd | | |
- dddddd | | |
- ddddddd | | |
- dddddddd | | |
-(6 rows)
-
-SELECT * FROM ONLY a ORDER BY a.aa;
- aa
---------
- zzzz
- zzzzz
- zzzzzz
- zzzzzz
- zzzzzz
- zzzzzz
-(6 rows)
-
-SELECT * from ONLY b ORDER BY b.aa;
- aa | bb
-----------+----
- bbb |
- bbbb |
- bbbbb |
- bbbbbb |
- bbbbbbb |
- bbbbbbbb |
-(6 rows)
-
-SELECT * FROM ONLY c ORDER BY c.aa;
- aa | cc
-----------+----
- ccc |
- cccc |
- ccccc |
- cccccc |
- ccccccc |
- cccccccc |
-(6 rows)
-
-SELECT * from ONLY d ORDER BY d.aa;
- aa | bb | cc | dd
-----------+----+----+----
- ddd | | |
- dddd | | |
- ddddd | | |
- dddddd | | |
- ddddddd | | |
- dddddddd | | |
-(6 rows)
-
-UPDATE b SET aa='new';
-SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
-SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
--- In Postgres-XL OIDs are not consistent across the cluster. Hence above
--- queries do not show any result. Hence in order to ensure data consistency, we
--- add following SQLs. In case above set of queries start producing valid
--- results in XC, we should remove the following set
-SELECT * FROM a ORDER BY a.aa;
- aa
-----------
- ccc
- cccc
- ccccc
- cccccc
- ccccccc
- cccccccc
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- zzzz
- zzzzz
- zzzzzz
- zzzzzz
- zzzzzz
- zzzzzz
-(24 rows)
-
-SELECT * from b ORDER BY b.aa;
- aa | bb
------+----
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
-(12 rows)
-
-SELECT * FROM c ORDER BY c.aa;
- aa | cc
-----------+----
- ccc |
- cccc |
- ccccc |
- cccccc |
- ccccccc |
- cccccccc |
- new |
- new |
- new |
- new |
- new |
- new |
-(12 rows)
-
-SELECT * from d ORDER BY d.aa;
- aa | bb | cc | dd
------+----+----+----
- new | | |
- new | | |
- new | | |
- new | | |
- new | | |
- new | | |
-(6 rows)
-
-SELECT * FROM ONLY a ORDER BY a.aa;
- aa
---------
- zzzz
- zzzzz
- zzzzzz
- zzzzzz
- zzzzzz
- zzzzzz
-(6 rows)
-
-SELECT * from ONLY b ORDER BY b.aa;
- aa | bb
------+----
- new |
- new |
- new |
- new |
- new |
- new |
-(6 rows)
-
-SELECT * FROM ONLY c ORDER BY c.aa;
- aa | cc
-----------+----
- ccc |
- cccc |
- ccccc |
- cccccc |
- ccccccc |
- cccccccc |
-(6 rows)
-
-SELECT * from ONLY d ORDER BY d.aa;
- aa | bb | cc | dd
------+----+----+----
- new | | |
- new | | |
- new | | |
- new | | |
- new | | |
- new | | |
-(6 rows)
-
-UPDATE a SET aa='new';
-DELETE FROM ONLY c WHERE aa='new';
-SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
-SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
--- In Postgres-XL OIDs are not consistent across the cluster. Hence above
--- queries do not show any result. Hence in order to ensure data consistency, we
--- add following SQLs. In case above set of queries start producing valid
--- results in XC, we should remove the following set
-SELECT * FROM a ORDER BY a.aa;
- aa
------
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
- new
-(18 rows)
-
-SELECT * from b ORDER BY b.aa;
- aa | bb
------+----
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
- new |
-(12 rows)
-
-SELECT * FROM c ORDER BY c.aa;
- aa | cc
------+----
- new |
- new |
- new |
- new |
- new |
- new |
-(6 rows)
-
-SELECT * from d ORDER BY d.aa;
- aa | bb | cc | dd
------+----+----+----
- new | | |
- new | | |
- new | | |
- new | | |
- new | | |
- new | | |
-(6 rows)
-
-SELECT * FROM ONLY a ORDER BY a.aa;
- aa
------
- new
- new
- new
- new
- new
- new
-(6 rows)
-
-SELECT * from ONLY b ORDER BY b.aa;
- aa | bb
------+----
- new |
- new |
- new |
- new |
- new |
- new |
-(6 rows)
-
-SELECT * FROM ONLY c ORDER BY c.aa;
- aa | cc
-----+----
-(0 rows)
-
-SELECT * from ONLY d ORDER BY d.aa;
- aa | bb | cc | dd
------+----+----+----
- new | | |
- new | | |
- new | | |
- new | | |
- new | | |
- new | | |
-(6 rows)
-
-DELETE FROM a;
-SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
-SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
- relname | aa
----------+----
-(0 rows)
-
-SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
- relname | aa | bb
----------+----+----
-(0 rows)
-
-SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
- relname | aa | cc
----------+----+----
-(0 rows)
-
-SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
- relname | aa | bb | cc | dd
----------+----+----+----+----
-(0 rows)
-
--- In Postgres-XL OIDs are not consistent across the cluster. Hence above
--- queries do not show any result. Hence in order to ensure data consistency, we
--- add following SQLs. In case above set of queries start producing valid
--- results in XC, we should remove the following set
-SELECT * FROM a ORDER BY a.aa;
- aa
-----
-(0 rows)
-
-SELECT * from b ORDER BY b.aa;
- aa | bb
-----+----
-(0 rows)
-
-SELECT * FROM c ORDER BY c.aa;
- aa | cc
-----+----
-(0 rows)
-
-SELECT * from d ORDER BY d.aa;
- aa | bb | cc | dd
-----+----+----+----
-(0 rows)
-
-SELECT * FROM ONLY a ORDER BY a.aa;
- aa
-----
-(0 rows)
-
-SELECT * from ONLY b ORDER BY b.aa;
- aa | bb
-----+----
-(0 rows)
-
-SELECT * FROM ONLY c ORDER BY c.aa;
- aa | cc
-----+----
-(0 rows)
-
-SELECT * from ONLY d ORDER BY d.aa;
- aa | bb | cc | dd
-----+----+----+----
-(0 rows)
-
--- Confirm PRIMARY KEY adds NOT NULL constraint to child table
-CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a);
-INSERT INTO z VALUES (NULL, 'text'); -- should fail
-ERROR: null value in column "aa" violates not-null constraint
-DETAIL: Failing row contains (null, text).
--- Check UPDATE with inherited target and an inherited source table
-create temp table foo(f1 int, f2 int);
-create temp table foo2(f3 int) inherits (foo);
-create temp table bar(f1 int, f2 int);
-create temp table bar2(f3 int) inherits (bar);
-insert into foo values(1,1);
-insert into foo values(3,3);
-insert into foo2 values(2,2,2);
-insert into foo2 values(3,3,3);
-insert into bar values(1,1);
-insert into bar values(2,2);
-insert into bar values(3,3);
-insert into bar values(4,4);
-insert into bar2 values(1,1,1);
-insert into bar2 values(2,2,2);
-insert into bar2 values(3,3,3);
-insert into bar2 values(4,4,4);
-update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
---select tableoid::regclass::text as relname, bar.* from bar order by 1,2;
--- In Postgres-XL OIDs are not consistent across the cluster. Hence above
--- queries do not show any result. Hence in order to ensure data consistency, we
--- add following SQLs. In case above set of queries start producing valid
--- results in XC, we should remove the following set
-SELECT * FROM bar ORDER BY f1, f2;
- f1 | f2
-----+-----
- 1 | 101
- 1 | 101
- 2 | 102
- 2 | 102
- 3 | 103
- 3 | 103
- 4 | 4
- 4 | 4
-(8 rows)
-
-SELECT * FROM ONLY bar ORDER BY f1, f2;
- f1 | f2
-----+-----
- 1 | 101
- 2 | 102
- 3 | 103
- 4 | 4
-(4 rows)
-
-SELECT * FROM bar2 ORDER BY f1, f2;
- f1 | f2 | f3
-----+-----+----
- 1 | 101 | 1
- 2 | 102 | 2
- 3 | 103 | 3
- 4 | 4 | 4
-(4 rows)
-
--- Check UPDATE with inherited target and an appendrel subquery
-update bar set f2 = f2 + 100
-from
- ( select f1 from foo union all select f1+3 from foo ) ss
-where bar.f1 = ss.f1;
---select tableoid::regclass::text as relname, bar.* from bar order by 1,2;
-/* Test multiple inheritance of column defaults */
-CREATE TABLE firstparent (tomorrow date default now()::date + 1);
-CREATE TABLE secondparent (tomorrow date default now() :: date + 1);
-CREATE TABLE jointchild () INHERITS (firstparent, secondparent); -- ok
-NOTICE: merging multiple inherited definitions of column "tomorrow"
-CREATE TABLE thirdparent (tomorrow date default now()::date - 1);
-CREATE TABLE otherchild () INHERITS (firstparent, thirdparent); -- not ok
-NOTICE: merging multiple inherited definitions of column "tomorrow"
-ERROR: column "tomorrow" inherits conflicting default values
-HINT: To resolve the conflict, specify a default explicitly.
-CREATE TABLE otherchild (tomorrow date default now())
- INHERITS (firstparent, thirdparent); -- ok, child resolves ambiguous default
-NOTICE: merging multiple inherited definitions of column "tomorrow"
-NOTICE: merging column "tomorrow" with inherited definition
-DROP TABLE firstparent, secondparent, jointchild, thirdparent, otherchild;
--- Test changing the type of inherited columns
-insert into d values('test','one','two','three');
-alter table a alter column aa type integer using bit_length(aa);
-select * from d;
- aa | bb | cc | dd
-----+-----+-----+-------
- 32 | one | two | three
-(1 row)
-
--- Test non-inheritable parent constraints
-create table p1(ff1 int);
-alter table p1 add constraint p1chk check (ff1 > 0) no inherit;
-alter table p1 add constraint p2chk check (ff1 > 10);
--- connoinherit should be true for NO INHERIT constraint
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.connoinherit from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname = 'p1' order by 1,2;
- relname | conname | contype | conislocal | coninhcount | connoinherit
----------+---------+---------+------------+-------------+--------------
- p1 | p1chk | c | t | 0 | t
- p1 | p2chk | c | t | 0 | f
-(2 rows)
-
--- Test that child does not inherit NO INHERIT constraints
-create table c1 () inherits (p1);
-\d p1
- Table "public.p1"
- Column | Type | Modifiers
---------+---------+-----------
- ff1 | integer |
-Check constraints:
- "p1chk" CHECK (ff1 > 0) NO INHERIT
- "p2chk" CHECK (ff1 > 10)
-Number of child tables: 1 (Use \d+ to list them.)
-
-\d c1
- Table "public.c1"
- Column | Type | Modifiers
---------+---------+-----------
- ff1 | integer |
-Check constraints:
- "p2chk" CHECK (ff1 > 10)
-Inherits: p1
-
-drop table p1 cascade;
-NOTICE: drop cascades to table c1
--- Tests for casting between the rowtypes of parent and child
--- tables. See the pgsql-hackers thread beginning Dec. 4/04
-create table base (i integer);
-create table derived () inherits (base);
-insert into derived (i) values (0);
-select derived::base from derived;
- derived
----------
- (0)
-(1 row)
-
-drop table derived;
-drop table base;
-create table p1(ff1 int);
-create table p2(f1 text);
-create function p2text(p2) returns text as 'select $1.f1' language sql;
-create table c1(f3 int) inherits(p1,p2);
-insert into c1 values(123456789, 'hi', 42);
-select p2text(c1.*) from c1;
- p2text
---------
- hi
-(1 row)
-
-drop function p2text(p2);
-drop table c1;
-drop table p2;
-drop table p1;
-CREATE TABLE ac (aa TEXT);
-alter table ac add constraint ac_check check (aa is not null);
-CREATE TABLE bc (bb TEXT) INHERITS (ac);
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+----------+---------+------------+-------------+------------------
- ac | ac_check | c | t | 0 | (aa IS NOT NULL)
- bc | ac_check | c | f | 1 | (aa IS NOT NULL)
-(2 rows)
-
-insert into ac (aa) values (NULL);
-ERROR: new row for relation "ac" violates check constraint "ac_check"
-DETAIL: Failing row contains (null).
-insert into bc (aa) values (NULL);
-ERROR: new row for relation "bc" violates check constraint "ac_check"
-DETAIL: Failing row contains (null, null).
-alter table bc drop constraint ac_check; -- fail, disallowed
-ERROR: cannot drop inherited constraint "ac_check" of relation "bc"
-alter table ac drop constraint ac_check;
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+---------+---------+------------+-------------+--------
-(0 rows)
-
--- try the unnamed-constraint case
-alter table ac add check (aa is not null);
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+-------------+---------+------------+-------------+------------------
- ac | ac_aa_check | c | t | 0 | (aa IS NOT NULL)
- bc | ac_aa_check | c | f | 1 | (aa IS NOT NULL)
-(2 rows)
-
-insert into ac (aa) values (NULL);
-ERROR: new row for relation "ac" violates check constraint "ac_aa_check"
-DETAIL: Failing row contains (null).
-insert into bc (aa) values (NULL);
-ERROR: new row for relation "bc" violates check constraint "ac_aa_check"
-DETAIL: Failing row contains (null, null).
-alter table bc drop constraint ac_aa_check; -- fail, disallowed
-ERROR: cannot drop inherited constraint "ac_aa_check" of relation "bc"
-alter table ac drop constraint ac_aa_check;
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+---------+---------+------------+-------------+--------
-(0 rows)
-
-alter table ac add constraint ac_check check (aa is not null);
-alter table bc no inherit ac;
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+----------+---------+------------+-------------+------------------
- ac | ac_check | c | t | 0 | (aa IS NOT NULL)
- bc | ac_check | c | t | 0 | (aa IS NOT NULL)
-(2 rows)
-
-alter table bc drop constraint ac_check;
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+----------+---------+------------+-------------+------------------
- ac | ac_check | c | t | 0 | (aa IS NOT NULL)
-(1 row)
-
-alter table ac drop constraint ac_check;
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+---------+---------+------------+-------------+--------
-(0 rows)
-
-drop table bc;
-drop table ac;
-create table ac (a int constraint check_a check (a <> 0));
-create table bc (a int constraint check_a check (a <> 0), b int constraint check_b check (b <> 0)) inherits (ac);
-NOTICE: merging column "a" with inherited definition
-NOTICE: merging constraint "check_a" with inherited definition
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+---------+---------+------------+-------------+----------
- ac | check_a | c | t | 0 | (a <> 0)
- bc | check_a | c | t | 1 | (a <> 0)
- bc | check_b | c | t | 0 | (b <> 0)
-(3 rows)
-
-drop table bc;
-drop table ac;
-create table ac (a int constraint check_a check (a <> 0));
-create table bc (b int constraint check_b check (b <> 0));
-create table cc (c int constraint check_c check (c <> 0)) inherits (ac, bc);
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+---------+---------+------------+-------------+----------
- ac | check_a | c | t | 0 | (a <> 0)
- bc | check_b | c | t | 0 | (b <> 0)
- cc | check_a | c | f | 1 | (a <> 0)
- cc | check_b | c | f | 1 | (b <> 0)
- cc | check_c | c | t | 0 | (c <> 0)
-(5 rows)
-
-alter table cc no inherit bc;
-select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2;
- relname | conname | contype | conislocal | coninhcount | consrc
----------+---------+---------+------------+-------------+----------
- ac | check_a | c | t | 0 | (a <> 0)
- bc | check_b | c | t | 0 | (b <> 0)
- cc | check_a | c | f | 1 | (a <> 0)
- cc | check_b | c | t | 0 | (b <> 0)
- cc | check_c | c | t | 0 | (c <> 0)
-(5 rows)
-
-drop table cc;
-drop table bc;
-drop table ac;
-create table p1(f1 int);
-create table p2(f2 int);
-create table c1(f3 int) inherits(p1,p2);
-insert into c1 values(1,-1,2);
-alter table p2 add constraint cc check (f2>0); -- fail
-ERROR: check constraint "cc" is violated by some row
-alter table p2 add check (f2>0); -- check it without a name, too
-ERROR: check constraint "p2_f2_check" is violated by some row
-delete from c1;
-insert into c1 values(1,1,2);
-alter table p2 add check (f2>0);
-insert into c1 values(1,-1,2); -- fail
-ERROR: new row for relation "c1" violates check constraint "p2_f2_check"
-DETAIL: Failing row contains (1, -1, 2).
-create table c2(f3 int) inherits(p1,p2);
-\d c2
- Table "public.c2"
- Column | Type | Modifiers
---------+---------+-----------
- f1 | integer |
- f2 | integer |
- f3 | integer |
-Check constraints:
- "p2_f2_check" CHECK (f2 > 0)
-Inherits: p1,
- p2
-
-create table c3 (f4 int) inherits(c1,c2);
-NOTICE: merging multiple inherited definitions of column "f1"
-NOTICE: merging multiple inherited definitions of column "f2"
-NOTICE: merging multiple inherited definitions of column "f3"
-\d c3
- Table "public.c3"
- Column | Type | Modifiers
---------+---------+-----------
- f1 | integer |
- f2 | integer |
- f3 | integer |
- f4 | integer |
-Check constraints:
- "p2_f2_check" CHECK (f2 > 0)
-Inherits: c1,
- c2
-
-drop table p1 cascade;
-NOTICE: drop cascades to 3 other objects
-DETAIL: drop cascades to table c1
-drop cascades to table c2
-drop cascades to table c3
-drop table p2 cascade;
-create table pp1 (f1 int);
-create table cc1 (f2 text, f3 int) inherits (pp1);
-alter table pp1 add column a1 int check (a1 > 0);
-\d cc1
- Table "public.cc1"
- Column | Type | Modifiers
---------+---------+-----------
- f1 | integer |
- f2 | text |
- f3 | integer |
- a1 | integer |
-Check constraints:
- "pp1_a1_check" CHECK (a1 > 0)
-Inherits: pp1
-
-create table cc2(f4 float) inherits(pp1,cc1);
-NOTICE: merging multiple inherited definitions of column "f1"
-NOTICE: merging multiple inherited definitions of column "a1"
-\d cc2
- Table "public.cc2"
- Column | Type | Modifiers
---------+------------------+-----------
- f1 | integer |
- a1 | integer |
- f2 | text |
- f3 | integer |
- f4 | double precision |
-Check constraints:
- "pp1_a1_check" CHECK (a1 > 0)
-Inherits: pp1,
- cc1
-
-alter table pp1 add column a2 int check (a2 > 0);
-NOTICE: merging definition of column "a2" for child "cc2"
-NOTICE: merging constraint "pp1_a2_check" with inherited definition
-\d cc2
- Table "public.cc2"
- Column | Type | Modifiers
---------+------------------+-----------
- f1 | integer |
- a1 | integer |
- f2 | text |
- f3 | integer |
- f4 | double precision |
- a2 | integer |
-Check constraints:
- "pp1_a1_check" CHECK (a1 > 0)
- "pp1_a2_check" CHECK (a2 > 0)
-Inherits: pp1,
- cc1
-
-drop table pp1 cascade;
-NOTICE: drop cascades to 2 other objects
-DETAIL: drop cascades to table cc1
-drop cascades to table cc2
--- Test for renaming in simple multiple inheritance
-CREATE TABLE inht1 (a int, b int);
-CREATE TABLE inhs1 (b int, c int);
-CREATE TABLE inhts (d int) INHERITS (inht1, inhs1);
-NOTICE: merging multiple inherited definitions of column "b"
-ALTER TABLE inht1 RENAME a TO aa;
-ALTER TABLE inht1 RENAME b TO bb; -- to be failed
-ERROR: cannot rename inherited column "b"
-ALTER TABLE inhts RENAME aa TO aaa; -- to be failed
-ERROR: cannot rename inherited column "aa"
-ALTER TABLE inhts RENAME d TO dd;
-\d+ inhts
- Table "public.inhts"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+---------+-----------+---------+--------------+-------------
- aa | integer | | plain | |
- b | integer | | plain | |
- c | integer | | plain | |
- dd | integer | | plain | |
-Inherits: inht1,
- inhs1
-Distribute By: HASH(aa)
-Location Nodes: ALL DATANODES
-
-DROP TABLE inhts;
--- Test for renaming in diamond inheritance
-CREATE TABLE inht2 (x int) INHERITS (inht1);
-CREATE TABLE inht3 (y int) INHERITS (inht1);
-CREATE TABLE inht4 (z int) INHERITS (inht2, inht3);
-NOTICE: merging multiple inherited definitions of column "aa"
-NOTICE: merging multiple inherited definitions of column "b"
-ALTER TABLE inht1 RENAME aa TO aaa;
-\d+ inht4
- Table "public.inht4"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+---------+-----------+---------+--------------+-------------
- aaa | integer | | plain | |
- b | integer | | plain | |
- x | integer | | plain | |
- y | integer | | plain | |
- z | integer | | plain | |
-Inherits: inht2,
- inht3
-Distribute By: HASH(aaa)
-Location Nodes: ALL DATANODES
-
-CREATE TABLE inhts (d int) INHERITS (inht2, inhs1);
-NOTICE: merging multiple inherited definitions of column "b"
-ALTER TABLE inht1 RENAME aaa TO aaaa;
-ALTER TABLE inht1 RENAME b TO bb; -- to be failed
-ERROR: cannot rename inherited column "b"
-\d+ inhts
- Table "public.inhts"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+---------+-----------+---------+--------------+-------------
- aaaa | integer | | plain | |
- b | integer | | plain | |
- x | integer | | plain | |
- c | integer | | plain | |
- d | integer | | plain | |
-Inherits: inht2,
- inhs1
-Distribute By: HASH(aaaa)
-Location Nodes: ALL DATANODES
-
-WITH RECURSIVE r AS (
- SELECT 'inht1'::regclass AS inhrelid
-UNION ALL
- SELECT c.inhrelid FROM pg_inherits c, r WHERE r.inhrelid = c.inhparent
-)
-SELECT a.attrelid::regclass, a.attname, a.attinhcount, e.expected
- FROM (SELECT inhrelid, count(*) AS expected FROM pg_inherits
- WHERE inhparent IN (SELECT inhrelid FROM r) GROUP BY inhrelid) e
- JOIN pg_attribute a ON e.inhrelid = a.attrelid WHERE NOT attislocal
- ORDER BY a.attrelid::regclass::name, a.attnum;
- attrelid | attname | attinhcount | expected
-----------+---------+-------------+----------
- inht2 | aaaa | 1 | 1
- inht2 | b | 1 | 1
- inht3 | aaaa | 1 | 1
- inht3 | b | 1 | 1
- inht4 | aaaa | 2 | 2
- inht4 | b | 2 | 2
- inht4 | x | 1 | 2
- inht4 | y | 1 | 2
- inhts | aaaa | 1 | 1
- inhts | b | 2 | 1
- inhts | x | 1 | 1
- inhts | c | 1 | 1
-(12 rows)
-
-DROP TABLE inht1, inhs1 CASCADE;
-NOTICE: drop cascades to 4 other objects
-DETAIL: drop cascades to table inht2
-drop cascades to table inhts
-drop cascades to table inht3
-drop cascades to table inht4
--- Test non-inheritable indices [UNIQUE, EXCLUDE] contraints
-CREATE TABLE test_constraints (id int, val1 varchar, val2 int, UNIQUE(val1, val2));
-CREATE TABLE test_constraints_inh () INHERITS (test_constraints);
-\d+ test_constraints
- Table "public.test_constraints"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+-------------------+-----------+----------+--------------+-------------
- id | integer | | plain | |
- val1 | character varying | | extended | |
- val2 | integer | | plain | |
-Indexes:
- "test_constraints_val1_val2_key" UNIQUE CONSTRAINT, btree (val1, val2)
-Child tables: test_constraints_inh
-Distribute By: HASH(val1)
-Location Nodes: ALL DATANODES
-
-ALTER TABLE ONLY test_constraints DROP CONSTRAINT test_constraints_val1_val2_key;
-\d+ test_constraints
- Table "public.test_constraints"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+-------------------+-----------+----------+--------------+-------------
- id | integer | | plain | |
- val1 | character varying | | extended | |
- val2 | integer | | plain | |
-Child tables: test_constraints_inh
-Distribute By: HASH(val1)
-Location Nodes: ALL DATANODES
-
-\d+ test_constraints_inh
- Table "public.test_constraints_inh"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+-------------------+-----------+----------+--------------+-------------
- id | integer | | plain | |
- val1 | character varying | | extended | |
- val2 | integer | | plain | |
-Inherits: test_constraints
-Distribute By: HASH(val1)
-Location Nodes: ALL DATANODES
-
-DROP TABLE test_constraints_inh;
-DROP TABLE test_constraints;
-CREATE TABLE test_ex_constraints (
- c circle,
- EXCLUDE USING gist (c WITH &&)
-);
-CREATE TABLE test_ex_constraints_inh () INHERITS (test_ex_constraints);
-\d+ test_ex_constraints
- Table "public.test_ex_constraints"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+--------+-----------+---------+--------------+-------------
- c | circle | | plain | |
-Indexes:
- "test_ex_constraints_c_excl" EXCLUDE USING gist (c WITH &&)
-Child tables: test_ex_constraints_inh
-Distribute By: ROUND ROBIN
-Location Nodes: ALL DATANODES
-
-ALTER TABLE test_ex_constraints DROP CONSTRAINT test_ex_constraints_c_excl;
-\d+ test_ex_constraints
- Table "public.test_ex_constraints"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+--------+-----------+---------+--------------+-------------
- c | circle | | plain | |
-Child tables: test_ex_constraints_inh
-Distribute By: ROUND ROBIN
-Location Nodes: ALL DATANODES
-
-\d+ test_ex_constraints_inh
- Table "public.test_ex_constraints_inh"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+--------+-----------+---------+--------------+-------------
- c | circle | | plain | |
-Inherits: test_ex_constraints
-Distribute By: ROUND ROBIN
-Location Nodes: ALL DATANODES
-
-DROP TABLE test_ex_constraints_inh;
-DROP TABLE test_ex_constraints;
--- Test non-inheritable foreign key contraints
-CREATE TABLE test_primary_constraints(id int PRIMARY KEY);
-CREATE TABLE test_foreign_constraints(id1 int REFERENCES test_primary_constraints(id));
-CREATE TABLE test_foreign_constraints_inh () INHERITS (test_foreign_constraints);
-\d+ test_primary_constraints
- Table "public.test_primary_constraints"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+---------+-----------+---------+--------------+-------------
- id | integer | not null | plain | |
-Indexes:
- "test_primary_constraints_pkey" PRIMARY KEY, btree (id)
-Referenced by:
- TABLE "test_foreign_constraints" CONSTRAINT "test_foreign_constraints_id1_fkey" FOREIGN KEY (id1) REFERENCES test_primary_constraints(id)
-Distribute By: HASH(id)
-Location Nodes: ALL DATANODES
-
-\d+ test_foreign_constraints
- Table "public.test_foreign_constraints"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+---------+-----------+---------+--------------+-------------
- id1 | integer | | plain | |
-Foreign-key constraints:
- "test_foreign_constraints_id1_fkey" FOREIGN KEY (id1) REFERENCES test_primary_constraints(id)
-Child tables: test_foreign_constraints_inh
-Distribute By: HASH(id1)
-Location Nodes: ALL DATANODES
-
-ALTER TABLE test_foreign_constraints DROP CONSTRAINT test_foreign_constraints_id1_fkey;
-\d+ test_foreign_constraints
- Table "public.test_foreign_constraints"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+---------+-----------+---------+--------------+-------------
- id1 | integer | | plain | |
-Child tables: test_foreign_constraints_inh
-Distribute By: HASH(id1)
-Location Nodes: ALL DATANODES
-
-\d+ test_foreign_constraints_inh
- Table "public.test_foreign_constraints_inh"
- Column | Type | Modifiers | Storage | Stats target | Description
---------+---------+-----------+---------+--------------+-------------
- id1 | integer | | plain | |
-Inherits: test_foreign_constraints
-Distribute By: HASH(id1)
-Location Nodes: ALL DATANODES
-
-DROP TABLE test_foreign_constraints_inh;
-DROP TABLE test_foreign_constraints;
-DROP TABLE test_primary_constraints;
---
--- Test parameterized append plans for inheritance trees
---
-create temp table patest0 (id, x) as
- select x, x from generate_series(0,1000) x;
-create temp table patest1() inherits (patest0);
-insert into patest1
- select x, x from generate_series(0,1000) x;
-create temp table patest2() inherits (patest0);
-insert into patest2
- select x, x from generate_series(0,1000) x;
-create index patest0i on patest0(id);
-create index patest1i on patest1(id);
-create index patest2i on patest2(id);
-analyze patest0;
-analyze patest1;
-analyze patest2;
-analyze int4_tbl;
-explain (costs off, num_nodes off, nodes off)
-select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
- QUERY PLAN
-----------------------------------------------------------------
- Nested Loop
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Seq Scan on int4_tbl
- Filter: (f1 = 0)
- -> Materialize
- -> Remote Subquery Scan on all
- -> Append
- -> Bitmap Heap Scan on patest0
- Recheck Cond: (id = int4_tbl.f1)
- -> Bitmap Index Scan on patest0i
- Index Cond: (id = int4_tbl.f1)
- -> Index Scan using patest1i on patest1
- Index Cond: (id = int4_tbl.f1)
- -> Index Scan using patest2i on patest2
- Index Cond: (id = int4_tbl.f1)
-(17 rows)
-
-select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
- id | x | f1
-----+---+----
- 0 | 0 | 0
- 0 | 0 | 0
- 0 | 0 | 0
-(3 rows)
-
-drop index patest2i;
-explain (costs off, num_nodes off, nodes off)
-select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
- QUERY PLAN
-----------------------------------------------------------------
- Nested Loop
- -> Limit
- -> Remote Subquery Scan on all
- -> Limit
- -> Seq Scan on int4_tbl
- Filter: (f1 = 0)
- -> Materialize
- -> Remote Subquery Scan on all
- -> Append
- -> Bitmap Heap Scan on patest0
- Recheck Cond: (id = int4_tbl.f1)
- -> Bitmap Index Scan on patest0i
- Index Cond: (id = int4_tbl.f1)
- -> Index Scan using patest1i on patest1
- Index Cond: (id = int4_tbl.f1)
- -> Seq Scan on patest2
- Filter: (int4_tbl.f1 = id)
-(17 rows)
-
-select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
- id | x | f1
-----+---+----
- 0 | 0 | 0
- 0 | 0 | 0
- 0 | 0 | 0
-(3 rows)
-
-drop table patest0 cascade;
-NOTICE: drop cascades to 2 other objects
-DETAIL: drop cascades to table patest1
-drop cascades to table patest2
---
--- Test merge-append plans for inheritance trees
---
-create table matest0 (id serial primary key, name text);
-create table matest1 (id integer primary key) inherits (matest0);
-NOTICE: merging column "id" with inherited definition
-create table matest2 (id integer primary key) inherits (matest0);
-NOTICE: merging column "id" with inherited definition
-create table matest3 (id integer primary key) inherits (matest0);
-NOTICE: merging column "id" with inherited definition
-create index matest0i on matest0 ((1-id));
-create index matest1i on matest1 ((1-id));
--- create index matest2i on matest2 ((1-id)); -- intentionally missing
-create index matest3i on matest3 ((1-id));
-insert into matest1 (name) values ('Test 1');
-insert into matest1 (name) values ('Test 2');
-insert into matest2 (name) values ('Test 3');
-insert into matest2 (name) values ('Test 4');
-insert into matest3 (name) values ('Test 5');
-insert into matest3 (name) values ('Test 6');
-set enable_indexscan = off; -- force use of seqscan/sort, so no merge
-explain (verbose, costs off, nodes off) select * from matest0 order by 1-id;
- QUERY PLAN
-------------------------------------------------------------------
- Remote Subquery Scan on all
- Output: id, name, (1 - id)
- -> Sort
- Output: matest0.id, matest0.name, ((1 - matest0.id))
- Sort Key: ((1 - matest0.id))
- -> Result
- Output: matest0.id, matest0.name, (1 - matest0.id)
- -> Append
- -> Seq Scan on public.matest0
- Output: matest0.id, matest0.name
- -> Seq Scan on public.matest1
- Output: matest1.id, matest1.name
- -> Seq Scan on public.matest2
- Output: matest2.id, matest2.name
- -> Seq Scan on public.matest3
- Output: matest3.id, matest3.name
-(16 rows)
-
-select * from matest0 order by 1-id;
- id | name
-----+--------
- 6 | Test 6
- 5 | Test 5
- 4 | Test 4
- 3 | Test 3
- 2 | Test 2
- 1 | Test 1
-(6 rows)
-
-explain (verbose, costs off) select min(1-id) from matest0;
- QUERY PLAN
------------------------------------------------------------
- Aggregate
- Output: min((min((1 - id))))
- -> Remote Subquery Scan on all (datanode_1,datanode_2)
- Output: min((1 - id))
- -> Aggregate
- Output: min((1 - matest0.id))
- -> Append
- -> Seq Scan on public.matest0
- Output: matest0.id
- -> Seq Scan on public.matest1
- Output: matest1.id
- -> Seq Scan on public.matest2
- Output: matest2.id
- -> Seq Scan on public.matest3
- Output: matest3.id
-(15 rows)
-
-select min(1-id) from matest0;
- min
------
- -5
-(1 row)
-
-reset enable_indexscan;
-set enable_seqscan = off; -- plan with fewest seqscans should be merge
-explain (verbose, costs off, nodes off) select * from matest0 order by 1-id;
- QUERY PLAN
----------------------------------------------------------------------
- Remote Subquery Scan on all
- Output: id, name, (1 - id)
- -> Sort
- Output: matest0.id, matest0.name, ((1 - matest0.id))
- Sort Key: ((1 - matest0.id))
- -> Result
- Output: matest0.id, matest0.name, (1 - matest0.id)
- -> Append
- -> Index Scan using matest0i on public.matest0
- Output: matest0.id, matest0.name
- -> Index Scan using matest1i on public.matest1
- Output: matest1.id, matest1.name
- -> Seq Scan on public.matest2
- Output: matest2.id, matest2.name
- -> Index Scan using matest3i on public.matest3
- Output: matest3.id, matest3.name
-(16 rows)
-
-select * from matest0 order by 1-id;
- id | name
-----+--------
- 6 | Test 6
- 5 | Test 5
- 4 | Test 4
- 3 | Test 3
- 2 | Test 2
- 1 | Test 1
-(6 rows)
-
-explain (verbose, costs off) select min(1-id) from matest0;
- QUERY PLAN
-------------------------------------------------------------------------------
- Aggregate
- Output: min((min((1 - id))))
- -> Remote Subquery Scan on all (datanode_1,datanode_2)
- Output: min((1 - id))
- -> Aggregate
- Output: min((1 - matest0.id))
- -> Append
- -> Index Only Scan using matest0_pkey on public.matest0
- Output: matest0.id
- -> Bitmap Heap Scan on public.matest1
- Output: matest1.id
- -> Bitmap Index Scan on matest1_pkey
- -> Bitmap Heap Scan on public.matest2
- Output: matest2.id
- -> Bitmap Index Scan on matest2_pkey
- -> Bitmap Heap Scan on public.matest3
- Output: matest3.id
- -> Bitmap Index Scan on matest3_pkey
-(18 rows)
-
-select min(1-id) from matest0;
- min
------
- -5
-(1 row)
-
-reset enable_seqscan;
-drop table matest0 cascade;
-NOTICE: drop cascades to 3 other objects
-DETAIL: drop cascades to table matest1
-drop cascades to table matest2
-drop cascades to table matest3
---
--- Check that use of an index with an extraneous column doesn't produce
--- a plan with extraneous sorting
---
-create table matest0 (a int, b int, c int, d int);
-create table matest1 () inherits(matest0);
-create index matest0i on matest0 (b, c);
-create index matest1i on matest1 (b, c);
-set enable_nestloop = off; -- we want a plan with two MergeAppends
-explain (costs off)
-select t1.* from matest0 t1, matest0 t2
-where t1.b = t2.b and t2.c = t2.d
-order by t1.b limit 10;
- QUERY PLAN
------------------------------------------------------------------------------------------
- Limit
- -> Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Limit
- -> Sort
- Sort Key: b
- -> Hash Join
- Hash Cond: (b = b)
- -> Remote Subquery Scan on all (datanode_1,datanode_2)
- Distribute results by H: b
- -> Append
- -> Seq Scan on matest0 t1
- -> Seq Scan on matest1 t1_1
- -> Hash
- -> Remote Subquery Scan on all (datanode_1,datanode_2)
- Distribute results by H: b
- -> Append
- -> Seq Scan on matest0 t2
- Filter: (c = d)
- -> Seq Scan on matest1 t2_1
- Filter: (c = d)
-(20 rows)
-
-reset enable_nestloop;
-drop table matest0 cascade;
-NOTICE: drop cascades to table matest1
---
--- Test merge-append for UNION ALL append relations
---
-set enable_seqscan = off;
-set enable_indexscan = on;
-set enable_bitmapscan = off;
--- Check handling of duplicated, constant, or volatile targetlist items
-explain (costs off, num_nodes off, nodes off)
-SELECT thousand, tenthous FROM tenk1
-UNION ALL
-SELECT thousand, thousand FROM tenk1
-ORDER BY thousand, tenthous;
- QUERY PLAN
--------------------------------------------------------------------------------
- Merge Append
- Sort Key: tenk1.thousand, tenk1.tenthous
- -> Remote Subquery Scan on all
- -> Index Only Scan using tenk1_thous_tenthous on tenk1
- -> Remote Subquery Scan on all
- -> Sort
- Sort Key: tenk1_1.thousand, tenk1_1.thousand
- -> Index Only Scan using tenk1_thous_tenthous on tenk1 tenk1_1
-(8 rows)
-
-explain (costs off, num_nodes off, nodes off)
-SELECT thousand, tenthous, thousand+tenthous AS x FROM tenk1
-UNION ALL
-SELECT 42, 42, hundred FROM tenk1
-ORDER BY thousand, tenthous;
- QUERY PLAN
-------------------------------------------------------------------------
- Remote Subquery Scan on all
- -> Sort
- Sort Key: tenk1.thousand, tenk1.tenthous
- -> Append
- -> Index Only Scan using tenk1_thous_tenthous on tenk1
- -> Index Only Scan using tenk1_hundred on tenk1 tenk1_1
-(6 rows)
-
-explain (costs off, num_nodes off, nodes off)
-SELECT thousand, tenthous FROM tenk1
-UNION ALL
-SELECT thousand, random()::integer FROM tenk1
-ORDER BY thousand, tenthous;
- QUERY PLAN
--------------------------------------------------------------------------------
- Merge Append
- Sort Key: tenk1.thousand, tenk1.tenthous
- -> Remote Subquery Scan on all
- -> Index Only Scan using tenk1_thous_tenthous on tenk1
- -> Remote Subquery Scan on all
- -> Sort
- Sort Key: tenk1_1.thousand, ((random())::integer)
- -> Index Only Scan using tenk1_thous_tenthous on tenk1 tenk1_1
-(8 rows)
-
--- Check min/max aggregate optimization
-explain (costs off, num_nodes off, nodes off)
-SELECT min(x) FROM
- (SELECT unique1 AS x FROM tenk1 a
- UNION ALL
- SELECT unique2 AS x FROM tenk1 b) s;
- QUERY PLAN
---------------------------------------------------------------------------
- Result
- InitPlan 1 (returns $0)
- -> Limit
- -> Merge Append
- Sort Key: a.unique1
- -> Remote Subquery Scan on all
- -> Index Only Scan using tenk1_unique1 on tenk1 a
- Index Cond: (unique1 IS NOT NULL)
- -> Remote Subquery Scan on all
- -> Index Only Scan using tenk1_unique2 on tenk1 b
- Index Cond: (unique2 IS NOT NULL)
-(11 rows)
-
-explain (costs off, num_nodes off, nodes off)
-SELECT min(y) FROM
- (SELECT unique1 AS x, unique1 AS y FROM tenk1 a
- UNION ALL
- SELECT unique2 AS x, unique2 AS y FROM tenk1 b) s;
- QUERY PLAN
---------------------------------------------------------------------------
- Result
- InitPlan 1 (returns $0)
- -> Limit
- -> Merge Append
- Sort Key: a.unique1
- -> Remote Subquery Scan on all
- -> Index Only Scan using tenk1_unique1 on tenk1 a
- Index Cond: (unique1 IS NOT NULL)
- -> Remote Subquery Scan on all
- -> Index Only Scan using tenk1_unique2 on tenk1 b
- Index Cond: (unique2 IS NOT NULL)
-(11 rows)
-
--- XXX planner doesn't recognize that index on unique2 is sufficiently sorted
-explain (costs off, num_nodes off, nodes off)
-SELECT x, y FROM
- (SELECT thousand AS x, tenthous AS y FROM tenk1 a
- UNION ALL
- SELECT unique2 AS x, unique2 AS y FROM tenk1 b) s
-ORDER BY x, y;
- QUERY PLAN
--------------------------------------------------------------------
- Merge Append
- Sort Key: a.thousand, a.tenthous
- -> Remote Subquery Scan on all
- -> Index Only Scan using tenk1_thous_tenthous on tenk1 a
- -> Remote Subquery Scan on all
- -> Sort
- Sort Key: b.unique2, b.unique2
- -> Index Only Scan using tenk1_unique2 on tenk1 b
-(8 rows)
-
--- exercise rescan code path via a repeatedly-evaluated subquery
-explain (costs off)
-SELECT
- ARRAY(SELECT f.i FROM (
- (SELECT d + g.i FROM generate_series(4, 30, 3) d ORDER BY 1)
- UNION ALL
- (SELECT d + g.i FROM generate_series(0, 30, 5) d ORDER BY 1)
- ) f(i)
- ORDER BY f.i LIMIT 10)
-FROM generate_series(1, 3) g(i);
- QUERY PLAN
-----------------------------------------------------------------
- Function Scan on generate_series g
- SubPlan 1
- -> Limit
- -> Merge Append
- Sort Key: ((d.d + g.i))
- -> Sort
- Sort Key: ((d.d + g.i))
- -> Function Scan on generate_series d
- -> Sort
- Sort Key: ((d_1.d + g.i))
- -> Function Scan on generate_series d_1
-(11 rows)
-
-SELECT
- ARRAY(SELECT f.i FROM (
- (SELECT d + g.i FROM generate_series(4, 30, 3) d ORDER BY 1)
- UNION ALL
- (SELECT d + g.i FROM generate_series(0, 30, 5) d ORDER BY 1)
- ) f(i)
- ORDER BY f.i LIMIT 10)
-FROM generate_series(1, 3) g(i);
- array
-------------------------------
- {1,5,6,8,11,11,14,16,17,20}
- {2,6,7,9,12,12,15,17,18,21}
- {3,7,8,10,13,13,16,18,19,22}
-(3 rows)
-
-reset enable_seqscan;
-reset enable_indexscan;
-reset enable_bitmapscan;
+++ /dev/null
---
--- INT4
---
-CREATE TABLE INT4_TBL(f1 int4);
-INSERT INTO INT4_TBL(f1) VALUES (' 0 ');
-INSERT INTO INT4_TBL(f1) VALUES ('123456 ');
-INSERT INTO INT4_TBL(f1) VALUES (' -123456');
-INSERT INTO INT4_TBL(f1) VALUES ('34.5');
-ERROR: invalid input syntax for integer: "34.5"
-LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('34.5');
- ^
--- largest and smallest values
-INSERT INTO INT4_TBL(f1) VALUES ('2147483647');
-INSERT INTO INT4_TBL(f1) VALUES ('-2147483647');
--- bad input values -- should give errors
-INSERT INTO INT4_TBL(f1) VALUES ('1000000000000');
-ERROR: value "1000000000000" is out of range for type integer
-LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('1000000000000');
- ^
-INSERT INTO INT4_TBL(f1) VALUES ('asdf');
-ERROR: invalid input syntax for integer: "asdf"
-LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('asdf');
- ^
-INSERT INTO INT4_TBL(f1) VALUES (' ');
-ERROR: invalid input syntax for integer: " "
-LINE 1: INSERT INTO INT4_TBL(f1) VALUES (' ');
- ^
-INSERT INTO INT4_TBL(f1) VALUES (' asdf ');
-ERROR: invalid input syntax for integer: " asdf "
-LINE 1: INSERT INTO INT4_TBL(f1) VALUES (' asdf ');
- ^
-INSERT INTO INT4_TBL(f1) VALUES ('- 1234');
-ERROR: invalid input syntax for integer: "- 1234"
-LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('- 1234');
- ^
-INSERT INTO INT4_TBL(f1) VALUES ('123 5');
-ERROR: invalid input syntax for integer: "123 5"
-LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('123 5');
- ^
-INSERT INTO INT4_TBL(f1) VALUES ('');
-ERROR: invalid input syntax for integer: ""
-LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('');
- ^
-SELECT '' AS five, * FROM INT4_TBL ORDER BY f1;
- five | f1
-------+-------------
- | -2147483647
- | -123456
- | 0
- | 123456
- | 2147483647
-(5 rows)
-
-SELECT '' AS four, i.* FROM INT4_TBL i WHERE i.f1 <> int2 '0' ORDER BY f1;
- four | f1
-------+-------------
- | -2147483647
- | -123456
- | 123456
- | 2147483647
-(4 rows)
-
-SELECT '' AS four, i.* FROM INT4_TBL i WHERE i.f1 <> int4 '0' ORDER BY f1;
- four | f1
-------+-------------
- | -2147483647
- | -123456
- | 123456
- | 2147483647
-(4 rows)
-
-SELECT '' AS one, i.* FROM INT4_TBL i WHERE i.f1 = int2 '0';
- one | f1
------+----
- | 0
-(1 row)
-
-SELECT '' AS one, i.* FROM INT4_TBL i WHERE i.f1 = int4 '0';
- one | f1
------+----
- | 0
-(1 row)
-
-SELECT '' AS two, i.* FROM INT4_TBL i WHERE i.f1 < int2 '0' ORDER BY f1;
- two | f1
------+-------------
- | -2147483647
- | -123456
-(2 rows)
-
-SELECT '' AS two, i.* FROM INT4_TBL i WHERE i.f1 < int4 '0' ORDER BY f1;
- two | f1
------+-------------
- | -2147483647
- | -123456
-(2 rows)
-
-SELECT '' AS three, i.* FROM INT4_TBL i WHERE i.f1 <= int2 '0' ORDER BY f1;
- three | f1
--------+-------------
- | -2147483647
- | -123456
- | 0
-(3 rows)
-
-SELECT '' AS three, i.* FROM INT4_TBL i WHERE i.f1 <= int4 '0' ORDER BY f1;
- three | f1
--------+-------------
- | -2147483647
- | -123456
- | 0
-(3 rows)
-
-SELECT '' AS two, i.* FROM INT4_TBL i WHERE i.f1 > int2 '0' ORDER BY f1;
- two | f1
------+------------
- | 123456
- | 2147483647
-(2 rows)
-
-SELECT '' AS two, i.* FROM INT4_TBL i WHERE i.f1 > int4 '0' ORDER BY f1;
- two | f1
------+------------
- | 123456
- | 2147483647
-(2 rows)
-
-SELECT '' AS three, i.* FROM INT4_TBL i WHERE i.f1 >= int2 '0' ORDER BY f1;
- three | f1
--------+------------
- | 0
- | 123456
- | 2147483647
-(3 rows)
-
-SELECT '' AS three, i.* FROM INT4_TBL i WHERE i.f1 >= int4 '0' ORDER BY f1;
- three | f1
--------+------------
- | 0
- | 123456
- | 2147483647
-(3 rows)
-
--- positive odds
-SELECT '' AS one, i.* FROM INT4_TBL i WHERE (i.f1 % int2 '2') = int2 '1' ORDER BY f1;
- one | f1
------+------------
- | 2147483647
-(1 row)
-
--- any evens
-SELECT '' AS three, i.* FROM INT4_TBL i WHERE (i.f1 % int4 '2') = int2 '0' ORDER BY f1;
- three | f1
--------+---------
- | -123456
- | 0
- | 123456
-(3 rows)
-
-SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i ORDER BY f1;
-ERROR: integer out of range
-SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i
-WHERE abs(f1) < 1073741824 ORDER BY f1;
- five | f1 | x
-------+---------+---------
- | -123456 | -246912
- | 0 | 0
- | 123456 | 246912
-(3 rows)
-
-SELECT '' AS five, i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i ORDER BY f1;
-ERROR: integer out of range
-SELECT '' AS five, i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i
-WHERE abs(f1) < 1073741824 ORDER BY f1;
- five | f1 | x
-------+---------+---------
- | -123456 | -246912
- | 0 | 0
- | 123456 | 246912
-(3 rows)
-
-SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i ORDER BY f1;
-ERROR: integer out of range
-SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i
-WHERE f1 < 2147483646 ORDER BY f1;
- five | f1 | x
-------+-------------+-------------
- | -2147483647 | -2147483645
- | -123456 | -123454
- | 0 | 2
- | 123456 | 123458
-(4 rows)
-
-SELECT '' AS five, i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i ORDER BY f1;
-ERROR: integer out of range
-SELECT '' AS five, i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i
-WHERE f1 < 2147483646 ORDER BY f1;
- five | f1 | x
-------+-------------+-------------
- | -2147483647 | -2147483645
- | -123456 | -123454
- | 0 | 2
- | 123456 | 123458
-(4 rows)
-
-SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i ORDER BY f1;
-ERROR: integer out of range
-SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i
-WHERE f1 > -2147483647 ORDER BY f1;
- five | f1 | x
-------+------------+------------
- | -123456 | -123458
- | 0 | -2
- | 123456 | 123454
- | 2147483647 | 2147483645
-(4 rows)
-
-SELECT '' AS five, i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i ORDER BY f1;
-ERROR: integer out of range
-SELECT '' AS five, i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i
-WHERE f1 > -2147483647 ORDER BY f1;
- five | f1 | x
-------+------------+------------
- | -123456 | -123458
- | 0 | -2
- | 123456 | 123454
- | 2147483647 | 2147483645
-(4 rows)
-
-SELECT '' AS five, i.f1, i.f1 / int2 '2' AS x FROM INT4_TBL i ORDER BY f1;
- five | f1 | x
-------+-------------+-------------
- | -2147483647 | -1073741823
- | -123456 | -61728
- | 0 | 0
- | 123456 | 61728
- | 2147483647 | 1073741823
-(5 rows)
-
-SELECT '' AS five, i.f1, i.f1 / int4 '2' AS x FROM INT4_TBL i ORDER BY f1;
- five | f1 | x
-------+-------------+-------------
- | -2147483647 | -1073741823
- | -123456 | -61728
- | 0 | 0
- | 123456 | 61728
- | 2147483647 | 1073741823
-(5 rows)
-
---
--- more complex expressions
---
--- variations on unary minus parsing
-SELECT -2+3 AS one;
- one
------
- 1
-(1 row)
-
-SELECT 4-2 AS two;
- two
------
- 2
-(1 row)
-
-SELECT 2- -1 AS three;
- three
--------
- 3
-(1 row)
-
-SELECT 2 - -2 AS four;
- four
-------
- 4
-(1 row)
-
-SELECT int2 '2' * int2 '2' = int2 '16' / int2 '4' AS true;
- true
-------
- t
-(1 row)
-
-SELECT int4 '2' * int2 '2' = int2 '16' / int4 '4' AS true;
- true
-------
- t
-(1 row)
-
-SELECT int2 '2' * int4 '2' = int4 '16' / int2 '4' AS true;
- true
-------
- t
-(1 row)
-
-SELECT int4 '1000' < int4 '999' AS false;
- false
--------
- f
-(1 row)
-
-SELECT 4! AS twenty_four;
- twenty_four
--------------
- 24
-(1 row)
-
-SELECT !!3 AS six;
- six
------
- 6
-(1 row)
-
-SELECT 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 AS ten;
- ten
------
- 10
-(1 row)
-
-SELECT 2 + 2 / 2 AS three;
- three
--------
- 3
-(1 row)
-
-SELECT (2 + 2) / 2 AS two;
- two
------
- 2
-(1 row)
-
--- corner case
-SELECT (-1::int4<<31)::text;
- text
--------------
- -2147483648
-(1 row)
-
-SELECT ((-1::int4<<31)+1)::text;
- text
--------------
- -2147483647
-(1 row)
-
+++ /dev/null
---
--- Regression tests for schemas (namespaces)
---
-CREATE SCHEMA test_schema_1
- CREATE UNIQUE INDEX abc_a_idx ON abc (a)
- CREATE VIEW abc_view AS
- SELECT a+1 AS a, b+1 AS b FROM abc
- CREATE TABLE abc (
- a serial,
- b int UNIQUE
- );
-NOTICE: CREATE TABLE will create implicit sequence "abc_a_seq" for serial column "abc.a"
-NOTICE: CREATE TABLE / UNIQUE will create implicit index "abc_b_key" for table "abc"
-ERROR: Unique index of partitioned table must contain the hash/modulo distribution column.
--- verify that the objects were created
-SELECT COUNT(*) FROM pg_class WHERE relnamespace =
- (SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
- count
--------
- 0
-(1 row)
-
-INSERT INTO test_schema_1.abc DEFAULT VALUES;
-ERROR: schema "test_schema_1" does not exist
-LINE 1: INSERT INTO test_schema_1.abc DEFAULT VALUES;
- ^
-INSERT INTO test_schema_1.abc DEFAULT VALUES;
-ERROR: schema "test_schema_1" does not exist
-LINE 1: INSERT INTO test_schema_1.abc DEFAULT VALUES;
- ^
-INSERT INTO test_schema_1.abc DEFAULT VALUES;
-ERROR: schema "test_schema_1" does not exist
-LINE 1: INSERT INTO test_schema_1.abc DEFAULT VALUES;
- ^
-SELECT * FROM test_schema_1.abc ORDER BY a;
-ERROR: schema "test_schema_1" does not exist
-LINE 1: SELECT * FROM test_schema_1.abc ORDER BY a;
- ^
-SELECT * FROM test_schema_1.abc_view ORDER BY a;
-ERROR: schema "test_schema_1" does not exist
-LINE 1: SELECT * FROM test_schema_1.abc_view ORDER BY a;
- ^
-DROP SCHEMA test_schema_1 CASCADE;
-ERROR: schema "test_schema_1" does not exist
--- verify that the objects were dropped
-SELECT COUNT(*) FROM pg_class WHERE relnamespace =
- (SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
- count
--------
- 0
-(1 row)
-
+++ /dev/null
--- Currently this tests polymorphic aggregates and indirectly does some
--- testing of polymorphic SQL functions. It ought to be extended.
--- Tests for other features related to function-calling have snuck in, too.
--- Legend:
------------
--- A = type is ANY
--- P = type is polymorphic
--- N = type is non-polymorphic
--- B = aggregate base type
--- S = aggregate state type
--- R = aggregate return type
--- 1 = arg1 of a function
--- 2 = arg2 of a function
--- ag = aggregate
--- tf = trans (state) function
--- ff = final function
--- rt = return type of a function
--- -> = implies
--- => = allowed
--- !> = not allowed
--- E = exists
--- NE = not-exists
---
--- Possible states:
--- ----------------
--- B = (A || P || N)
--- when (B = A) -> (tf2 = NE)
--- S = (P || N)
--- ff = (E || NE)
--- tf1 = (P || N)
--- tf2 = (NE || P || N)
--- R = (P || N)
--- create functions for use as tf and ff with the needed combinations of
--- argument polymorphism, but within the constraints of valid aggregate
--- functions, i.e. tf arg1 and tf return type must match
--- polymorphic single arg transfn
-CREATE FUNCTION stfp(anyarray) RETURNS anyarray AS
-'select $1' LANGUAGE SQL;
--- non-polymorphic single arg transfn
-CREATE FUNCTION stfnp(int[]) RETURNS int[] AS
-'select $1' LANGUAGE SQL;
--- dual polymorphic transfn
-CREATE FUNCTION tfp(anyarray,anyelement) RETURNS anyarray AS
-'select $1 || $2' LANGUAGE SQL;
--- dual non-polymorphic transfn
-CREATE FUNCTION tfnp(int[],int) RETURNS int[] AS
-'select $1 || $2' LANGUAGE SQL;
--- arg1 only polymorphic transfn
-CREATE FUNCTION tf1p(anyarray,int) RETURNS anyarray AS
-'select $1' LANGUAGE SQL;
--- arg2 only polymorphic transfn
-CREATE FUNCTION tf2p(int[],anyelement) RETURNS int[] AS
-'select $1' LANGUAGE SQL;
--- multi-arg polymorphic
-CREATE FUNCTION sum3(anyelement,anyelement,anyelement) returns anyelement AS
-'select $1+$2+$3' language sql strict;
--- finalfn polymorphic
-CREATE FUNCTION ffp(anyarray) RETURNS anyarray AS
-'select $1' LANGUAGE SQL;
--- finalfn non-polymorphic
-CREATE FUNCTION ffnp(int[]) returns int[] as
-'select $1' LANGUAGE SQL;
--- Try to cover all the possible states:
---
--- Note: in Cases 1 & 2, we are trying to return P. Therefore, if the transfn
--- is stfnp, tfnp, or tf2p, we must use ffp as finalfn, because stfnp, tfnp,
--- and tf2p do not return P. Conversely, in Cases 3 & 4, we are trying to
--- return N. Therefore, if the transfn is stfp, tfp, or tf1p, we must use ffnp
--- as finalfn, because stfp, tfp, and tf1p do not return N.
---
--- Case1 (R = P) && (B = A)
--- ------------------------
--- S tf1
--- -------
--- N N
--- should CREATE
-CREATE AGGREGATE myaggp01a(*) (SFUNC = stfnp, STYPE = int4[],
- FINALFUNC = ffp, INITCOND = '{}');
--- P N
--- should ERROR: stfnp(anyarray) not matched by stfnp(int[])
-CREATE AGGREGATE myaggp02a(*) (SFUNC = stfnp, STYPE = anyarray,
- FINALFUNC = ffp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- N P
--- should CREATE
-CREATE AGGREGATE myaggp03a(*) (SFUNC = stfp, STYPE = int4[],
- FINALFUNC = ffp, INITCOND = '{}');
-CREATE AGGREGATE myaggp03b(*) (SFUNC = stfp, STYPE = int4[],
- INITCOND = '{}');
--- P P
--- should ERROR: we have no way to resolve S
-CREATE AGGREGATE myaggp04a(*) (SFUNC = stfp, STYPE = anyarray,
- FINALFUNC = ffp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
-CREATE AGGREGATE myaggp04b(*) (SFUNC = stfp, STYPE = anyarray,
- INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- Case2 (R = P) && ((B = P) || (B = N))
--- -------------------------------------
--- S tf1 B tf2
--- -----------------------
--- N N N N
--- should CREATE
-CREATE AGGREGATE myaggp05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[],
- FINALFUNC = ffp, INITCOND = '{}');
--- N N N P
--- should CREATE
-CREATE AGGREGATE myaggp06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[],
- FINALFUNC = ffp, INITCOND = '{}');
--- N N P N
--- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int)
-CREATE AGGREGATE myaggp07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[],
- FINALFUNC = ffp, INITCOND = '{}');
-ERROR: function tfnp(integer[], anyelement) does not exist
--- N N P P
--- should CREATE
-CREATE AGGREGATE myaggp08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[],
- FINALFUNC = ffp, INITCOND = '{}');
--- N P N N
--- should CREATE
-CREATE AGGREGATE myaggp09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[],
- FINALFUNC = ffp, INITCOND = '{}');
-CREATE AGGREGATE myaggp09b(BASETYPE = int, SFUNC = tf1p, STYPE = int[],
- INITCOND = '{}');
--- N P N P
--- should CREATE
-CREATE AGGREGATE myaggp10a(BASETYPE = int, SFUNC = tfp, STYPE = int[],
- FINALFUNC = ffp, INITCOND = '{}');
-CREATE AGGREGATE myaggp10b(BASETYPE = int, SFUNC = tfp, STYPE = int[],
- INITCOND = '{}');
--- N P P N
--- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int)
-CREATE AGGREGATE myaggp11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[],
- FINALFUNC = ffp, INITCOND = '{}');
-ERROR: function tf1p(integer[], anyelement) does not exist
-CREATE AGGREGATE myaggp11b(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[],
- INITCOND = '{}');
-ERROR: function tf1p(integer[], anyelement) does not exist
--- N P P P
--- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement)
-CREATE AGGREGATE myaggp12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[],
- FINALFUNC = ffp, INITCOND = '{}');
-ERROR: function tfp(integer[], anyelement) does not exist
-CREATE AGGREGATE myaggp12b(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[],
- INITCOND = '{}');
-ERROR: function tfp(integer[], anyelement) does not exist
--- P N N N
--- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int)
-CREATE AGGREGATE myaggp13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
- FINALFUNC = ffp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- P N N P
--- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement)
-CREATE AGGREGATE myaggp14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
- FINALFUNC = ffp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- P N P N
--- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int)
-CREATE AGGREGATE myaggp15a(BASETYPE = anyelement, SFUNC = tfnp,
- STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
-ERROR: function tfnp(anyarray, anyelement) does not exist
--- P N P P
--- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement)
-CREATE AGGREGATE myaggp16a(BASETYPE = anyelement, SFUNC = tf2p,
- STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
-ERROR: function tf2p(anyarray, anyelement) does not exist
--- P P N N
--- should ERROR: we have no way to resolve S
-CREATE AGGREGATE myaggp17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
- FINALFUNC = ffp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
-CREATE AGGREGATE myaggp17b(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
- INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- P P N P
--- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement)
-CREATE AGGREGATE myaggp18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
- FINALFUNC = ffp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
-CREATE AGGREGATE myaggp18b(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
- INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- P P P N
--- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int)
-CREATE AGGREGATE myaggp19a(BASETYPE = anyelement, SFUNC = tf1p,
- STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
-ERROR: function tf1p(anyarray, anyelement) does not exist
-CREATE AGGREGATE myaggp19b(BASETYPE = anyelement, SFUNC = tf1p,
- STYPE = anyarray, INITCOND = '{}');
-ERROR: function tf1p(anyarray, anyelement) does not exist
--- P P P P
--- should CREATE
-CREATE AGGREGATE myaggp20a(BASETYPE = anyelement, SFUNC = tfp,
- STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}');
-CREATE AGGREGATE myaggp20b(BASETYPE = anyelement, SFUNC = tfp,
- STYPE = anyarray, INITCOND = '{}');
--- Case3 (R = N) && (B = A)
--- ------------------------
--- S tf1
--- -------
--- N N
--- should CREATE
-CREATE AGGREGATE myaggn01a(*) (SFUNC = stfnp, STYPE = int4[],
- FINALFUNC = ffnp, INITCOND = '{}');
-CREATE AGGREGATE myaggn01b(*) (SFUNC = stfnp, STYPE = int4[],
- INITCOND = '{}');
--- P N
--- should ERROR: stfnp(anyarray) not matched by stfnp(int[])
-CREATE AGGREGATE myaggn02a(*) (SFUNC = stfnp, STYPE = anyarray,
- FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
-CREATE AGGREGATE myaggn02b(*) (SFUNC = stfnp, STYPE = anyarray,
- INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- N P
--- should CREATE
-CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[],
- FINALFUNC = ffnp, INITCOND = '{}');
--- P P
--- should ERROR: ffnp(anyarray) not matched by ffnp(int[])
-CREATE AGGREGATE myaggn04a(*) (SFUNC = stfp, STYPE = anyarray,
- FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- Case4 (R = N) && ((B = P) || (B = N))
--- -------------------------------------
--- S tf1 B tf2
--- -----------------------
--- N N N N
--- should CREATE
-CREATE AGGREGATE myaggn05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[],
- FINALFUNC = ffnp, INITCOND = '{}');
-CREATE AGGREGATE myaggn05b(BASETYPE = int, SFUNC = tfnp, STYPE = int[],
- INITCOND = '{}');
--- N N N P
--- should CREATE
-CREATE AGGREGATE myaggn06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[],
- FINALFUNC = ffnp, INITCOND = '{}');
-CREATE AGGREGATE myaggn06b(BASETYPE = int, SFUNC = tf2p, STYPE = int[],
- INITCOND = '{}');
--- N N P N
--- should ERROR: tfnp(int[], anyelement) not matched by tfnp(int[], int)
-CREATE AGGREGATE myaggn07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[],
- FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: function tfnp(integer[], anyelement) does not exist
-CREATE AGGREGATE myaggn07b(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[],
- INITCOND = '{}');
-ERROR: function tfnp(integer[], anyelement) does not exist
--- N N P P
--- should CREATE
-CREATE AGGREGATE myaggn08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[],
- FINALFUNC = ffnp, INITCOND = '{}');
-CREATE AGGREGATE myaggn08b(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[],
- INITCOND = '{}');
--- N P N N
--- should CREATE
-CREATE AGGREGATE myaggn09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[],
- FINALFUNC = ffnp, INITCOND = '{}');
--- N P N P
--- should CREATE
-CREATE AGGREGATE myaggn10a(BASETYPE = int, SFUNC = tfp, STYPE = int[],
- FINALFUNC = ffnp, INITCOND = '{}');
--- N P P N
--- should ERROR: tf1p(int[],anyelement) not matched by tf1p(anyarray,int)
-CREATE AGGREGATE myaggn11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[],
- FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: function tf1p(integer[], anyelement) does not exist
--- N P P P
--- should ERROR: tfp(int[],anyelement) not matched by tfp(anyarray,anyelement)
-CREATE AGGREGATE myaggn12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[],
- FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: function tfp(integer[], anyelement) does not exist
--- P N N N
--- should ERROR: tfnp(anyarray, int) not matched by tfnp(int[],int)
-CREATE AGGREGATE myaggn13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
- FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
-CREATE AGGREGATE myaggn13b(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
- INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- P N N P
--- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement)
-CREATE AGGREGATE myaggn14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
- FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
-CREATE AGGREGATE myaggn14b(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
- INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- P N P N
--- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int)
-CREATE AGGREGATE myaggn15a(BASETYPE = anyelement, SFUNC = tfnp,
- STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: function tfnp(anyarray, anyelement) does not exist
-CREATE AGGREGATE myaggn15b(BASETYPE = anyelement, SFUNC = tfnp,
- STYPE = anyarray, INITCOND = '{}');
-ERROR: function tfnp(anyarray, anyelement) does not exist
--- P N P P
--- should ERROR: tf2p(anyarray, anyelement) not matched by tf2p(int[],anyelement)
-CREATE AGGREGATE myaggn16a(BASETYPE = anyelement, SFUNC = tf2p,
- STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: function tf2p(anyarray, anyelement) does not exist
-CREATE AGGREGATE myaggn16b(BASETYPE = anyelement, SFUNC = tf2p,
- STYPE = anyarray, INITCOND = '{}');
-ERROR: function tf2p(anyarray, anyelement) does not exist
--- P P N N
--- should ERROR: ffnp(anyarray) not matched by ffnp(int[])
-CREATE AGGREGATE myaggn17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
- FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- P P N P
--- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement)
-CREATE AGGREGATE myaggn18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
- FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: cannot determine transition data type
-DETAIL: An aggregate using a polymorphic transition type must have at least one polymorphic argument.
--- P P P N
--- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int)
-CREATE AGGREGATE myaggn19a(BASETYPE = anyelement, SFUNC = tf1p,
- STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: function tf1p(anyarray, anyelement) does not exist
--- P P P P
--- should ERROR: ffnp(anyarray) not matched by ffnp(int[])
-CREATE AGGREGATE myaggn20a(BASETYPE = anyelement, SFUNC = tfp,
- STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}');
-ERROR: function ffnp(anyarray) does not exist
--- multi-arg polymorphic
-CREATE AGGREGATE mysum2(anyelement,anyelement) (SFUNC = sum3,
- STYPE = anyelement, INITCOND = '0');
--- create test data for polymorphic aggregates
-create temp table t(f1 int, f2 int[], f3 text);
-insert into t values(1,array[1],'a');
-insert into t values(1,array[11],'b');
-insert into t values(1,array[111],'c');
-insert into t values(2,array[2],'a');
-insert into t values(2,array[22],'b');
-insert into t values(2,array[222],'c');
-insert into t values(3,array[3],'a');
-insert into t values(3,array[3],'b');
--- test the successfully created polymorphic aggregates
-select f3, myaggp01a(*) from t group by f3 order by f3;
- f3 | myaggp01a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggp03a(*) from t group by f3 order by f3;
- f3 | myaggp03a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggp03b(*) from t group by f3 order by f3;
- f3 | myaggp03b
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggp05a(f1 order by f1) from t group by f3 order by f3;
- f3 | myaggp05a
-----+-----------
- a | {1,2,3}
- b | {1,2,3}
- c | {1,2}
-(3 rows)
-
-select f3, myaggp06a(f1) from t group by f3 order by f3;
- f3 | myaggp06a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggp08a(f1) from t group by f3 order by f3;
- f3 | myaggp08a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggp09a(f1) from t group by f3 order by f3;
- f3 | myaggp09a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggp09b(f1) from t group by f3 order by f3;
- f3 | myaggp09b
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggp10a(f1 order by f1) from t group by f3 order by f3;
- f3 | myaggp10a
-----+-----------
- a | {1,2,3}
- b | {1,2,3}
- c | {1,2}
-(3 rows)
-
-select f3, myaggp10b(f1 order by f1) from t group by f3 order by f3;
- f3 | myaggp10b
-----+-----------
- a | {1,2,3}
- b | {1,2,3}
- c | {1,2}
-(3 rows)
-
-select f3, myaggp20a(f1 order by f1) from t group by f3 order by f3;
- f3 | myaggp20a
-----+-----------
- a | {1,2,3}
- b | {1,2,3}
- c | {1,2}
-(3 rows)
-
-select f3, myaggp20b(f1 order by f1) from t group by f3 order by f3;
- f3 | myaggp20b
-----+-----------
- a | {1,2,3}
- b | {1,2,3}
- c | {1,2}
-(3 rows)
-
-select f3, myaggn01a(*) from t group by f3 order by f3;
- f3 | myaggn01a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggn01b(*) from t group by f3 order by f3;
- f3 | myaggn01b
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggn03a(*) from t group by f3 order by f3;
- f3 | myaggn03a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggn05a(f1 order by f1) from t group by f3 order by f3;
- f3 | myaggn05a
-----+-----------
- a | {1,2,3}
- b | {1,2,3}
- c | {1,2}
-(3 rows)
-
-select f3, myaggn05b(f1 order by f1) from t group by f3 order by f3;
- f3 | myaggn05b
-----+-----------
- a | {1,2,3}
- b | {1,2,3}
- c | {1,2}
-(3 rows)
-
-select f3, myaggn06a(f1) from t group by f3 order by f3;
- f3 | myaggn06a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggn06b(f1) from t group by f3 order by f3;
- f3 | myaggn06b
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggn08a(f1) from t group by f3 order by f3;
- f3 | myaggn08a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggn08b(f1) from t group by f3 order by f3;
- f3 | myaggn08b
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggn09a(f1) from t group by f3 order by f3;
- f3 | myaggn09a
-----+-----------
- a | {}
- b | {}
- c | {}
-(3 rows)
-
-select f3, myaggn10a(f1 order by f1) from t group by f3 order by f3;
- f3 | myaggn10a
-----+-----------
- a | {1,2,3}
- b | {1,2,3}
- c | {1,2}
-(3 rows)
-
-select mysum2(f1, f1 + 1) from t;
- mysum2
---------
- 38
-(1 row)
-
--- test inlining of polymorphic SQL functions
-create function bleat(int) returns int as $$
-begin
- raise notice 'bleat %', $1;
- return $1;
-end$$ language plpgsql;
-create function sql_if(bool, anyelement, anyelement) returns anyelement as $$
-select case when $1 then $2 else $3 end $$ language sql;
--- Note this would fail with integer overflow, never mind wrong bleat() output,
--- if the CASE expression were not successfully inlined
-select f1, sql_if(f1 > 0, bleat(f1), bleat(f1 + 1)) from (select * from int4_tbl order by f1) q order by 1, 2;
- f1 | sql_if
--------------+-------------
- -2147483647 | -2147483646
- -123456 | -123455
- 0 | 1
- 123456 | 123456
- 2147483647 | 2147483647
-(5 rows)
-
-select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl order by 1, 2;
- q2 | sql_if
--------------------+-------------------
- -4567890123456789 | -4567890123456788
- 123 | 123
- 456 | 456
- 4567890123456789 | 4567890123456789
- 4567890123456789 | 4567890123456789
-(5 rows)
-
--- another sort of polymorphic aggregate
-CREATE AGGREGATE array_cat_accum (anyarray)
-(
- sfunc = array_cat,
- stype = anyarray,
- initcond = '{}'
-);
-SELECT array_cat_accum(i)
-FROM (VALUES (ARRAY[1,2]), (ARRAY[3,4])) as t(i);
- array_cat_accum
------------------
- {1,2,3,4}
-(1 row)
-
-SELECT array_cat_accum(i)
-FROM (VALUES (ARRAY[row(1,2),row(3,4)]), (ARRAY[row(5,6),row(7,8)])) as t(i);
- array_cat_accum
------------------------------------
- {"(1,2)","(3,4)","(5,6)","(7,8)"}
-(1 row)
-
--- another kind of polymorphic aggregate
-create function add_group(grp anyarray, ad anyelement, size integer)
- returns anyarray
- as $$
-begin
- if grp is null then
- return array[ad];
- end if;
- if array_upper(grp, 1) < size then
- return grp || ad;
- end if;
- return grp;
-end;
-$$
- language plpgsql immutable;
-create aggregate build_group(anyelement, integer) (
- SFUNC = add_group,
- STYPE = anyarray
-);
-select build_group(q1,3 order by q1) from int8_tbl;
- build_group
-----------------------------
- {123,123,4567890123456789}
-(1 row)
-
--- this should fail because stype isn't compatible with arg
-create aggregate build_group(int8, integer) (
- SFUNC = add_group,
- STYPE = int2[]
-);
-ERROR: function add_group(smallint[], bigint, integer) does not exist
--- but we can make a non-poly agg from a poly sfunc if types are OK
-create aggregate build_group(int8, integer) (
- SFUNC = add_group,
- STYPE = int8[]
-);
--- check that we can apply functions taking ANYARRAY to pg_stats
-select distinct array_ndims(histogram_bounds) from pg_stats
-where histogram_bounds is not null;
- array_ndims
--------------
- 1
-(1 row)
-
--- such functions must protect themselves if varying element type isn't OK
--- (WHERE clause here is to avoid possibly getting a collation error instead)
-select max(histogram_bounds) from pg_stats where tablename = 'pg_am';
-ERROR: cannot compare arrays of different element types
--- test variadic polymorphic functions
-create function myleast(variadic anyarray) returns anyelement as $$
- select min($1[i]) from generate_subscripts($1,1) g(i)
-$$ language sql immutable strict;
-select myleast(10, 1, 20, 33);
- myleast
----------
- 1
-(1 row)
-
-select myleast(1.1, 0.22, 0.55);
- myleast
----------
- 0.22
-(1 row)
-
-select myleast('z'::text);
- myleast
----------
- z
-(1 row)
-
-select myleast(); -- fail
-ERROR: function myleast() does not exist
-LINE 1: select myleast();
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
--- test with variadic call parameter
-select myleast(variadic array[1,2,3,4,-1]);
- myleast
----------
- -1
-(1 row)
-
-select myleast(variadic array[1.1, -5.5]);
- myleast
----------
- -5.5
-(1 row)
-
---test with empty variadic call parameter
-select myleast(variadic array[]::int[]);
- myleast
----------
-
-(1 row)
-
--- an example with some ordinary arguments too
-create function concat(text, variadic anyarray) returns text as $$
- select array_to_string($2, $1);
-$$ language sql immutable strict;
-select concat('%', 1, 2, 3, 4, 5);
- concat
------------
- 1%2%3%4%5
-(1 row)
-
-select concat('|', 'a'::text, 'b', 'c');
- concat
---------
- a|b|c
-(1 row)
-
-select concat('|', variadic array[1,2,33]);
- concat
---------
- 1|2|33
-(1 row)
-
-select concat('|', variadic array[]::int[]);
- concat
---------
-
-(1 row)
-
-drop function concat(text, anyarray);
--- mix variadic with anyelement
-create function formarray(anyelement, variadic anyarray) returns anyarray as $$
- select array_prepend($1, $2);
-$$ language sql immutable strict;
-select formarray(1,2,3,4,5);
- formarray
--------------
- {1,2,3,4,5}
-(1 row)
-
-select formarray(1.1, variadic array[1.2,55.5]);
- formarray
-----------------
- {1.1,1.2,55.5}
-(1 row)
-
-select formarray(1.1, array[1.2,55.5]); -- fail without variadic
-ERROR: function formarray(numeric, numeric[]) does not exist
-LINE 1: select formarray(1.1, array[1.2,55.5]);
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-select formarray(1, 'x'::text); -- fail, type mismatch
-ERROR: function formarray(integer, text) does not exist
-LINE 1: select formarray(1, 'x'::text);
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-select formarray(1, variadic array['x'::text]); -- fail, type mismatch
-ERROR: function formarray(integer, text[]) does not exist
-LINE 1: select formarray(1, variadic array['x'::text]);
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-drop function formarray(anyelement, variadic anyarray);
--- test pg_typeof() function
-select pg_typeof(null); -- unknown
- pg_typeof
------------
- unknown
-(1 row)
-
-select pg_typeof(0); -- integer
- pg_typeof
------------
- integer
-(1 row)
-
-select pg_typeof(0.0); -- numeric
- pg_typeof
------------
- numeric
-(1 row)
-
-select pg_typeof(1+1 = 2); -- boolean
- pg_typeof
------------
- boolean
-(1 row)
-
-select pg_typeof('x'); -- unknown
- pg_typeof
------------
- unknown
-(1 row)
-
-select pg_typeof('' || ''); -- text
- pg_typeof
------------
- text
-(1 row)
-
-select pg_typeof(pg_typeof(0)); -- regtype
- pg_typeof
------------
- regtype
-(1 row)
-
-select pg_typeof(array[1.2,55.5]); -- numeric[]
- pg_typeof
------------
- numeric[]
-(1 row)
-
-select pg_typeof(myleast(10, 1, 20, 33)); -- polymorphic input
- pg_typeof
------------
- integer
-(1 row)
-
--- test functions with default parameters
--- test basic functionality
-create function dfunc(a int = 1, int = 2) returns int as $$
- select $1 + $2;
-$$ language sql;
-select dfunc();
- dfunc
--------
- 3
-(1 row)
-
-select dfunc(10);
- dfunc
--------
- 12
-(1 row)
-
-select dfunc(10, 20);
- dfunc
--------
- 30
-(1 row)
-
-select dfunc(10, 20, 30); -- fail
-ERROR: function dfunc(integer, integer, integer) does not exist
-LINE 1: select dfunc(10, 20, 30);
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-drop function dfunc(); -- fail
-ERROR: function dfunc() does not exist
-drop function dfunc(int); -- fail
-ERROR: function dfunc(integer) does not exist
-drop function dfunc(int, int); -- ok
--- fail: defaults must be at end of argument list
-create function dfunc(a int = 1, b int) returns int as $$
- select $1 + $2;
-$$ language sql;
-ERROR: input parameters after one with a default value must also have defaults
--- however, this should work:
-create function dfunc(a int = 1, out sum int, b int = 2) as $$
- select $1 + $2;
-$$ language sql;
-select dfunc();
- dfunc
--------
- 3
-(1 row)
-
--- verify it lists properly
-\df dfunc
- List of functions
- Schema | Name | Result data type | Argument data types | Type
---------+-------+------------------+-----------------------------------------------------------+--------
- public | dfunc | integer | a integer DEFAULT 1, OUT sum integer, b integer DEFAULT 2 | normal
-(1 row)
-
-drop function dfunc(int, int);
--- check implicit coercion
-create function dfunc(a int DEFAULT 1.0, int DEFAULT '-1') returns int as $$
- select $1 + $2;
-$$ language sql;
-select dfunc();
- dfunc
--------
- 0
-(1 row)
-
-create function dfunc(a text DEFAULT 'Hello', b text DEFAULT 'World') returns text as $$
- select $1 || ', ' || $2;
-$$ language sql;
-select dfunc(); -- fail: which dfunc should be called? int or text
-ERROR: function dfunc() is not unique
-LINE 1: select dfunc();
- ^
-HINT: Could not choose a best candidate function. You might need to add explicit type casts.
-select dfunc('Hi'); -- ok
- dfunc
------------
- Hi, World
-(1 row)
-
-select dfunc('Hi', 'City'); -- ok
- dfunc
-----------
- Hi, City
-(1 row)
-
-select dfunc(0); -- ok
- dfunc
--------
- -1
-(1 row)
-
-select dfunc(10, 20); -- ok
- dfunc
--------
- 30
-(1 row)
-
-drop function dfunc(int, int);
-drop function dfunc(text, text);
-create function dfunc(int = 1, int = 2) returns int as $$
- select 2;
-$$ language sql;
-create function dfunc(int = 1, int = 2, int = 3, int = 4) returns int as $$
- select 4;
-$$ language sql;
--- Now, dfunc(nargs = 2) and dfunc(nargs = 4) are ambiguous when called
--- with 0 to 2 arguments.
-select dfunc(); -- fail
-ERROR: function dfunc() is not unique
-LINE 1: select dfunc();
- ^
-HINT: Could not choose a best candidate function. You might need to add explicit type casts.
-select dfunc(1); -- fail
-ERROR: function dfunc(integer) is not unique
-LINE 1: select dfunc(1);
- ^
-HINT: Could not choose a best candidate function. You might need to add explicit type casts.
-select dfunc(1, 2); -- fail
-ERROR: function dfunc(integer, integer) is not unique
-LINE 1: select dfunc(1, 2);
- ^
-HINT: Could not choose a best candidate function. You might need to add explicit type casts.
-select dfunc(1, 2, 3); -- ok
- dfunc
--------
- 4
-(1 row)
-
-select dfunc(1, 2, 3, 4); -- ok
- dfunc
--------
- 4
-(1 row)
-
-drop function dfunc(int, int);
-drop function dfunc(int, int, int, int);
--- default values are not allowed for output parameters
-create function dfunc(out int = 20) returns int as $$
- select 1;
-$$ language sql;
-ERROR: only input parameters can have default values
--- polymorphic parameter test
-create function dfunc(anyelement = 'World'::text) returns text as $$
- select 'Hello, ' || $1::text;
-$$ language sql;
-select dfunc();
- dfunc
---------------
- Hello, World
-(1 row)
-
-select dfunc(0);
- dfunc
-----------
- Hello, 0
-(1 row)
-
-select dfunc(to_date('20081215','YYYYMMDD'));
- dfunc
--------------------
- Hello, 12-15-2008
-(1 row)
-
-select dfunc('City'::text);
- dfunc
--------------
- Hello, City
-(1 row)
-
-drop function dfunc(anyelement);
--- check defaults for variadics
-create function dfunc(a variadic int[]) returns int as
-$$ select array_upper($1, 1) $$ language sql;
-select dfunc(); -- fail
-ERROR: function dfunc() does not exist
-LINE 1: select dfunc();
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-select dfunc(10);
- dfunc
--------
- 1
-(1 row)
-
-select dfunc(10,20);
- dfunc
--------
- 2
-(1 row)
-
-create or replace function dfunc(a variadic int[] default array[]::int[]) returns int as
-$$ select array_upper($1, 1) $$ language sql;
-select dfunc(); -- now ok
- dfunc
--------
-
-(1 row)
-
-select dfunc(10);
- dfunc
--------
- 1
-(1 row)
-
-select dfunc(10,20);
- dfunc
--------
- 2
-(1 row)
-
--- can't remove the default once it exists
-create or replace function dfunc(a variadic int[]) returns int as
-$$ select array_upper($1, 1) $$ language sql;
-ERROR: cannot remove parameter defaults from existing function
-HINT: Use DROP FUNCTION first.
-\df dfunc
- List of functions
- Schema | Name | Result data type | Argument data types | Type
---------+-------+------------------+-------------------------------------------------+--------
- public | dfunc | integer | VARIADIC a integer[] DEFAULT ARRAY[]::integer[] | normal
-(1 row)
-
-drop function dfunc(a variadic int[]);
--- Ambiguity should be reported only if there's not a better match available
-create function dfunc(int = 1, int = 2, int = 3) returns int as $$
- select 3;
-$$ language sql;
-create function dfunc(int = 1, int = 2) returns int as $$
- select 2;
-$$ language sql;
-create function dfunc(text) returns text as $$
- select $1;
-$$ language sql;
--- dfunc(narg=2) and dfunc(narg=3) are ambiguous
-select dfunc(1); -- fail
-ERROR: function dfunc(integer) is not unique
-LINE 1: select dfunc(1);
- ^
-HINT: Could not choose a best candidate function. You might need to add explicit type casts.
--- but this works since the ambiguous functions aren't preferred anyway
-select dfunc('Hi');
- dfunc
--------
- Hi
-(1 row)
-
-drop function dfunc(int, int, int);
-drop function dfunc(int, int);
-drop function dfunc(text);
---
--- Tests for named- and mixed-notation function calling
---
-create function dfunc(a int, b int, c int = 0, d int = 0)
- returns table (a int, b int, c int, d int) as $$
- select $1, $2, $3, $4;
-$$ language sql;
-select (dfunc(10,20,30)).*;
- a | b | c | d
-----+----+----+---
- 10 | 20 | 30 | 0
-(1 row)
-
-select (dfunc(a := 10, b := 20, c := 30)).*;
- a | b | c | d
-----+----+----+---
- 10 | 20 | 30 | 0
-(1 row)
-
-select * from dfunc(a := 10, b := 20);
- a | b | c | d
-----+----+---+---
- 10 | 20 | 0 | 0
-(1 row)
-
-select * from dfunc(b := 10, a := 20);
- a | b | c | d
-----+----+---+---
- 20 | 10 | 0 | 0
-(1 row)
-
-select * from dfunc(0); -- fail
-ERROR: function dfunc(integer) does not exist
-LINE 1: select * from dfunc(0);
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-select * from dfunc(1,2);
- a | b | c | d
----+---+---+---
- 1 | 2 | 0 | 0
-(1 row)
-
-select * from dfunc(1,2,c := 3);
- a | b | c | d
----+---+---+---
- 1 | 2 | 3 | 0
-(1 row)
-
-select * from dfunc(1,2,d := 3);
- a | b | c | d
----+---+---+---
- 1 | 2 | 0 | 3
-(1 row)
-
-select * from dfunc(x := 20, b := 10, x := 30); -- fail, duplicate name
-ERROR: argument name "x" used more than once
-LINE 1: select * from dfunc(x := 20, b := 10, x := 30);
- ^
-select * from dfunc(10, b := 20, 30); -- fail, named args must be last
-ERROR: positional argument cannot follow named argument
-LINE 1: select * from dfunc(10, b := 20, 30);
- ^
-select * from dfunc(x := 10, b := 20, c := 30); -- fail, unknown param
-ERROR: function dfunc(x := integer, b := integer, c := integer) does not exist
-LINE 1: select * from dfunc(x := 10, b := 20, c := 30);
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-select * from dfunc(10, 10, a := 20); -- fail, a overlaps positional parameter
-ERROR: function dfunc(integer, integer, a := integer) does not exist
-LINE 1: select * from dfunc(10, 10, a := 20);
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-select * from dfunc(1,c := 2,d := 3); -- fail, no value for b
-ERROR: function dfunc(integer, c := integer, d := integer) does not exist
-LINE 1: select * from dfunc(1,c := 2,d := 3);
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-drop function dfunc(int, int, int, int);
--- test with different parameter types
-create function dfunc(a varchar, b numeric, c date = current_date)
- returns table (a varchar, b numeric, c date) as $$
- select $1, $2, $3;
-$$ language sql;
-select (dfunc('Hello World', 20, '2009-07-25'::date)).*;
- a | b | c
--------------+----+------------
- Hello World | 20 | 07-25-2009
-(1 row)
-
-select * from dfunc('Hello World', 20, '2009-07-25'::date);
- a | b | c
--------------+----+------------
- Hello World | 20 | 07-25-2009
-(1 row)
-
-select * from dfunc(c := '2009-07-25'::date, a := 'Hello World', b := 20);
- a | b | c
--------------+----+------------
- Hello World | 20 | 07-25-2009
-(1 row)
-
-select * from dfunc('Hello World', b := 20, c := '2009-07-25'::date);
- a | b | c
--------------+----+------------
- Hello World | 20 | 07-25-2009
-(1 row)
-
-select * from dfunc('Hello World', c := '2009-07-25'::date, b := 20);
- a | b | c
--------------+----+------------
- Hello World | 20 | 07-25-2009
-(1 row)
-
-select * from dfunc('Hello World', c := 20, b := '2009-07-25'::date); -- fail
-ERROR: function dfunc(unknown, c := integer, b := date) does not exist
-LINE 1: select * from dfunc('Hello World', c := 20, b := '2009-07-25...
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-drop function dfunc(varchar, numeric, date);
--- test out parameters with named params
-create function dfunc(a varchar = 'def a', out _a varchar, c numeric = NULL, out _c numeric)
-returns record as $$
- select $1, $2;
-$$ language sql;
-select (dfunc()).*;
- _a | _c
--------+----
- def a |
-(1 row)
-
-select * from dfunc();
- _a | _c
--------+----
- def a |
-(1 row)
-
-select * from dfunc('Hello', 100);
- _a | _c
--------+-----
- Hello | 100
-(1 row)
-
-select * from dfunc(a := 'Hello', c := 100);
- _a | _c
--------+-----
- Hello | 100
-(1 row)
-
-select * from dfunc(c := 100, a := 'Hello');
- _a | _c
--------+-----
- Hello | 100
-(1 row)
-
-select * from dfunc('Hello');
- _a | _c
--------+----
- Hello |
-(1 row)
-
-select * from dfunc('Hello', c := 100);
- _a | _c
--------+-----
- Hello | 100
-(1 row)
-
-select * from dfunc(c := 100);
- _a | _c
--------+-----
- def a | 100
-(1 row)
-
--- fail, can no longer change an input parameter's name
-create or replace function dfunc(a varchar = 'def a', out _a varchar, x numeric = NULL, out _c numeric)
-returns record as $$
- select $1, $2;
-$$ language sql;
-ERROR: cannot change name of input parameter "c"
-HINT: Use DROP FUNCTION first.
-create or replace function dfunc(a varchar = 'def a', out _a varchar, numeric = NULL, out _c numeric)
-returns record as $$
- select $1, $2;
-$$ language sql;
-ERROR: cannot change name of input parameter "c"
-HINT: Use DROP FUNCTION first.
-drop function dfunc(varchar, numeric);
---fail, named parameters are not unique
-create function testfoo(a int, a int) returns int as $$ select 1;$$ language sql;
-ERROR: parameter name "a" used more than once
-create function testfoo(int, out a int, out a int) returns int as $$ select 1;$$ language sql;
-ERROR: parameter name "a" used more than once
-create function testfoo(out a int, inout a int) returns int as $$ select 1;$$ language sql;
-ERROR: parameter name "a" used more than once
-create function testfoo(a int, inout a int) returns int as $$ select 1;$$ language sql;
-ERROR: parameter name "a" used more than once
--- valid
-create function testfoo(a int, out a int) returns int as $$ select $1;$$ language sql;
-select testfoo(37);
- testfoo
----------
- 37
-(1 row)
-
-drop function testfoo(int);
-create function testfoo(a int) returns table(a int) as $$ select $1;$$ language sql;
-select * from testfoo(37);
- a
-----
- 37
-(1 row)
-
-drop function testfoo(int);
--- test polymorphic params and defaults
-create function dfunc(a anyelement, b anyelement = null, flag bool = true)
-returns anyelement as $$
- select case when $3 then $1 else $2 end;
-$$ language sql;
-select dfunc(1,2);
- dfunc
--------
- 1
-(1 row)
-
-select dfunc('a'::text, 'b'); -- positional notation with default
- dfunc
--------
- a
-(1 row)
-
-select dfunc(a := 1, b := 2);
- dfunc
--------
- 1
-(1 row)
-
-select dfunc(a := 'a'::text, b := 'b');
- dfunc
--------
- a
-(1 row)
-
-select dfunc(a := 'a'::text, b := 'b', flag := false); -- named notation
- dfunc
--------
- b
-(1 row)
-
-select dfunc(b := 'b'::text, a := 'a'); -- named notation with default
- dfunc
--------
- a
-(1 row)
-
-select dfunc(a := 'a'::text, flag := true); -- named notation with default
- dfunc
--------
- a
-(1 row)
-
-select dfunc(a := 'a'::text, flag := false); -- named notation with default
- dfunc
--------
-
-(1 row)
-
-select dfunc(b := 'b'::text, a := 'a', flag := true); -- named notation
- dfunc
--------
- a
-(1 row)
-
-select dfunc('a'::text, 'b', false); -- full positional notation
- dfunc
--------
- b
-(1 row)
-
-select dfunc('a'::text, 'b', flag := false); -- mixed notation
- dfunc
--------
- b
-(1 row)
-
-select dfunc('a'::text, 'b', true); -- full positional notation
- dfunc
--------
- a
-(1 row)
-
-select dfunc('a'::text, 'b', flag := true); -- mixed notation
- dfunc
--------
- a
-(1 row)
-
--- check reverse-listing of named-arg calls
-CREATE VIEW dfview AS
- SELECT q1, q2,
- dfunc(q1,q2, flag := q1>q2) as c3,
- dfunc(q1, flag := q1<q2, b := q2) as c4
- FROM int8_tbl;
-select * from dfview order by 1,2,3,4;
- q1 | q2 | c3 | c4
-------------------+-------------------+------------------+-------------------
- 123 | 456 | 456 | 123
- 123 | 4567890123456789 | 4567890123456789 | 123
- 4567890123456789 | -4567890123456789 | 4567890123456789 | -4567890123456789
- 4567890123456789 | 123 | 4567890123456789 | 123
- 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789
-(5 rows)
-
-\d+ dfview
- View "public.dfview"
- Column | Type | Modifiers | Storage | Description
---------+--------+-----------+---------+-------------
- q1 | bigint | | plain |
- q2 | bigint | | plain |
- c3 | bigint | | plain |
- c4 | bigint | | plain |
-View definition:
- SELECT int8_tbl.q1, int8_tbl.q2,
- dfunc(int8_tbl.q1, int8_tbl.q2, flag := int8_tbl.q1 > int8_tbl.q2) AS c3,
- dfunc(int8_tbl.q1, flag := int8_tbl.q1 < int8_tbl.q2, b := int8_tbl.q2) AS c4
- FROM int8_tbl;
-
-drop view dfview;
-drop function dfunc(anyelement, anyelement, bool);
+++ /dev/null
---
--- PREPARED TRANSACTIONS (two-phase commit)
---
--- We can't readily test persistence of prepared xacts within the
--- regression script framework, unfortunately. Note that a crash
--- isn't really needed ... stopping and starting the postmaster would
--- be enough, but we can't even do that here.
--- create a simple table that we'll use in the tests
-CREATE TABLE pxtest1 (foobar VARCHAR(10)) distribute by replication;
-INSERT INTO pxtest1 VALUES ('aaa');
--- Test PREPARE TRANSACTION
-BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-UPDATE pxtest1 SET foobar = 'bbb' WHERE foobar = 'aaa';
-SELECT * FROM pxtest1 ORDER BY foobar;
- foobar
---------
- bbb
-(1 row)
-
-PREPARE TRANSACTION 'foo1';
-SELECT * FROM pxtest1 ORDER BY foobar;
- foobar
---------
- aaa
-(1 row)
-
--- Test pg_prepared_xacts system view
-SELECT gid FROM pg_prepared_xacts ORDER BY gid;
- gid
-------
- foo1
-(1 row)
-
--- Test pgxc_prepared_xacts system view
-SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1;
- pgxc_prepared_xact
---------------------
- foo1
-(1 row)
-
--- Test ROLLBACK PREPARED
-ROLLBACK PREPARED 'foo1';
-SELECT * FROM pxtest1 ORDER BY foobar;
- foobar
---------
- aaa
-(1 row)
-
--- Check prepared transactions on Coordinator
-SELECT gid FROM pg_prepared_xacts ORDER BY gid;
- gid
------
-(0 rows)
-
--- Check prepared transactions in the cluster
-SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1;
- pgxc_prepared_xact
---------------------
-(0 rows)
-
--- Test COMMIT PREPARED
-BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-INSERT INTO pxtest1 VALUES ('ddd');
-SELECT * FROM pxtest1 ORDER BY foobar;
- foobar
---------
- aaa
- ddd
-(2 rows)
-
-PREPARE TRANSACTION 'foo2';
-SELECT * FROM pxtest1 ORDER BY foobar;
- foobar
---------
- aaa
-(1 row)
-
-COMMIT PREPARED 'foo2';
-SELECT * FROM pxtest1 ORDER BY foobar;
- foobar
---------
- aaa
- ddd
-(2 rows)
-
--- Test duplicate gids
-BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd';
-SELECT * FROM pxtest1 ORDER BY foobar;
- foobar
---------
- aaa
- eee
-(2 rows)
-
-PREPARE TRANSACTION 'foo3';
--- Check prepared transactions on Coordinator
-SELECT gid FROM pg_prepared_xacts ORDER BY gid;
- gid
-------
- foo3
-(1 row)
-
--- Check prepared transactions in the cluster
-SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1;
- pgxc_prepared_xact
---------------------
- foo3
-(1 row)
-
-BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-INSERT INTO pxtest1 VALUES ('fff');
--- This should fail, because the gid foo3 is already in use
-PREPARE TRANSACTION 'foo3';
-ERROR: transaction identifier "foo3" is already in use
-SELECT * FROM pxtest1 ORDER BY foobar;
- foobar
---------
- aaa
- ddd
-(2 rows)
-
-ROLLBACK PREPARED 'foo3';
-SELECT * FROM pxtest1 ORDER BY foobar;
- foobar
---------
- aaa
- ddd
-(2 rows)
-
--- Test serialization failure (SSI)
-BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd';
-SELECT * FROM pxtest1;
- foobar
---------
- aaa
- eee
-(2 rows)
-
-PREPARE TRANSACTION 'foo4';
-SELECT gid FROM pg_prepared_xacts;
- gid
-------
- foo4
-(1 row)
-
-BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-SELECT * FROM pxtest1;
- foobar
---------
- aaa
- ddd
-(2 rows)
-
--- This should fail, because the two transactions have a write-skew anomaly
-INSERT INTO pxtest1 VALUES ('fff');
-PREPARE TRANSACTION 'foo5';
-SELECT gid FROM pg_prepared_xacts;
- gid
-------
- foo4
- foo5
-(2 rows)
-
-ROLLBACK PREPARED 'foo4';
-SELECT gid FROM pg_prepared_xacts;
- gid
-------
- foo5
-(1 row)
-
--- In Postgres-XL, serializable is not yet supported, and SERIALIZABLE falls to
--- read-committed silently, so rollback transaction properly
-ROLLBACK PREPARED 'foo5';
--- Clean up
-DROP TABLE pxtest1;
--- Test subtransactions
-BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
- CREATE TABLE pxtest2 (a int);
- INSERT INTO pxtest2 VALUES (1);
- SAVEPOINT a;
-ERROR: SAVEPOINT is not yet supported.
- INSERT INTO pxtest2 VALUES (2);
-ERROR: current transaction is aborted, commands ignored until end of transaction block
- ROLLBACK TO a;
-ERROR: no such savepoint
- SAVEPOINT b;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
- INSERT INTO pxtest2 VALUES (3);
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-PREPARE TRANSACTION 'regress-one';
-CREATE TABLE pxtest3(fff int);
--- Test shared invalidation
-BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
- DROP TABLE pxtest3;
- CREATE TABLE pxtest4 (a int);
- INSERT INTO pxtest4 VALUES (1);
- INSERT INTO pxtest4 VALUES (2);
- DECLARE foo CURSOR FOR SELECT * FROM pxtest4;
- -- Fetch 1 tuple, keeping the cursor open
- FETCH 1 FROM foo;
- a
----
- 1
-(1 row)
-
-PREPARE TRANSACTION 'regress-two';
--- No such cursor
-FETCH 1 FROM foo;
-ERROR: cursor "foo" does not exist
--- Table doesn't exist, the creation hasn't been committed yet
-SELECT * FROM pxtest2;
-ERROR: relation "pxtest2" does not exist
-LINE 1: SELECT * FROM pxtest2;
- ^
--- There should be two prepared transactions
-SELECT gid FROM pg_prepared_xacts ORDER BY gid;
- gid
--------------
- regress-two
-(1 row)
-
--- Check prepared transactions in the cluster
-SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1;
- pgxc_prepared_xact
---------------------
- regress-two
-(1 row)
-
--- pxtest3 should be locked because of the pending DROP
-set statement_timeout to 2000;
-SELECT * FROM pxtest3;
-ERROR: canceling statement due to statement timeout
-reset statement_timeout;
--- Disconnect, we will continue testing in a different backend
-\c -
--- There should still be two prepared transactions
-SELECT gid FROM pg_prepared_xacts ORDER BY gid;
- gid
--------------
- regress-two
-(1 row)
-
--- Check prepared transactions in the cluster
-SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1;
- pgxc_prepared_xact
---------------------
- regress-two
-(1 row)
-
--- pxtest3 should still be locked because of the pending DROP
-set statement_timeout to 2000;
-SELECT * FROM pxtest3;
-ERROR: canceling statement due to statement timeout
-reset statement_timeout;
--- Commit table creation
-COMMIT PREPARED 'regress-one';
-ERROR: prepared transaction with identifier "regress-one" does not exist
-\d pxtest2
-SELECT * FROM pxtest2;
-ERROR: relation "pxtest2" does not exist
-LINE 1: SELECT * FROM pxtest2;
- ^
--- There should be one prepared transaction
-SELECT gid FROM pg_prepared_xacts ORDER BY 1;
- gid
--------------
- regress-two
-(1 row)
-
--- Check prepared transactions in the cluster
-SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1;
- pgxc_prepared_xact
---------------------
- regress-two
-(1 row)
-
--- Commit table drop
-COMMIT PREPARED 'regress-two';
-SELECT * FROM pxtest3;
-ERROR: relation "pxtest3" does not exist
-LINE 1: SELECT * FROM pxtest3;
- ^
--- There should be no prepared transactions
-SELECT gid FROM pg_prepared_xacts ORDER BY gid;
- gid
------
-(0 rows)
-
--- Check prepared transactions in the cluster
-SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1;
- pgxc_prepared_xact
---------------------
-(0 rows)
-
--- Clean up
-DROP TABLE pxtest2;
-ERROR: table "pxtest2" does not exist
-DROP TABLE pxtest3; -- will still be there if prepared xacts are disabled
-ERROR: table "pxtest3" does not exist
-DROP TABLE pxtest4;
+++ /dev/null
---
--- Test access privileges
---
--- Clean up in case a prior regression run failed
--- Suppress NOTICE messages when users/groups don't exist
-SET client_min_messages TO 'warning';
-DROP ROLE IF EXISTS regressgroup1;
-DROP ROLE IF EXISTS regressgroup2;
-DROP ROLE IF EXISTS regressuser1;
-DROP ROLE IF EXISTS regressuser2;
-DROP ROLE IF EXISTS regressuser3;
-DROP ROLE IF EXISTS regressuser4;
-DROP ROLE IF EXISTS regressuser5;
-DROP ROLE IF EXISTS regressuser6;
-SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
- lo_unlink
------------
-(0 rows)
-
-RESET client_min_messages;
--- test proper begins here
-CREATE USER regressuser1;
-CREATE USER regressuser2;
-CREATE USER regressuser3;
-CREATE USER regressuser4;
-CREATE USER regressuser5;
-CREATE USER regressuser5; -- duplicate
-ERROR: role "regressuser5" already exists
-CREATE GROUP regressgroup1;
-CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2;
-ALTER GROUP regressgroup1 ADD USER regressuser4;
-ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate
-NOTICE: role "regressuser2" is already a member of role "regressgroup2"
-ALTER GROUP regressgroup2 DROP USER regressuser2;
-ALTER GROUP regressgroup2 ADD USER regressuser4;
--- test owner privileges
-SET SESSION AUTHORIZATION regressuser1;
-SELECT session_user, current_user;
- session_user | current_user
---------------+--------------
- regressuser1 | regressuser1
-(1 row)
-
-CREATE TABLE atest1 ( a int, b text );
-SELECT * FROM atest1;
- a | b
----+---
-(0 rows)
-
-INSERT INTO atest1 VALUES (1, 'one');
-DELETE FROM atest1;
-UPDATE atest1 SET a = 1 WHERE b = 'blech';
-ERROR: Partition column can't be updated in current version
-TRUNCATE atest1;
-BEGIN;
-LOCK atest1 IN ACCESS EXCLUSIVE MODE;
-COMMIT;
-REVOKE ALL ON atest1 FROM PUBLIC;
-SELECT * FROM atest1;
- a | b
----+---
-(0 rows)
-
-GRANT ALL ON atest1 TO regressuser2;
-GRANT SELECT ON atest1 TO regressuser3, regressuser4;
-SELECT * FROM atest1;
- a | b
----+---
-(0 rows)
-
-CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
-GRANT SELECT ON atest2 TO regressuser2;
-GRANT UPDATE ON atest2 TO regressuser3;
-GRANT INSERT ON atest2 TO regressuser4;
-GRANT TRUNCATE ON atest2 TO regressuser5;
-SET SESSION AUTHORIZATION regressuser2;
-SELECT session_user, current_user;
- session_user | current_user
---------------+--------------
- regressuser2 | regressuser2
-(1 row)
-
--- try various combinations of queries on atest1 and atest2
-SELECT * FROM atest1; -- ok
- a | b
----+---
-(0 rows)
-
-SELECT * FROM atest2; -- ok
- col1 | col2
-------+------
-(0 rows)
-
-INSERT INTO atest1 VALUES (2, 'two'); -- ok
-INSERT INTO atest2 VALUES ('foo', true); -- fail
-ERROR: permission denied for relation atest2
-INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok
-UPDATE atest1 SET a = 1 WHERE a = 2; -- ok
-ERROR: Partition column can't be updated in current version
-UPDATE atest2 SET col2 = NOT col2; -- fail
-ERROR: permission denied for relation atest2
-SELECT * FROM atest1 ORDER BY 1 FOR UPDATE; -- ok
- a | b
----+-----
- 1 | two
- 2 | two
-(2 rows)
-
-SELECT * FROM atest2 ORDER BY 1 FOR UPDATE; -- fail
-ERROR: permission denied for relation atest2
-DELETE FROM atest2; -- fail
-ERROR: permission denied for relation atest2
-TRUNCATE atest2; -- fail
-ERROR: permission denied for relation atest2
-BEGIN;
-LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
-ERROR: permission denied for relation atest2
-COMMIT;
-COPY atest2 FROM stdin; -- fail
-ERROR: permission denied for relation atest2
-GRANT ALL ON atest1 TO PUBLIC; -- fail
-WARNING: no privileges were granted for "atest1"
--- checks in subquery, both ok
-SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
- a | b
----+---
-(0 rows)
-
-SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) );
- col1 | col2
-------+------
-(0 rows)
-
-SET SESSION AUTHORIZATION regressuser3;
-SELECT session_user, current_user;
- session_user | current_user
---------------+--------------
- regressuser3 | regressuser3
-(1 row)
-
-SELECT * FROM atest1 ORDER BY 1; -- ok
- a | b
----+-----
- 1 | two
- 2 | two
-(2 rows)
-
-SELECT * FROM atest2; -- fail
-ERROR: permission denied for relation atest2
-INSERT INTO atest1 VALUES (2, 'two'); -- fail
-ERROR: permission denied for relation atest1
-INSERT INTO atest2 VALUES ('foo', true); -- fail
-ERROR: permission denied for relation atest2
-INSERT INTO atest1 SELECT 1, b FROM atest1; -- fail
-ERROR: permission denied for relation atest1
-UPDATE atest1 SET a = 1 WHERE a = 2; -- fail
-ERROR: Partition column can't be updated in current version
-UPDATE atest2 SET col2 = NULL; -- ok
-UPDATE atest2 SET col2 = NOT col2; -- fails; requires SELECT on atest2
-ERROR: permission denied for relation atest2
-UPDATE atest2 SET col2 = true FROM atest1 WHERE atest1.a = 5; -- ok
-ERROR: permission denied for relation atest2
-SELECT * FROM atest1 FOR UPDATE; -- fail
-ERROR: permission denied for relation atest1
-SELECT * FROM atest2 FOR UPDATE; -- fail
-ERROR: permission denied for relation atest2
-DELETE FROM atest2; -- fail
-ERROR: permission denied for relation atest2
-TRUNCATE atest2; -- fail
-ERROR: permission denied for relation atest2
-BEGIN;
-LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
-COMMIT;
-COPY atest2 FROM stdin; -- fail
-ERROR: permission denied for relation atest2
--- checks in subquery, both fail
-SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
-ERROR: permission denied for relation atest2
-SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) );
-ERROR: permission denied for relation atest2
-SET SESSION AUTHORIZATION regressuser4;
-COPY atest2 FROM stdin; -- ok
-SELECT * FROM atest1 ORDER BY 1; -- ok
- a | b
----+-----
- 1 | two
- 2 | two
-(2 rows)
-
--- groups
-SET SESSION AUTHORIZATION regressuser3;
-CREATE TABLE atest3 (one int, two int, three int);
-GRANT DELETE ON atest3 TO GROUP regressgroup2;
-SET SESSION AUTHORIZATION regressuser1;
-SELECT * FROM atest3; -- fail
-ERROR: permission denied for relation atest3
-DELETE FROM atest3; -- ok
--- views
-SET SESSION AUTHORIZATION regressuser3;
-CREATE VIEW atestv1 AS SELECT * FROM atest1; -- ok
-/* The next *should* fail, but it's not implemented that way yet. */
-CREATE VIEW atestv2 AS SELECT * FROM atest2;
-CREATE VIEW atestv3 AS SELECT * FROM atest3; -- ok
-SELECT * FROM atestv1; -- ok
- a | b
----+-----
- 2 | two
- 1 | two
-(2 rows)
-
-SELECT * FROM atestv2; -- fail
-ERROR: permission denied for relation atest2
-GRANT SELECT ON atestv1, atestv3 TO regressuser4;
-GRANT SELECT ON atestv2 TO regressuser2;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT * FROM atestv1; -- ok
- a | b
----+-----
- 2 | two
- 1 | two
-(2 rows)
-
-SELECT * FROM atestv2; -- fail
-ERROR: permission denied for relation atestv2
-SELECT * FROM atestv3; -- fail due to issue 3520503, see above
-ERROR: permission denied for relation atest3
-CREATE VIEW atestv4 AS SELECT * FROM atestv3; -- nested view
-SELECT * FROM atestv4; -- fail due to issue 3520503, see above
-ERROR: permission denied for relation atest3
-GRANT SELECT ON atestv4 TO regressuser2;
-SET SESSION AUTHORIZATION regressuser2;
--- Two complex cases:
-SELECT * FROM atestv3; -- fail
-ERROR: permission denied for relation atestv3
--- fail due to issue 3520503, see above
-SELECT * FROM atestv4; -- ok (even though regressuser2 cannot access underlying atestv3)
-ERROR: permission denied for relation atest3
-SELECT * FROM atest2; -- ok
- col1 | col2
-------+------
- bar | t
-(1 row)
-
-SELECT * FROM atestv2; -- fail (even though regressuser2 can access underlying atest2)
-ERROR: permission denied for relation atest2
--- Test column level permissions
-SET SESSION AUTHORIZATION regressuser1;
-CREATE TABLE atest5 (one int, two int, three int);
-CREATE TABLE atest6 (one int, two int, blue int);
-GRANT SELECT (one), INSERT (two), UPDATE (three) ON atest5 TO regressuser4;
-GRANT ALL (one) ON atest5 TO regressuser3;
-INSERT INTO atest5 VALUES (1,2,3);
-SET SESSION AUTHORIZATION regressuser4;
-SELECT * FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-SELECT one FROM atest5; -- ok
- one
------
- 1
-(1 row)
-
-COPY atest5 (one) TO stdout; -- ok
-1
-SELECT two FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-COPY atest5 (two) TO stdout; -- fail
-ERROR: permission denied for relation atest5
-SELECT atest5 FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-COPY atest5 (one,two) TO stdout; -- fail
-ERROR: permission denied for relation atest5
-SELECT 1 FROM atest5; -- ok
- ?column?
-----------
- 1
-(1 row)
-
-SELECT 1 FROM atest5 a JOIN atest5 b USING (one); -- ok
- ?column?
-----------
- 1
-(1 row)
-
-SELECT 1 FROM atest5 a JOIN atest5 b USING (two); -- fail
-ERROR: permission denied for relation atest5
-SELECT 1 FROM atest5 a NATURAL JOIN atest5 b; -- fail
-ERROR: permission denied for relation atest5
-SELECT (j.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)) j; -- fail
-ERROR: permission denied for relation atest5
-SELECT 1 FROM atest5 WHERE two = 2; -- fail
-ERROR: permission denied for relation atest5
-SELECT * FROM atest1, atest5; -- fail
-ERROR: permission denied for relation atest5
-SELECT atest1.* FROM atest1, atest5; -- ok
-ERROR: permission denied for relation atest5
-SELECT atest1.*,atest5.one FROM atest1, atest5; -- ok
- a | b | one
----+-----+-----
- 2 | two | 1
- 1 | two | 1
-(2 rows)
-
-SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.two); -- fail
-ERROR: permission denied for relation atest5
-SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.one); -- ok
- a | b | one
----+-----+-----
- 1 | two | 1
-(1 row)
-
-SELECT one, two FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-SET SESSION AUTHORIZATION regressuser1;
-GRANT SELECT (one,two) ON atest6 TO regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT one, two FROM atest5 NATURAL JOIN atest6; -- fail still
-ERROR: permission denied for relation atest5
-SET SESSION AUTHORIZATION regressuser1;
-GRANT SELECT (two) ON atest5 TO regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT one, two FROM atest5 NATURAL JOIN atest6; -- ok now
- one | two
------+-----
-(0 rows)
-
--- test column-level privileges for INSERT and UPDATE
-INSERT INTO atest5 (two) VALUES (3); -- fail due to issue 3520503, see above
-ERROR: permission denied for relation atest5
-COPY atest5 FROM stdin; -- fail
-ERROR: permission denied for relation atest5
-COPY atest5 (two) FROM stdin; -- ok
-INSERT INTO atest5 (three) VALUES (4); -- fail
-ERROR: permission denied for relation atest5
-INSERT INTO atest5 VALUES (5,5,5); -- fail
-ERROR: permission denied for relation atest5
-UPDATE atest5 SET three = 10; -- ok
-UPDATE atest5 SET one = 8; -- fail
-ERROR: Partition column can't be updated in current version
-UPDATE atest5 SET three = 5, one = 2; -- fail
-ERROR: Partition column can't be updated in current version
-SET SESSION AUTHORIZATION regressuser1;
-REVOKE ALL (one) ON atest5 FROM regressuser4;
-GRANT SELECT (one,two,blue) ON atest6 TO regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT one FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-UPDATE atest5 SET one = 1; -- fail
-ERROR: Partition column can't be updated in current version
-SELECT atest6 FROM atest6; -- ok
- atest6
---------
-(0 rows)
-
-COPY atest6 TO stdout; -- ok
--- test column-level privileges when involved with DELETE
-SET SESSION AUTHORIZATION regressuser1;
-ALTER TABLE atest6 ADD COLUMN three integer;
-GRANT DELETE ON atest5 TO regressuser3;
-GRANT SELECT (two) ON atest5 TO regressuser3;
-REVOKE ALL (one) ON atest5 FROM regressuser3;
-GRANT SELECT (one) ON atest5 TO regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT atest6 FROM atest6; -- fail
-ERROR: permission denied for relation atest6
-SELECT one FROM atest5 NATURAL JOIN atest6; -- fail
-ERROR: permission denied for relation atest5
-SET SESSION AUTHORIZATION regressuser1;
-ALTER TABLE atest6 DROP COLUMN three;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT atest6 FROM atest6; -- ok
- atest6
---------
-(0 rows)
-
-SELECT one FROM atest5 NATURAL JOIN atest6; -- ok
- one
------
-(0 rows)
-
-SET SESSION AUTHORIZATION regressuser1;
-ALTER TABLE atest6 DROP COLUMN two;
-REVOKE SELECT (one,blue) ON atest6 FROM regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT * FROM atest6; -- fail
-ERROR: permission denied for relation atest6
-SELECT 1 FROM atest6; -- fail
-ERROR: permission denied for relation atest6
-SET SESSION AUTHORIZATION regressuser3;
-DELETE FROM atest5 WHERE one = 1; -- fail
-ERROR: permission denied for relation atest5
-DELETE FROM atest5 WHERE two = 2; -- ok
--- check inheritance cases
-SET SESSION AUTHORIZATION regressuser1;
-CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS;
-CREATE TABLE atestp2 (fx int, fy int) WITH OIDS;
-CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2);
-GRANT SELECT(fx,fy,oid) ON atestp2 TO regressuser2;
-GRANT SELECT(fx) ON atestc TO regressuser2;
-SET SESSION AUTHORIZATION regressuser2;
-SELECT fx FROM atestp2; -- ok
- fx
-----
-(0 rows)
-
-SELECT fy FROM atestp2; -- fail due to issue 3520503, see above
-ERROR: permission denied for relation atestc
-SELECT atestp2 FROM atestp2; -- fail due to issue 3520503, see above
-ERROR: permission denied for relation atestc
-SELECT oid FROM atestp2; -- fail due to issue 3520503, see above
-ERROR: permission denied for relation atestc
-SELECT fy FROM atestc; -- fail
-ERROR: permission denied for relation atestc
-SET SESSION AUTHORIZATION regressuser1;
-GRANT SELECT(fy,oid) ON atestc TO regressuser2;
-SET SESSION AUTHORIZATION regressuser2;
-SELECT fx FROM atestp2; -- still ok
- fx
-----
-(0 rows)
-
-SELECT fy FROM atestp2; -- ok
- fy
-----
-(0 rows)
-
-SELECT atestp2 FROM atestp2; -- fail due to issue 3520503, see above
-ERROR: permission denied for relation atestc
-SELECT oid FROM atestp2; -- ok
- oid
------
-(0 rows)
-
--- privileges on functions, languages
--- switch to superuser
-\c -
-REVOKE ALL PRIVILEGES ON LANGUAGE sql FROM PUBLIC;
-GRANT USAGE ON LANGUAGE sql TO regressuser1; -- ok
-GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail
-ERROR: language "c" is not trusted
-SET SESSION AUTHORIZATION regressuser1;
-GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
-WARNING: no privileges were granted for "sql"
-CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
-CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
-REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC;
-GRANT EXECUTE ON FUNCTION testfunc1(int), testfunc2(int) TO regressuser2;
-GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error
-ERROR: invalid privilege type USAGE for function
-GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4;
-GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regressuser4;
-ERROR: function testfunc_nosuch(integer) does not exist
-CREATE FUNCTION testfunc4(boolean) RETURNS text
- AS 'select col1 from atest2 where col2 = $1;'
- LANGUAGE sql SECURITY DEFINER;
-GRANT EXECUTE ON FUNCTION testfunc4(boolean) TO regressuser3;
-SET SESSION AUTHORIZATION regressuser2;
-SELECT testfunc1(5), testfunc2(5); -- ok
- testfunc1 | testfunc2
------------+-----------
- 10 | 15
-(1 row)
-
-CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
-ERROR: permission denied for language sql
-SET SESSION AUTHORIZATION regressuser3;
-SELECT testfunc1(5); -- fail
-ERROR: permission denied for function testfunc1
-SELECT col1 FROM atest2 WHERE col2 = true; -- fail
-ERROR: permission denied for relation atest2
-SELECT testfunc4(true); -- fail due to issue 3520503, see above
-ERROR: permission denied for relation atest2
-CONTEXT: SQL function "testfunc4" statement 1
-SET SESSION AUTHORIZATION regressuser4;
-SELECT testfunc1(5); -- ok
- testfunc1
------------
- 10
-(1 row)
-
-DROP FUNCTION testfunc1(int); -- fail
-ERROR: must be owner of function testfunc1
-\c -
-DROP FUNCTION testfunc1(int); -- ok
--- restore to sanity
-GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
--- privileges on types
--- switch to superuser
-\c -
-CREATE TYPE testtype1 AS (a int, b text);
-REVOKE USAGE ON TYPE testtype1 FROM PUBLIC;
-GRANT USAGE ON TYPE testtype1 TO regressuser2;
-GRANT USAGE ON TYPE _testtype1 TO regressuser2; -- fail
-ERROR: cannot set privileges of array types
-GRANT USAGE ON DOMAIN testtype1 TO regressuser2; -- fail
-ERROR: "testtype1" is not a domain
-CREATE DOMAIN testdomain1 AS int;
-REVOKE USAGE on DOMAIN testdomain1 FROM PUBLIC;
-GRANT USAGE ON DOMAIN testdomain1 TO regressuser2;
-GRANT USAGE ON TYPE testdomain1 TO regressuser2; -- ok
-SET SESSION AUTHORIZATION regressuser1;
--- commands that should fail
-CREATE AGGREGATE testagg1a(testdomain1) (sfunc = int4_sum, stype = bigint);
-ERROR: permission denied for type testdomain1
-CREATE DOMAIN testdomain2a AS testdomain1;
-ERROR: permission denied for type testdomain1
-CREATE DOMAIN testdomain3a AS int;
-CREATE FUNCTION castfunc(int) RETURNS testdomain3a AS $$ SELECT $1::testdomain3a $$ LANGUAGE SQL;
-CREATE CAST (testdomain1 AS testdomain3a) WITH FUNCTION castfunc(int);
-ERROR: permission denied for type testdomain1
-DROP FUNCTION castfunc(int) CASCADE;
-DROP DOMAIN testdomain3a;
-CREATE FUNCTION testfunc5a(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
-ERROR: permission denied for type testdomain1
-CREATE FUNCTION testfunc6a(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$;
-ERROR: permission denied for type testdomain1
-CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = testdomain1, RIGHTARG = testdomain1);
-ERROR: permission denied for type testdomain1
-CREATE TABLE test5a (a int, b testdomain1);
-ERROR: permission denied for type testdomain1
-CREATE TABLE test6a OF testtype1;
-ERROR: permission denied for type testtype1
-CREATE TABLE test10a (a int[], b testtype1[]);
-ERROR: permission denied for type testtype1[]
-CREATE TABLE test9a (a int, b int);
-ALTER TABLE test9a ADD COLUMN c testdomain1;
-ERROR: permission denied for type testdomain1
-ALTER TABLE test9a ALTER COLUMN b TYPE testdomain1;
-ERROR: permission denied for type testdomain1
-CREATE TYPE test7a AS (a int, b testdomain1);
-ERROR: permission denied for type testdomain1
-CREATE TYPE test8a AS (a int, b int);
-ALTER TYPE test8a ADD ATTRIBUTE c testdomain1;
-ERROR: permission denied for type testdomain1
-ALTER TYPE test8a ALTER ATTRIBUTE b TYPE testdomain1;
-ERROR: permission denied for type testdomain1
-CREATE TABLE test11a AS (SELECT 1::testdomain1 AS a);
-ERROR: permission denied for type testdomain1
-REVOKE ALL ON TYPE testtype1 FROM PUBLIC;
-ERROR: permission denied for type testtype1
-SET SESSION AUTHORIZATION regressuser2;
--- commands that should succeed
-CREATE AGGREGATE testagg1b(testdomain1) (sfunc = int4_sum, stype = bigint);
-CREATE DOMAIN testdomain2b AS testdomain1;
-CREATE DOMAIN testdomain3b AS int;
-CREATE FUNCTION castfunc(int) RETURNS testdomain3b AS $$ SELECT $1::testdomain3b $$ LANGUAGE SQL;
-CREATE CAST (testdomain1 AS testdomain3b) WITH FUNCTION castfunc(int);
-WARNING: cast will be ignored because the source data type is a domain
-CREATE FUNCTION testfunc5b(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
-CREATE FUNCTION testfunc6b(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$;
-CREATE OPERATOR !! (PROCEDURE = testfunc5b, RIGHTARG = testdomain1);
-CREATE TABLE test5b (a int, b testdomain1);
-CREATE TABLE test6b OF testtype1;
-CREATE TABLE test10b (a int[], b testtype1[]);
-CREATE TABLE test9b (a int, b int);
-ALTER TABLE test9b ADD COLUMN c testdomain1;
-ALTER TABLE test9b ALTER COLUMN b TYPE testdomain1;
-CREATE TYPE test7b AS (a int, b testdomain1);
-CREATE TYPE test8b AS (a int, b int);
-ALTER TYPE test8b ADD ATTRIBUTE c testdomain1;
-ALTER TYPE test8b ALTER ATTRIBUTE b TYPE testdomain1;
-CREATE TABLE test11b AS (SELECT 1::testdomain1 AS a);
-REVOKE ALL ON TYPE testtype1 FROM PUBLIC;
-WARNING: no privileges could be revoked for "testtype1"
-\c -
-DROP AGGREGATE testagg1b(testdomain1);
-DROP DOMAIN testdomain2b;
-DROP OPERATOR !! (NONE, testdomain1);
-DROP FUNCTION testfunc5b(a testdomain1);
-DROP FUNCTION testfunc6b(b int);
-DROP TABLE test5b;
-DROP TABLE test6b;
-DROP TABLE test9b;
-DROP TABLE test10b;
-DROP TYPE test7b;
-DROP TYPE test8b;
-DROP CAST (testdomain1 AS testdomain3b);
-DROP FUNCTION castfunc(int) CASCADE;
-DROP DOMAIN testdomain3b;
-DROP TABLE test11b;
-DROP TYPE testtype1; -- ok
-DROP DOMAIN testdomain1; -- ok
--- truncate
-SET SESSION AUTHORIZATION regressuser5;
-TRUNCATE atest2; -- ok
-TRUNCATE atest3; -- fail
-ERROR: permission denied for relation atest3
--- has_table_privilege function
--- bad-input checks
-select has_table_privilege(NULL,'pg_authid','select');
- has_table_privilege
----------------------
-
-(1 row)
-
-select has_table_privilege('pg_shad','select');
-ERROR: relation "pg_shad" does not exist
-select has_table_privilege('nosuchuser','pg_authid','select');
-ERROR: role "nosuchuser" does not exist
-select has_table_privilege('pg_authid','sel');
-ERROR: unrecognized privilege type: "sel"
-select has_table_privilege(-999999,'pg_authid','update');
-ERROR: role with OID 4293967297 does not exist
-select has_table_privilege(1,'select');
- has_table_privilege
----------------------
-
-(1 row)
-
--- superuser
-\c -
-select has_table_privilege(current_user,'pg_authid','select');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(current_user,'pg_authid','insert');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,'pg_authid','update')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,'pg_authid','delete')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
--- 'rule' privilege no longer exists, but for backwards compatibility
--- has_table_privilege still recognizes the keyword and says FALSE
-select has_table_privilege(current_user,t1.oid,'rule')
-from (select oid from pg_class where relname = 'pg_authid') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(current_user,t1.oid,'references')
-from (select oid from pg_class where relname = 'pg_authid') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_authid') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'insert')
-from (select oid from pg_class where relname = 'pg_authid') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege('pg_authid','update');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege('pg_authid','delete');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege('pg_authid','truncate');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_authid') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t1.oid,'trigger')
-from (select oid from pg_class where relname = 'pg_authid') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
--- non-superuser
-SET SESSION AUTHORIZATION regressuser3;
-select has_table_privilege(current_user,'pg_class','select');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(current_user,'pg_class','insert');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,'pg_class','update')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,'pg_class','delete')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(current_user,t1.oid,'references')
-from (select oid from pg_class where relname = 'pg_class') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_class') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'insert')
-from (select oid from pg_class where relname = 'pg_class') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('pg_class','update');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('pg_class','delete');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('pg_class','truncate');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_class') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t1.oid,'trigger')
-from (select oid from pg_class where relname = 'pg_class') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(current_user,'atest1','select');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(current_user,'atest1','insert');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,'atest1','update')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,'atest1','delete')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(current_user,t1.oid,'references')
-from (select oid from pg_class where relname = 'atest1') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'select')
-from (select oid from pg_class where relname = 'atest1') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'insert')
-from (select oid from pg_class where relname = 'atest1') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('atest1','update');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('atest1','delete');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('atest1','truncate');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t1.oid,'select')
-from (select oid from pg_class where relname = 'atest1') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t1.oid,'trigger')
-from (select oid from pg_class where relname = 'atest1') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
--- Grant options
-SET SESSION AUTHORIZATION regressuser1;
-CREATE TABLE atest4 (a int);
-GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION;
-GRANT UPDATE ON atest4 TO regressuser2;
-GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION;
-SET SESSION AUTHORIZATION regressuser2;
-GRANT SELECT ON atest4 TO regressuser3;
-GRANT UPDATE ON atest4 TO regressuser3; -- fail
-WARNING: no privileges were granted for "atest4"
-SET SESSION AUTHORIZATION regressuser1;
-REVOKE SELECT ON atest4 FROM regressuser3; -- does nothing
-SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
-REVOKE SELECT ON atest4 FROM regressuser2; -- fail
-ERROR: dependent privileges exist
-REVOKE GRANT OPTION FOR SELECT ON atest4 FROM regressuser2 CASCADE; -- ok
-SELECT has_table_privilege('regressuser2', 'atest4', 'SELECT'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- false
- has_table_privilege
----------------------
- f
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'atest4', 'SELECT WITH GRANT OPTION'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
--- has_sequence_privilege tests
-\c -
-CREATE SEQUENCE x_seq;
-GRANT USAGE on x_seq to regressuser2;
-SELECT has_sequence_privilege('regressuser1', 'atest1', 'SELECT');
-ERROR: "atest1" is not a sequence
-SELECT has_sequence_privilege('regressuser1', 'x_seq', 'INSERT');
-ERROR: unrecognized privilege type: "INSERT"
-SELECT has_sequence_privilege('regressuser1', 'x_seq', 'SELECT');
- has_sequence_privilege
-------------------------
- f
-(1 row)
-
-SET SESSION AUTHORIZATION regressuser2;
-SELECT has_sequence_privilege('x_seq', 'USAGE');
- has_sequence_privilege
-------------------------
- t
-(1 row)
-
--- largeobject privilege tests
-\c -
-SET SESSION AUTHORIZATION regressuser1;
-SELECT lo_create(1001);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_create(1002);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_create(1003);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_create(1004);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_create(1005);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-GRANT ALL ON LARGE OBJECT 1001 TO PUBLIC;
-ERROR: large object 1001 does not exist
-GRANT SELECT ON LARGE OBJECT 1003 TO regressuser2;
-ERROR: large object 1003 does not exist
-GRANT SELECT,UPDATE ON LARGE OBJECT 1004 TO regressuser2;
-ERROR: large object 1004 does not exist
-GRANT ALL ON LARGE OBJECT 1005 TO regressuser2;
-ERROR: large object 1005 does not exist
-GRANT SELECT ON LARGE OBJECT 1005 TO regressuser2 WITH GRANT OPTION;
-ERROR: large object 1005 does not exist
-GRANT SELECT, INSERT ON LARGE OBJECT 1001 TO PUBLIC; -- to be failed
-ERROR: large object 1001 does not exist
-GRANT SELECT, UPDATE ON LARGE OBJECT 1001 TO nosuchuser; -- to be failed
-ERROR: large object 1001 does not exist
-GRANT SELECT, UPDATE ON LARGE OBJECT 999 TO PUBLIC; -- to be failed
-ERROR: large object 999 does not exist
-\c -
-SET SESSION AUTHORIZATION regressuser2;
-SELECT lo_create(2001);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_create(2002);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1001, x'40000'::int), 32);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1003, x'40000'::int), 32);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1004, x'40000'::int), 32);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1001, x'20000'::int), 'abcd');
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1003, x'20000'::int), 'abcd'); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1004, x'20000'::int), 'abcd');
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-GRANT SELECT ON LARGE OBJECT 1005 TO regressuser3;
-ERROR: large object 1005 does not exist
-GRANT UPDATE ON LARGE OBJECT 1006 TO regressuser3; -- to be denied
-ERROR: large object 1006 does not exist
-REVOKE ALL ON LARGE OBJECT 2001, 2002 FROM PUBLIC;
-ERROR: large object 2001 does not exist
-GRANT ALL ON LARGE OBJECT 2001 TO regressuser3;
-ERROR: large object 2001 does not exist
-SELECT lo_unlink(1001); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_unlink(2002);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-\c -
--- confirm ACL setting
-SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata;
- oid | ownername | lomacl
------+-----------+--------
-(0 rows)
-
-SET SESSION AUTHORIZATION regressuser3;
-SELECT loread(lo_open(1001, x'40000'::int), 32);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1003, x'40000'::int), 32); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1005, x'40000'::int), 32);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_truncate(lo_open(1005, x'20000'::int), 10); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_truncate(lo_open(2001, x'20000'::int), 10);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
--- compatibility mode in largeobject permission
-\c -
-SET lo_compat_privileges = false; -- default setting
-SET SESSION AUTHORIZATION regressuser4;
-SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_unlink(1002); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_export(1001, '/dev/null'); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-\c -
-SET lo_compat_privileges = true; -- compatibility mode
-SET SESSION AUTHORIZATION regressuser4;
-SELECT loread(lo_open(1002, x'40000'::int), 32);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd');
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_truncate(lo_open(1002, x'20000'::int), 10);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_unlink(1002);
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
-SELECT lo_export(1001, '/dev/null'); -- to be denied
-ERROR: Postgres-XL does not support large object yet
-DETAIL: The feature is not currently supported
--- don't allow unpriv users to access pg_largeobject contents
-\c -
-SELECT * FROM pg_largeobject LIMIT 0;
- loid | pageno | data
-------+--------+------
-(0 rows)
-
-SET SESSION AUTHORIZATION regressuser1;
-SELECT * FROM pg_largeobject LIMIT 0; -- to be denied
-ERROR: permission denied for relation pg_largeobject
--- test default ACLs
-\c -
-CREATE SCHEMA testns;
-GRANT ALL ON SCHEMA testns TO regressuser1;
-CREATE TABLE testns.acltest1 (x int);
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT SELECT ON TABLES TO public;
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-DROP TABLE testns.acltest1;
-CREATE TABLE testns.acltest1 (x int);
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- yes
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT INSERT ON TABLES TO regressuser1;
-DROP TABLE testns.acltest1;
-CREATE TABLE testns.acltest1 (x int);
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- yes
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- yes
- has_table_privilege
----------------------
- t
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns REVOKE INSERT ON TABLES FROM regressuser1;
-DROP TABLE testns.acltest1;
-CREATE TABLE testns.acltest1 (x int);
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- yes
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES FOR ROLE regressuser1 REVOKE EXECUTE ON FUNCTIONS FROM public;
-SET ROLE regressuser1;
-CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql;
-SELECT has_function_privilege('regressuser2', 'testns.foo()', 'EXECUTE'); -- no
- has_function_privilege
-------------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT EXECUTE ON FUNCTIONS to public;
-DROP FUNCTION testns.foo();
-CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql;
-SELECT has_function_privilege('regressuser2', 'testns.foo()', 'EXECUTE'); -- yes
- has_function_privilege
-------------------------
- t
-(1 row)
-
-DROP FUNCTION testns.foo();
-ALTER DEFAULT PRIVILEGES FOR ROLE regressuser1 REVOKE USAGE ON TYPES FROM public;
-CREATE DOMAIN testns.testdomain1 AS int;
-SELECT has_type_privilege('regressuser2', 'testns.testdomain1', 'USAGE'); -- no
- has_type_privilege
---------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON TYPES to public;
-DROP DOMAIN testns.testdomain1;
-CREATE DOMAIN testns.testdomain1 AS int;
-SELECT has_type_privilege('regressuser2', 'testns.testdomain1', 'USAGE'); -- yes
- has_type_privilege
---------------------
- t
-(1 row)
-
-DROP DOMAIN testns.testdomain1;
-RESET ROLE;
-SELECT count(*)
- FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
- WHERE nspname = 'testns';
- count
--------
- 3
-(1 row)
-
-DROP SCHEMA testns CASCADE;
-NOTICE: drop cascades to table testns.acltest1
-SELECT d.* -- check that entries went away
- FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
- WHERE nspname IS NULL AND defaclnamespace != 0;
- defaclrole | defaclnamespace | defaclobjtype | defaclacl
-------------+-----------------+---------------+-----------
-(0 rows)
-
--- Grant on all objects of given type in a schema
-\c -
-CREATE SCHEMA testns;
-CREATE TABLE testns.t1 (f1 int);
-CREATE TABLE testns.t2 (f1 int);
-SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- false
- has_table_privilege
----------------------
- f
-(1 row)
-
-GRANT ALL ON ALL TABLES IN SCHEMA testns TO regressuser1;
-SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.t2', 'SELECT'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
-REVOKE ALL ON ALL TABLES IN SCHEMA testns FROM regressuser1;
-SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- false
- has_table_privilege
----------------------
- f
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.t2', 'SELECT'); -- false
- has_table_privilege
----------------------
- f
-(1 row)
-
-CREATE FUNCTION testns.testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
-SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE'); -- true by default
- has_function_privilege
-------------------------
- t
-(1 row)
-
-REVOKE ALL ON ALL FUNCTIONS IN SCHEMA testns FROM PUBLIC;
-SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE'); -- false
- has_function_privilege
-------------------------
- f
-(1 row)
-
-SET client_min_messages TO 'warning';
-DROP SCHEMA testns CASCADE;
-RESET client_min_messages;
--- clean up
-\c
-drop sequence x_seq;
-DROP FUNCTION testfunc2(int);
-DROP FUNCTION testfunc4(boolean);
-DROP VIEW atestv1;
-DROP VIEW atestv2;
--- this should cascade to drop atestv4
-DROP VIEW atestv3 CASCADE;
-NOTICE: drop cascades to view atestv4
--- this should complain "does not exist"
-DROP VIEW atestv4;
-ERROR: view "atestv4" does not exist
-DROP TABLE atest1;
-DROP TABLE atest2;
-DROP TABLE atest3;
-DROP TABLE atest4;
-DROP TABLE atest5;
-DROP TABLE atest6;
-DROP TABLE atestc;
-DROP TABLE atestp1;
-DROP TABLE atestp2;
-SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
- lo_unlink
------------
-(0 rows)
-
-DROP GROUP regressgroup1;
-DROP GROUP regressgroup2;
--- these are needed to clean up permissions
-REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
-DROP OWNED BY regressuser1;
-DROP USER regressuser1;
-DROP USER regressuser2;
-DROP USER regressuser3;
-DROP USER regressuser4;
-DROP USER regressuser5;
-DROP USER regressuser6;
-ERROR: role "regressuser6" does not exist
+++ /dev/null
---
--- Test access privileges
---
--- Clean up in case a prior regression run failed
--- Suppress NOTICE messages when users/groups don't exist
-SET client_min_messages TO 'warning';
-DROP ROLE IF EXISTS regressgroup1;
-DROP ROLE IF EXISTS regressgroup2;
-DROP ROLE IF EXISTS regressuser1;
-DROP ROLE IF EXISTS regressuser2;
-DROP ROLE IF EXISTS regressuser3;
-DROP ROLE IF EXISTS regressuser4;
-DROP ROLE IF EXISTS regressuser5;
-DROP ROLE IF EXISTS regressuser6;
-SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
- lo_unlink
------------
-(0 rows)
-
-RESET client_min_messages;
--- test proper begins here
-CREATE USER regressuser1;
-CREATE USER regressuser2;
-CREATE USER regressuser3;
-CREATE USER regressuser4;
-CREATE USER regressuser5;
-CREATE USER regressuser5; -- duplicate
-ERROR: role "regressuser5" already exists
-CREATE GROUP regressgroup1;
-CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2;
-ALTER GROUP regressgroup1 ADD USER regressuser4;
-ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate
-NOTICE: role "regressuser2" is already a member of role "regressgroup2"
-ALTER GROUP regressgroup2 DROP USER regressuser2;
-GRANT regressgroup2 TO regressuser4 WITH ADMIN OPTION;
--- test owner privileges
-SET SESSION AUTHORIZATION regressuser1;
-SELECT session_user, current_user;
- session_user | current_user
---------------+--------------
- regressuser1 | regressuser1
-(1 row)
-
-CREATE TABLE atest1 ( a int, b text );
-SELECT * FROM atest1;
- a | b
----+---
-(0 rows)
-
-INSERT INTO atest1 VALUES (1, 'one');
-DELETE FROM atest1;
-UPDATE atest1 SET a = 1 WHERE b = 'blech';
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-TRUNCATE atest1;
-BEGIN;
-LOCK atest1 IN ACCESS EXCLUSIVE MODE;
-COMMIT;
-REVOKE ALL ON atest1 FROM PUBLIC;
-SELECT * FROM atest1;
- a | b
----+---
-(0 rows)
-
-GRANT ALL ON atest1 TO regressuser2;
-GRANT SELECT ON atest1 TO regressuser3, regressuser4;
-SELECT * FROM atest1;
- a | b
----+---
-(0 rows)
-
-CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
-GRANT SELECT ON atest2 TO regressuser2;
-GRANT UPDATE ON atest2 TO regressuser3;
-GRANT INSERT ON atest2 TO regressuser4;
-GRANT TRUNCATE ON atest2 TO regressuser5;
-SET SESSION AUTHORIZATION regressuser2;
-SELECT session_user, current_user;
- session_user | current_user
---------------+--------------
- regressuser2 | regressuser2
-(1 row)
-
--- try various combinations of queries on atest1 and atest2
-SELECT * FROM atest1; -- ok
- a | b
----+---
-(0 rows)
-
-SELECT * FROM atest2; -- ok
- col1 | col2
-------+------
-(0 rows)
-
-INSERT INTO atest1 VALUES (2, 'two'); -- ok
-INSERT INTO atest2 VALUES ('foo', true); -- fail
-ERROR: permission denied for relation atest2
-INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok
-UPDATE atest1 SET a = 1 WHERE a = 2; -- ok
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-UPDATE atest2 SET col2 = NOT col2; -- fail
-ERROR: permission denied for relation atest2
-SELECT * FROM atest1 ORDER BY 1 FOR UPDATE; -- ok
- a | b
----+-----
- 1 | two
- 2 | two
-(2 rows)
-
-SELECT * FROM atest2 ORDER BY 1 FOR UPDATE; -- fail
-ERROR: permission denied for relation atest2
-DELETE FROM atest2; -- fail
-ERROR: permission denied for relation atest2
-TRUNCATE atest2; -- fail
-ERROR: permission denied for relation atest2
-BEGIN;
-LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
-ERROR: permission denied for relation atest2
-COMMIT;
-COPY atest2 FROM stdin; -- fail
-ERROR: permission denied for relation atest2
-GRANT ALL ON atest1 TO PUBLIC; -- fail
-WARNING: no privileges were granted for "atest1"
--- checks in subquery, both ok
-SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
- a | b
----+---
-(0 rows)
-
-SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) );
- col1 | col2
-------+------
-(0 rows)
-
-SET SESSION AUTHORIZATION regressuser3;
-SELECT session_user, current_user;
- session_user | current_user
---------------+--------------
- regressuser3 | regressuser3
-(1 row)
-
-SELECT * FROM atest1 ORDER BY 1; -- ok
- a | b
----+-----
- 1 | two
- 2 | two
-(2 rows)
-
-SELECT * FROM atest2; -- fail
-ERROR: permission denied for relation atest2
-INSERT INTO atest1 VALUES (2, 'two'); -- fail
-ERROR: permission denied for relation atest1
-INSERT INTO atest2 VALUES ('foo', true); -- fail
-ERROR: permission denied for relation atest2
-INSERT INTO atest1 SELECT 1, b FROM atest1; -- fail
-ERROR: permission denied for relation atest1
-UPDATE atest1 SET a = 1 WHERE a = 2; -- fail
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-UPDATE atest2 SET col2 = NULL; -- ok
-UPDATE atest2 SET col2 = NOT col2; -- fails; requires SELECT on atest2
-ERROR: permission denied for relation atest2
-UPDATE atest2 SET col2 = true FROM atest1 WHERE atest1.a = 5; -- ok
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM atest1 FOR UPDATE; -- fail
-ERROR: permission denied for relation atest1
-SELECT * FROM atest2 FOR UPDATE; -- fail
-ERROR: permission denied for relation atest2
-DELETE FROM atest2; -- fail
-ERROR: permission denied for relation atest2
-TRUNCATE atest2; -- fail
-ERROR: permission denied for relation atest2
-BEGIN;
-LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
-COMMIT;
-COPY atest2 FROM stdin; -- fail
-ERROR: permission denied for relation atest2
--- checks in subquery, both fail
-SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
-ERROR: permission denied for relation atest2
-SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) );
-ERROR: permission denied for relation atest2
-SET SESSION AUTHORIZATION regressuser4;
-COPY atest2 FROM stdin; -- ok
-SELECT * FROM atest1 ORDER BY 1; -- ok
- a | b
----+-----
- 1 | two
- 2 | two
-(2 rows)
-
--- groups
-SET SESSION AUTHORIZATION regressuser3;
-CREATE TABLE atest3 (one int, two int, three int);
-GRANT DELETE ON atest3 TO GROUP regressgroup2;
-SET SESSION AUTHORIZATION regressuser1;
-SELECT * FROM atest3; -- fail
-ERROR: permission denied for relation atest3
-DELETE FROM atest3; -- ok
--- views
-SET SESSION AUTHORIZATION regressuser3;
-CREATE VIEW atestv1 AS SELECT * FROM atest1; -- ok
-/* The next *should* fail, but it's not implemented that way yet. */
-CREATE VIEW atestv2 AS SELECT * FROM atest2;
-CREATE VIEW atestv3 AS SELECT * FROM atest3; -- ok
-/* Empty view is a corner case that failed in 9.2. */
-CREATE VIEW atestv0 AS SELECT 0 as x WHERE false; -- ok
-SELECT * FROM atestv1; -- ok
- a | b
----+-----
- 2 | two
- 1 | two
-(2 rows)
-
-SELECT * FROM atestv2; -- fail
-ERROR: permission denied for relation atest2
-GRANT SELECT ON atestv1, atestv3 TO regressuser4;
-GRANT SELECT ON atestv2 TO regressuser2;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT * FROM atestv1; -- ok
- a | b
----+-----
- 2 | two
- 1 | two
-(2 rows)
-
-SELECT * FROM atestv2; -- fail
-ERROR: permission denied for relation atestv2
-SELECT * FROM atestv3; -- fail due to issue 3520503, see above
- one | two | three
------+-----+-------
-(0 rows)
-
-SELECT * FROM atestv0; -- fail
-ERROR: permission denied for relation atestv0
--- Appendrels excluded by constraints failed to check permissions in 8.4-9.2.
-select * from
- ((select a.q1 as x from int8_tbl a offset 0)
- union all
- (select b.q2 as x from int8_tbl b offset 0)) ss
-where false;
-ERROR: permission denied for relation int8_tbl
-set constraint_exclusion = on;
-select * from
- ((select a.q1 as x, random() from int8_tbl a where q1 > 0)
- union all
- (select b.q2 as x, random() from int8_tbl b where q2 > 0)) ss
-where x < 0;
-ERROR: permission denied for relation int8_tbl
-reset constraint_exclusion;
-CREATE VIEW atestv4 AS SELECT * FROM atestv3; -- nested view
-SELECT * FROM atestv4; -- fail due to issue 3520503, see above
- one | two | three
------+-----+-------
-(0 rows)
-
-GRANT SELECT ON atestv4 TO regressuser2;
-SET SESSION AUTHORIZATION regressuser2;
--- Two complex cases:
-SELECT * FROM atestv3; -- fail
-ERROR: permission denied for relation atestv3
--- fail due to issue 3520503, see above
-SELECT * FROM atestv4; -- ok (even though regressuser2 cannot access underlying atestv3)
- one | two | three
------+-----+-------
-(0 rows)
-
-SELECT * FROM atest2; -- ok
- col1 | col2
-------+------
- bar | t
-(1 row)
-
-SELECT * FROM atestv2; -- fail (even though regressuser2 can access underlying atest2)
-ERROR: permission denied for relation atest2
--- Test column level permissions
-SET SESSION AUTHORIZATION regressuser1;
-CREATE TABLE atest5 (one int, two int unique, three int, four int unique);
-CREATE TABLE atest6 (one int, two int, blue int);
-GRANT SELECT (one), INSERT (two), UPDATE (three) ON atest5 TO regressuser4;
-GRANT ALL (one) ON atest5 TO regressuser3;
-INSERT INTO atest5 VALUES (1,2,3);
-SET SESSION AUTHORIZATION regressuser4;
-SELECT * FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-SELECT one FROM atest5; -- ok
- one
------
- 1
-(1 row)
-
-COPY atest5 (one) TO stdout; -- ok
-1
-SELECT two FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-COPY atest5 (two) TO stdout; -- fail
-ERROR: permission denied for relation atest5
-SELECT atest5 FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-COPY atest5 (one,two) TO stdout; -- fail
-ERROR: permission denied for relation atest5
-SELECT 1 FROM atest5; -- ok
- ?column?
-----------
- 1
-(1 row)
-
-SELECT 1 FROM atest5 a JOIN atest5 b USING (one); -- ok
- ?column?
-----------
- 1
-(1 row)
-
-SELECT 1 FROM atest5 a JOIN atest5 b USING (two); -- fail
-ERROR: permission denied for relation atest5
-SELECT 1 FROM atest5 a NATURAL JOIN atest5 b; -- fail
-ERROR: permission denied for relation atest5
-SELECT (j.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)) j; -- fail
-ERROR: permission denied for relation atest5
-SELECT 1 FROM atest5 WHERE two = 2; -- fail
-ERROR: permission denied for relation atest5
-SELECT * FROM atest1, atest5; -- fail
-ERROR: permission denied for relation atest5
-SELECT atest1.* FROM atest1, atest5; -- ok
- a | b
----+-----
- 2 | two
- 1 | two
-(2 rows)
-
-SELECT atest1.*,atest5.one FROM atest1, atest5; -- ok
- a | b | one
----+-----+-----
- 2 | two | 1
- 1 | two | 1
-(2 rows)
-
-SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.two); -- fail
-ERROR: permission denied for relation atest5
-SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.one); -- ok
- a | b | one
----+-----+-----
- 1 | two | 1
-(1 row)
-
-SELECT one, two FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-SET SESSION AUTHORIZATION regressuser1;
-GRANT SELECT (one,two) ON atest6 TO regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT one, two FROM atest5 NATURAL JOIN atest6; -- fail still
-ERROR: permission denied for relation atest5
-SET SESSION AUTHORIZATION regressuser1;
-GRANT SELECT (two) ON atest5 TO regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT one, two FROM atest5 NATURAL JOIN atest6; -- ok now
- one | two
------+-----
-(0 rows)
-
--- test column-level privileges for INSERT and UPDATE
-INSERT INTO atest5 (two) VALUES (3); -- fail due to issue 3520503, see above
-COPY atest5 FROM stdin; -- fail
-ERROR: permission denied for relation atest5
-COPY atest5 (two) FROM stdin; -- ok
-INSERT INTO atest5 (three) VALUES (4); -- fail
-ERROR: permission denied for relation atest5
-INSERT INTO atest5 VALUES (5,5,5); -- fail
-ERROR: permission denied for relation atest5
-UPDATE atest5 SET three = 10; -- ok
-UPDATE atest5 SET one = 8; -- fail
-ERROR: permission denied for relation atest5
-UPDATE atest5 SET three = 5, one = 2; -- fail
-ERROR: permission denied for relation atest5
--- Check that column level privs are enforced in RETURNING
--- Ok.
-INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10;
--- Error. No SELECT on column three.
-INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10 RETURNING atest5.three;
-ERROR: permission denied for relation atest5
--- Ok. May SELECT on column "one":
-INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10 RETURNING atest5.one;
- one
------
-
-(1 row)
-
--- Check that column level privileges are enforced for EXCLUDED
--- Ok. we may select one
-INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = EXCLUDED.one;
--- Error. No select rights on three
-INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = EXCLUDED.three;
-ERROR: permission denied for relation atest5
-INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set one = 8; -- fails (due to UPDATE)
-ERROR: permission denied for relation atest5
-INSERT INTO atest5(three) VALUES (4) ON CONFLICT (two) DO UPDATE set three = 10; -- fails (due to INSERT)
-ERROR: permission denied for relation atest5
--- Check that the the columns in the inference require select privileges
--- Error. No privs on four
-INSERT INTO atest5(three) VALUES (4) ON CONFLICT (four) DO UPDATE set three = 10;
-ERROR: permission denied for relation atest5
-SET SESSION AUTHORIZATION regressuser1;
-REVOKE ALL (one) ON atest5 FROM regressuser4;
-GRANT SELECT (one,two,blue) ON atest6 TO regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT one FROM atest5; -- fail
-ERROR: permission denied for relation atest5
-UPDATE atest5 SET one = 1; -- fail
-ERROR: permission denied for relation atest5
-SELECT atest6 FROM atest6; -- ok
- atest6
---------
-(0 rows)
-
-COPY atest6 TO stdout; -- ok
--- check error reporting with column privs
-SET SESSION AUTHORIZATION regressuser1;
-CREATE TABLE t1 (c1 int, c2 int, c3 int check (c3 < 5), primary key (c1, c2));
-GRANT SELECT (c1) ON t1 TO regressuser2;
-GRANT INSERT (c1, c2, c3) ON t1 TO regressuser2;
-GRANT UPDATE (c1, c2, c3) ON t1 TO regressuser2;
--- seed data
-INSERT INTO t1 VALUES (1, 1, 1);
-INSERT INTO t1 VALUES (1, 2, 1);
-INSERT INTO t1 VALUES (2, 1, 2);
-INSERT INTO t1 VALUES (2, 2, 2);
-INSERT INTO t1 VALUES (3, 1, 3);
-SET SESSION AUTHORIZATION regressuser2;
-INSERT INTO t1 (c1, c2) VALUES (1, 1); -- fail, but row not shown
-ERROR: duplicate key value violates unique constraint "t1_pkey"
-UPDATE t1 SET c2 = 1; -- fail, but row not shown
-ERROR: duplicate key value violates unique constraint "t1_pkey"
-INSERT INTO t1 (c1, c2) VALUES (null, null); -- fail, but see columns being inserted
-ERROR: null value in column "c1" violates not-null constraint
-DETAIL: Failing row contains (c1, c2) = (null, null).
-INSERT INTO t1 (c3) VALUES (null); -- fail, but see columns being inserted or have SELECT
-ERROR: null value in column "c1" violates not-null constraint
-DETAIL: Failing row contains (c1, c3) = (null, null).
-INSERT INTO t1 (c1) VALUES (5); -- fail, but see columns being inserted or have SELECT
-ERROR: null value in column "c2" violates not-null constraint
-DETAIL: Failing row contains (c1) = (5).
-UPDATE t1 SET c3 = 10; -- fail, but see columns with SELECT rights, or being modified
-ERROR: new row for relation "t1" violates check constraint "t1_c3_check"
-DETAIL: Failing row contains (c1, c3) = (1, 10).
-SET SESSION AUTHORIZATION regressuser1;
-DROP TABLE t1;
--- test column-level privileges when involved with DELETE
-SET SESSION AUTHORIZATION regressuser1;
-ALTER TABLE atest6 ADD COLUMN three integer;
-GRANT DELETE ON atest5 TO regressuser3;
-GRANT SELECT (two) ON atest5 TO regressuser3;
-REVOKE ALL (one) ON atest5 FROM regressuser3;
-GRANT SELECT (one) ON atest5 TO regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT atest6 FROM atest6; -- fail
-ERROR: permission denied for relation atest6
-SELECT one FROM atest5 NATURAL JOIN atest6; -- fail
-ERROR: permission denied for relation atest5
-SET SESSION AUTHORIZATION regressuser1;
-ALTER TABLE atest6 DROP COLUMN three;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT atest6 FROM atest6; -- ok
- atest6
---------
-(0 rows)
-
-SELECT one FROM atest5 NATURAL JOIN atest6; -- ok
- one
------
-(0 rows)
-
-SET SESSION AUTHORIZATION regressuser1;
-ALTER TABLE atest6 DROP COLUMN two;
-REVOKE SELECT (one,blue) ON atest6 FROM regressuser4;
-SET SESSION AUTHORIZATION regressuser4;
-SELECT * FROM atest6; -- fail
-ERROR: permission denied for relation atest6
-SELECT 1 FROM atest6; -- fail
-ERROR: permission denied for relation atest6
-SET SESSION AUTHORIZATION regressuser3;
-DELETE FROM atest5 WHERE one = 1; -- fail
-ERROR: permission denied for relation atest5
-DELETE FROM atest5 WHERE two = 2; -- ok
--- check inheritance cases
-SET SESSION AUTHORIZATION regressuser1;
-CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS;
-CREATE TABLE atestp2 (fx int, fy int) WITH OIDS;
-CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2);
-GRANT SELECT(fx,fy,oid) ON atestp2 TO regressuser2;
-GRANT SELECT(fx) ON atestc TO regressuser2;
-SET SESSION AUTHORIZATION regressuser2;
-SELECT fx FROM atestp2; -- ok
- fx
-----
-(0 rows)
-
-SELECT fy FROM atestp2; -- fail due to issue 3520503, see above
- fy
-----
-(0 rows)
-
-SELECT atestp2 FROM atestp2; -- fail due to issue 3520503, see above
- atestp2
----------
-(0 rows)
-
-SELECT oid FROM atestp2; -- fail due to issue 3520503, see above
- oid
------
-(0 rows)
-
-SELECT fy FROM atestc; -- fail
-ERROR: permission denied for relation atestc
-SET SESSION AUTHORIZATION regressuser1;
-GRANT SELECT(fy,oid) ON atestc TO regressuser2;
-SET SESSION AUTHORIZATION regressuser2;
-SELECT fx FROM atestp2; -- still ok
- fx
-----
-(0 rows)
-
-SELECT fy FROM atestp2; -- ok
- fy
-----
-(0 rows)
-
-SELECT atestp2 FROM atestp2; -- fail due to issue 3520503, see above
- atestp2
----------
-(0 rows)
-
-SELECT oid FROM atestp2; -- ok
- oid
------
-(0 rows)
-
--- privileges on functions, languages
--- switch to superuser
-\c -
-REVOKE ALL PRIVILEGES ON LANGUAGE sql FROM PUBLIC;
-GRANT USAGE ON LANGUAGE sql TO regressuser1; -- ok
-GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail
-ERROR: language "c" is not trusted
-HINT: Only superusers can use untrusted languages.
-SET SESSION AUTHORIZATION regressuser1;
-GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
-WARNING: no privileges were granted for "sql"
-CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
-CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
-REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC;
-GRANT EXECUTE ON FUNCTION testfunc1(int), testfunc2(int) TO regressuser2;
-GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error
-ERROR: invalid privilege type USAGE for function
-GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4;
-GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regressuser4;
-ERROR: function testfunc_nosuch(integer) does not exist
-CREATE FUNCTION testfunc4(boolean) RETURNS text
- AS 'select col1 from atest2 where col2 = $1;'
- LANGUAGE sql SECURITY DEFINER;
-GRANT EXECUTE ON FUNCTION testfunc4(boolean) TO regressuser3;
-SET SESSION AUTHORIZATION regressuser2;
-SELECT testfunc1(5), testfunc2(5); -- ok
- testfunc1 | testfunc2
------------+-----------
- 10 | 15
-(1 row)
-
-CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
-ERROR: permission denied for language sql
-SET SESSION AUTHORIZATION regressuser3;
-SELECT testfunc1(5); -- fail
-ERROR: permission denied for function testfunc1
-SELECT col1 FROM atest2 WHERE col2 = true; -- fail
-ERROR: permission denied for relation atest2
-SELECT testfunc4(true); -- fail due to issue 3520503, see above
-ERROR: permission denied for relation atest2
-CONTEXT: SQL function "testfunc4" statement 1
-SET SESSION AUTHORIZATION regressuser4;
-SELECT testfunc1(5); -- ok
- testfunc1
------------
- 10
-(1 row)
-
-DROP FUNCTION testfunc1(int); -- fail
-ERROR: must be owner of function testfunc1
-\c -
-DROP FUNCTION testfunc1(int); -- ok
--- restore to sanity
-GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
--- privileges on types
--- switch to superuser
-\c -
-CREATE TYPE testtype1 AS (a int, b text);
-REVOKE USAGE ON TYPE testtype1 FROM PUBLIC;
-GRANT USAGE ON TYPE testtype1 TO regressuser2;
-GRANT USAGE ON TYPE _testtype1 TO regressuser2; -- fail
-ERROR: cannot set privileges of array types
-HINT: Set the privileges of the element type instead.
-GRANT USAGE ON DOMAIN testtype1 TO regressuser2; -- fail
-ERROR: "testtype1" is not a domain
-CREATE DOMAIN testdomain1 AS int;
-REVOKE USAGE on DOMAIN testdomain1 FROM PUBLIC;
-GRANT USAGE ON DOMAIN testdomain1 TO regressuser2;
-GRANT USAGE ON TYPE testdomain1 TO regressuser2; -- ok
-SET SESSION AUTHORIZATION regressuser1;
--- commands that should fail
-CREATE AGGREGATE testagg1a(testdomain1) (sfunc = int4_sum, stype = bigint);
-ERROR: permission denied for type testdomain1
-CREATE DOMAIN testdomain2a AS testdomain1;
-ERROR: permission denied for type testdomain1
-CREATE DOMAIN testdomain3a AS int;
-CREATE FUNCTION castfunc(int) RETURNS testdomain3a AS $$ SELECT $1::testdomain3a $$ LANGUAGE SQL;
-CREATE CAST (testdomain1 AS testdomain3a) WITH FUNCTION castfunc(int);
-ERROR: permission denied for type testdomain1
-DROP FUNCTION castfunc(int) CASCADE;
-DROP DOMAIN testdomain3a;
-CREATE FUNCTION testfunc5a(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
-ERROR: permission denied for type testdomain1
-CREATE FUNCTION testfunc6a(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$;
-ERROR: permission denied for type testdomain1
-CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = testdomain1, RIGHTARG = testdomain1);
-ERROR: permission denied for type testdomain1
-CREATE TABLE test5a (a int, b testdomain1);
-ERROR: permission denied for type testdomain1
-CREATE TABLE test6a OF testtype1;
-ERROR: permission denied for type testtype1
-CREATE TABLE test10a (a int[], b testtype1[]);
-ERROR: permission denied for type testtype1
-CREATE TABLE test9a (a int, b int);
-ALTER TABLE test9a ADD COLUMN c testdomain1;
-ERROR: permission denied for type testdomain1
-ALTER TABLE test9a ALTER COLUMN b TYPE testdomain1;
-ERROR: permission denied for type testdomain1
-CREATE TYPE test7a AS (a int, b testdomain1);
-ERROR: permission denied for type testdomain1
-CREATE TYPE test8a AS (a int, b int);
-ALTER TYPE test8a ADD ATTRIBUTE c testdomain1;
-ERROR: permission denied for type testdomain1
-ALTER TYPE test8a ALTER ATTRIBUTE b TYPE testdomain1;
-ERROR: permission denied for type testdomain1
-CREATE TABLE test11a AS (SELECT 1::testdomain1 AS a);
-ERROR: permission denied for type testdomain1
-REVOKE ALL ON TYPE testtype1 FROM PUBLIC;
-ERROR: permission denied for type testtype1
-SET SESSION AUTHORIZATION regressuser2;
--- commands that should succeed
-CREATE AGGREGATE testagg1b(testdomain1) (sfunc = int4_sum, stype = bigint);
-CREATE DOMAIN testdomain2b AS testdomain1;
-CREATE DOMAIN testdomain3b AS int;
-CREATE FUNCTION castfunc(int) RETURNS testdomain3b AS $$ SELECT $1::testdomain3b $$ LANGUAGE SQL;
-CREATE CAST (testdomain1 AS testdomain3b) WITH FUNCTION castfunc(int);
-WARNING: cast will be ignored because the source data type is a domain
-CREATE FUNCTION testfunc5b(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
-CREATE FUNCTION testfunc6b(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$;
-CREATE OPERATOR !! (PROCEDURE = testfunc5b, RIGHTARG = testdomain1);
-CREATE TABLE test5b (a int, b testdomain1);
-CREATE TABLE test6b OF testtype1;
-CREATE TABLE test10b (a int[], b testtype1[]);
-CREATE TABLE test9b (a int, b int);
-ALTER TABLE test9b ADD COLUMN c testdomain1;
-ALTER TABLE test9b ALTER COLUMN b TYPE testdomain1;
-CREATE TYPE test7b AS (a int, b testdomain1);
-CREATE TYPE test8b AS (a int, b int);
-ALTER TYPE test8b ADD ATTRIBUTE c testdomain1;
-ALTER TYPE test8b ALTER ATTRIBUTE b TYPE testdomain1;
-CREATE TABLE test11b AS (SELECT 1::testdomain1 AS a);
-REVOKE ALL ON TYPE testtype1 FROM PUBLIC;
-WARNING: no privileges could be revoked for "testtype1"
-\c -
-DROP AGGREGATE testagg1b(testdomain1);
-DROP DOMAIN testdomain2b;
-DROP OPERATOR !! (NONE, testdomain1);
-DROP FUNCTION testfunc5b(a testdomain1);
-DROP FUNCTION testfunc6b(b int);
-DROP TABLE test5b;
-DROP TABLE test6b;
-DROP TABLE test9b;
-DROP TABLE test10b;
-DROP TYPE test7b;
-DROP TYPE test8b;
-DROP CAST (testdomain1 AS testdomain3b);
-DROP FUNCTION castfunc(int) CASCADE;
-DROP DOMAIN testdomain3b;
-DROP TABLE test11b;
-DROP TYPE testtype1; -- ok
-DROP DOMAIN testdomain1; -- ok
--- truncate
-SET SESSION AUTHORIZATION regressuser5;
-TRUNCATE atest2; -- ok
-TRUNCATE atest3; -- fail
-ERROR: permission denied for relation atest3
--- has_table_privilege function
--- bad-input checks
-select has_table_privilege(NULL,'pg_authid','select');
- has_table_privilege
----------------------
-
-(1 row)
-
-select has_table_privilege('pg_shad','select');
-ERROR: relation "pg_shad" does not exist
-select has_table_privilege('nosuchuser','pg_authid','select');
-ERROR: role "nosuchuser" does not exist
-select has_table_privilege('pg_authid','sel');
-ERROR: unrecognized privilege type: "sel"
-select has_table_privilege(-999999,'pg_authid','update');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(1,'select');
- has_table_privilege
----------------------
-
-(1 row)
-
--- superuser
-\c -
-select has_table_privilege(current_user,'pg_authid','select');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(current_user,'pg_authid','insert');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,'pg_authid','update')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,'pg_authid','delete')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
--- 'rule' privilege no longer exists, but for backwards compatibility
--- has_table_privilege still recognizes the keyword and says FALSE
-select has_table_privilege(current_user,t1.oid,'rule')
-from (select oid from pg_class where relname = 'pg_authid') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(current_user,t1.oid,'references')
-from (select oid from pg_class where relname = 'pg_authid') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_authid') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'insert')
-from (select oid from pg_class where relname = 'pg_authid') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege('pg_authid','update');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege('pg_authid','delete');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege('pg_authid','truncate');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_authid') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t1.oid,'trigger')
-from (select oid from pg_class where relname = 'pg_authid') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
--- non-superuser
-SET SESSION AUTHORIZATION regressuser3;
-select has_table_privilege(current_user,'pg_class','select');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(current_user,'pg_class','insert');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,'pg_class','update')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,'pg_class','delete')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(current_user,t1.oid,'references')
-from (select oid from pg_class where relname = 'pg_class') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_class') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'insert')
-from (select oid from pg_class where relname = 'pg_class') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('pg_class','update');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('pg_class','delete');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('pg_class','truncate');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_class') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t1.oid,'trigger')
-from (select oid from pg_class where relname = 'pg_class') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(current_user,'atest1','select');
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(current_user,'atest1','insert');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,'atest1','update')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,'atest1','delete')
-from (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(current_user,t1.oid,'references')
-from (select oid from pg_class where relname = 'atest1') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'select')
-from (select oid from pg_class where relname = 'atest1') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t2.oid,t1.oid,'insert')
-from (select oid from pg_class where relname = 'atest1') as t1,
- (select oid from pg_roles where rolname = current_user) as t2;
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('atest1','update');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('atest1','delete');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege('atest1','truncate');
- has_table_privilege
----------------------
- f
-(1 row)
-
-select has_table_privilege(t1.oid,'select')
-from (select oid from pg_class where relname = 'atest1') as t1;
- has_table_privilege
----------------------
- t
-(1 row)
-
-select has_table_privilege(t1.oid,'trigger')
-from (select oid from pg_class where relname = 'atest1') as t1;
- has_table_privilege
----------------------
- f
-(1 row)
-
--- Grant options
-SET SESSION AUTHORIZATION regressuser1;
-CREATE TABLE atest4 (a int);
-GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION;
-GRANT UPDATE ON atest4 TO regressuser2;
-GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION;
-SET SESSION AUTHORIZATION regressuser2;
-GRANT SELECT ON atest4 TO regressuser3;
-GRANT UPDATE ON atest4 TO regressuser3; -- fail
-WARNING: no privileges were granted for "atest4"
-SET SESSION AUTHORIZATION regressuser1;
-REVOKE SELECT ON atest4 FROM regressuser3; -- does nothing
-SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
-REVOKE SELECT ON atest4 FROM regressuser2; -- fail
-ERROR: dependent privileges exist
-HINT: Use CASCADE to revoke them too.
-REVOKE GRANT OPTION FOR SELECT ON atest4 FROM regressuser2 CASCADE; -- ok
-SELECT has_table_privilege('regressuser2', 'atest4', 'SELECT'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- false
- has_table_privilege
----------------------
- f
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'atest4', 'SELECT WITH GRANT OPTION'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
--- Admin options
-SET SESSION AUTHORIZATION regressuser4;
-CREATE FUNCTION dogrant_ok() RETURNS void LANGUAGE sql SECURITY DEFINER AS
- 'GRANT regressgroup2 TO regressuser5';
-GRANT regressgroup2 TO regressuser5; -- ok: had ADMIN OPTION
-SET ROLE regressgroup2;
-GRANT regressgroup2 TO regressuser5; -- fails: SET ROLE suspended privilege
-ERROR: must have admin option on role "regressgroup2"
-SET SESSION AUTHORIZATION regressuser1;
-GRANT regressgroup2 TO regressuser5; -- fails: no ADMIN OPTION
-ERROR: must have admin option on role "regressgroup2"
-SELECT dogrant_ok(); -- ok: SECURITY DEFINER conveys ADMIN
-NOTICE: role "regressuser5" is already a member of role "regressgroup2"
-CONTEXT: SQL function "dogrant_ok" statement 1
-ERROR: must have admin option on role "regressgroup2"
-CONTEXT: SQL function "dogrant_ok" statement 1
-SET ROLE regressgroup2;
-GRANT regressgroup2 TO regressuser5; -- fails: SET ROLE did not help
-ERROR: must have admin option on role "regressgroup2"
-SET SESSION AUTHORIZATION regressgroup2;
-GRANT regressgroup2 TO regressuser5; -- ok: a role can self-admin
-NOTICE: role "regressuser5" is already a member of role "regressgroup2"
-CREATE FUNCTION dogrant_fails() RETURNS void LANGUAGE sql SECURITY DEFINER AS
- 'GRANT regressgroup2 TO regressuser5';
-SELECT dogrant_fails(); -- fails: no self-admin in SECURITY DEFINER
-ERROR: must have admin option on role "regressgroup2"
-CONTEXT: SQL function "dogrant_fails" statement 1
-DROP FUNCTION dogrant_fails();
-SET SESSION AUTHORIZATION regressuser4;
-DROP FUNCTION dogrant_ok();
-REVOKE regressgroup2 FROM regressuser5;
--- has_sequence_privilege tests
-\c -
-CREATE SEQUENCE x_seq;
-GRANT USAGE on x_seq to regressuser2;
-SELECT has_sequence_privilege('regressuser1', 'atest1', 'SELECT');
-ERROR: "atest1" is not a sequence
-SELECT has_sequence_privilege('regressuser1', 'x_seq', 'INSERT');
-ERROR: unrecognized privilege type: "INSERT"
-SELECT has_sequence_privilege('regressuser1', 'x_seq', 'SELECT');
- has_sequence_privilege
-------------------------
- f
-(1 row)
-
-SET SESSION AUTHORIZATION regressuser2;
-SELECT has_sequence_privilege('x_seq', 'USAGE');
- has_sequence_privilege
-------------------------
- t
-(1 row)
-
--- largeobject privilege tests
-\c -
-SET SESSION AUTHORIZATION regressuser1;
-SELECT lo_create(1001);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_create(1002);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_create(1003);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_create(1004);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_create(1005);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-GRANT ALL ON LARGE OBJECT 1001 TO PUBLIC;
-ERROR: large object 1001 does not exist
-GRANT SELECT ON LARGE OBJECT 1003 TO regressuser2;
-ERROR: large object 1003 does not exist
-GRANT SELECT,UPDATE ON LARGE OBJECT 1004 TO regressuser2;
-ERROR: large object 1004 does not exist
-GRANT ALL ON LARGE OBJECT 1005 TO regressuser2;
-ERROR: large object 1005 does not exist
-GRANT SELECT ON LARGE OBJECT 1005 TO regressuser2 WITH GRANT OPTION;
-ERROR: large object 1005 does not exist
-GRANT SELECT, INSERT ON LARGE OBJECT 1001 TO PUBLIC; -- to be failed
-ERROR: large object 1001 does not exist
-GRANT SELECT, UPDATE ON LARGE OBJECT 1001 TO nosuchuser; -- to be failed
-ERROR: large object 1001 does not exist
-GRANT SELECT, UPDATE ON LARGE OBJECT 999 TO PUBLIC; -- to be failed
-ERROR: large object 999 does not exist
-\c -
-SET SESSION AUTHORIZATION regressuser2;
-SELECT lo_create(2001);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_create(2002);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1001, x'40000'::int), 32);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1003, x'40000'::int), 32);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1004, x'40000'::int), 32);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1001, x'20000'::int), 'abcd');
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1003, x'20000'::int), 'abcd'); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1004, x'20000'::int), 'abcd');
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-GRANT SELECT ON LARGE OBJECT 1005 TO regressuser3;
-ERROR: large object 1005 does not exist
-GRANT UPDATE ON LARGE OBJECT 1006 TO regressuser3; -- to be denied
-ERROR: large object 1006 does not exist
-REVOKE ALL ON LARGE OBJECT 2001, 2002 FROM PUBLIC;
-ERROR: large object 2001 does not exist
-GRANT ALL ON LARGE OBJECT 2001 TO regressuser3;
-ERROR: large object 2001 does not exist
-SELECT lo_unlink(1001); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_unlink(2002);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-\c -
--- confirm ACL setting
-SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata;
- oid | ownername | lomacl
------+-----------+--------
-(0 rows)
-
-SET SESSION AUTHORIZATION regressuser3;
-SELECT loread(lo_open(1001, x'40000'::int), 32);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1003, x'40000'::int), 32); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT loread(lo_open(1005, x'40000'::int), 32);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_truncate(lo_open(1005, x'20000'::int), 10); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_truncate(lo_open(2001, x'20000'::int), 10);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
--- compatibility mode in largeobject permission
-\c -
-SET lo_compat_privileges = false; -- default setting
-SET SESSION AUTHORIZATION regressuser4;
-SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_unlink(1002); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_export(1001, '/dev/null'); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-\c -
-SET lo_compat_privileges = true; -- compatibility mode
-SET SESSION AUTHORIZATION regressuser4;
-SELECT loread(lo_open(1002, x'40000'::int), 32);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd');
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_truncate(lo_open(1002, x'20000'::int), 10);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_unlink(1002);
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
-SELECT lo_export(1001, '/dev/null'); -- to be denied
-ERROR: Postgres-XL does not yet support large objects
-DETAIL: The feature is not currently supported
--- don't allow unpriv users to access pg_largeobject contents
-\c -
-SELECT * FROM pg_largeobject LIMIT 0;
- loid | pageno | data
-------+--------+------
-(0 rows)
-
-SET SESSION AUTHORIZATION regressuser1;
-SELECT * FROM pg_largeobject LIMIT 0; -- to be denied
-ERROR: permission denied for relation pg_largeobject
--- test default ACLs
-\c -
-CREATE SCHEMA testns;
-GRANT ALL ON SCHEMA testns TO regressuser1;
-CREATE TABLE testns.acltest1 (x int);
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT SELECT ON TABLES TO public;
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-DROP TABLE testns.acltest1;
-CREATE TABLE testns.acltest1 (x int);
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- yes
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT INSERT ON TABLES TO regressuser1;
-DROP TABLE testns.acltest1;
-CREATE TABLE testns.acltest1 (x int);
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- yes
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- yes
- has_table_privilege
----------------------
- t
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns REVOKE INSERT ON TABLES FROM regressuser1;
-DROP TABLE testns.acltest1;
-CREATE TABLE testns.acltest1 (x int);
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'SELECT'); -- yes
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.acltest1', 'INSERT'); -- no
- has_table_privilege
----------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES FOR ROLE regressuser1 REVOKE EXECUTE ON FUNCTIONS FROM public;
-SET ROLE regressuser1;
-CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql;
-SELECT has_function_privilege('regressuser2', 'testns.foo()', 'EXECUTE'); -- no
- has_function_privilege
-------------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT EXECUTE ON FUNCTIONS to public;
-DROP FUNCTION testns.foo();
-CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql;
-SELECT has_function_privilege('regressuser2', 'testns.foo()', 'EXECUTE'); -- yes
- has_function_privilege
-------------------------
- t
-(1 row)
-
-DROP FUNCTION testns.foo();
-ALTER DEFAULT PRIVILEGES FOR ROLE regressuser1 REVOKE USAGE ON TYPES FROM public;
-CREATE DOMAIN testns.testdomain1 AS int;
-SELECT has_type_privilege('regressuser2', 'testns.testdomain1', 'USAGE'); -- no
- has_type_privilege
---------------------
- f
-(1 row)
-
-ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON TYPES to public;
-DROP DOMAIN testns.testdomain1;
-CREATE DOMAIN testns.testdomain1 AS int;
-SELECT has_type_privilege('regressuser2', 'testns.testdomain1', 'USAGE'); -- yes
- has_type_privilege
---------------------
- t
-(1 row)
-
-DROP DOMAIN testns.testdomain1;
-RESET ROLE;
-SELECT count(*)
- FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
- WHERE nspname = 'testns';
- count
--------
- 3
-(1 row)
-
-DROP SCHEMA testns CASCADE;
-NOTICE: drop cascades to table testns.acltest1
-SELECT d.* -- check that entries went away
- FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
- WHERE nspname IS NULL AND defaclnamespace != 0;
- defaclrole | defaclnamespace | defaclobjtype | defaclacl
-------------+-----------------+---------------+-----------
-(0 rows)
-
--- Grant on all objects of given type in a schema
-\c -
-CREATE SCHEMA testns;
-CREATE TABLE testns.t1 (f1 int);
-CREATE TABLE testns.t2 (f1 int);
-SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- false
- has_table_privilege
----------------------
- f
-(1 row)
-
-GRANT ALL ON ALL TABLES IN SCHEMA testns TO regressuser1;
-SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.t2', 'SELECT'); -- true
- has_table_privilege
----------------------
- t
-(1 row)
-
-REVOKE ALL ON ALL TABLES IN SCHEMA testns FROM regressuser1;
-SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- false
- has_table_privilege
----------------------
- f
-(1 row)
-
-SELECT has_table_privilege('regressuser1', 'testns.t2', 'SELECT'); -- false
- has_table_privilege
----------------------
- f
-(1 row)
-
-CREATE FUNCTION testns.testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
-SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE'); -- true by default
- has_function_privilege
-------------------------
- t
-(1 row)
-
-REVOKE ALL ON ALL FUNCTIONS IN SCHEMA testns FROM PUBLIC;
-SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE'); -- false
- has_function_privilege
-------------------------
- f
-(1 row)
-
-SET client_min_messages TO 'warning';
-DROP SCHEMA testns CASCADE;
-RESET client_min_messages;
--- Change owner of the schema & and rename of new schema owner
-\c -
-CREATE ROLE schemauser1 superuser login;
-CREATE ROLE schemauser2 superuser login;
-SET SESSION ROLE schemauser1;
-CREATE SCHEMA testns;
-SELECT nspname, rolname FROM pg_namespace, pg_roles WHERE pg_namespace.nspname = 'testns' AND pg_namespace.nspowner = pg_roles.oid;
- nspname | rolname
----------+-------------
- testns | schemauser1
-(1 row)
-
-ALTER SCHEMA testns OWNER TO schemauser2;
-ALTER ROLE schemauser2 RENAME TO schemauser_renamed;
-SELECT nspname, rolname FROM pg_namespace, pg_roles WHERE pg_namespace.nspname = 'testns' AND pg_namespace.nspowner = pg_roles.oid;
- nspname | rolname
----------+--------------------
- testns | schemauser_renamed
-(1 row)
-
-set session role schemauser_renamed;
-SET client_min_messages TO 'warning';
-DROP SCHEMA testns CASCADE;
-RESET client_min_messages;
--- clean up
-\c -
-DROP ROLE schemauser1;
-DROP ROLE schemauser_renamed;
--- test that dependent privileges are revoked (or not) properly
-\c -
-set session role regressuser1;
-create table dep_priv_test (a int);
-grant select on dep_priv_test to regressuser2 with grant option;
-grant select on dep_priv_test to regressuser3 with grant option;
-set session role regressuser2;
-grant select on dep_priv_test to regressuser4 with grant option;
-set session role regressuser3;
-grant select on dep_priv_test to regressuser4 with grant option;
-set session role regressuser4;
-grant select on dep_priv_test to regressuser5;
-\dp dep_priv_test
- Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------+---------------+-------+-----------------------------------+-------------------+----------
- public | dep_priv_test | table | regressuser1=arwdDxt/regressuser1+| |
- | | | regressuser2=r*/regressuser1 +| |
- | | | regressuser3=r*/regressuser1 +| |
- | | | regressuser4=r*/regressuser2 +| |
- | | | regressuser4=r*/regressuser3 +| |
- | | | regressuser5=r/regressuser4 | |
-(1 row)
-
-set session role regressuser2;
-revoke select on dep_priv_test from regressuser4 cascade;
-\dp dep_priv_test
- Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------+---------------+-------+-----------------------------------+-------------------+----------
- public | dep_priv_test | table | regressuser1=arwdDxt/regressuser1+| |
- | | | regressuser2=r*/regressuser1 +| |
- | | | regressuser3=r*/regressuser1 +| |
- | | | regressuser4=r*/regressuser3 +| |
- | | | regressuser5=r/regressuser4 | |
-(1 row)
-
-set session role regressuser3;
-revoke select on dep_priv_test from regressuser4 cascade;
-\dp dep_priv_test
- Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------+---------------+-------+-----------------------------------+-------------------+----------
- public | dep_priv_test | table | regressuser1=arwdDxt/regressuser1+| |
- | | | regressuser2=r*/regressuser1 +| |
- | | | regressuser3=r*/regressuser1 | |
-(1 row)
-
-set session role regressuser1;
-drop table dep_priv_test;
--- clean up
-\c
-drop sequence x_seq;
-DROP FUNCTION testfunc2(int);
-DROP FUNCTION testfunc4(boolean);
-DROP VIEW atestv0;
-DROP VIEW atestv1;
-DROP VIEW atestv2;
--- this should cascade to drop atestv4
-DROP VIEW atestv3 CASCADE;
-NOTICE: drop cascades to view atestv4
--- this should complain "does not exist"
-DROP VIEW atestv4;
-ERROR: view "atestv4" does not exist
-DROP TABLE atest1;
-DROP TABLE atest2;
-DROP TABLE atest3;
-DROP TABLE atest4;
-DROP TABLE atest5;
-DROP TABLE atest6;
-DROP TABLE atestc;
-DROP TABLE atestp1;
-DROP TABLE atestp2;
-SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
- lo_unlink
------------
-(0 rows)
-
-DROP GROUP regressgroup1;
-DROP GROUP regressgroup2;
--- these are needed to clean up permissions
-REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
-DROP OWNED BY regressuser1;
-DROP USER regressuser1;
-DROP USER regressuser2;
-DROP USER regressuser3;
-DROP USER regressuser4;
-DROP USER regressuser5;
-DROP USER regressuser6;
-ERROR: role "regressuser6" does not exist
--- permissions with LOCK TABLE
-CREATE USER locktable_user;
-CREATE TABLE lock_table (a int);
--- LOCK TABLE and SELECT permission
-GRANT SELECT ON lock_table TO locktable_user;
-SET SESSION AUTHORIZATION locktable_user;
-BEGIN;
-LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should fail
-ERROR: permission denied for relation lock_table
-ROLLBACK;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
-COMMIT;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
-ERROR: permission denied for relation lock_table
-ROLLBACK;
-\c
-REVOKE SELECT ON lock_table FROM locktable_user;
--- LOCK TABLE and INSERT permission
-GRANT INSERT ON lock_table TO locktable_user;
-SET SESSION AUTHORIZATION locktable_user;
-BEGIN;
-LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
-COMMIT;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ERROR: permission denied for relation lock_table
-ROLLBACK;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
-ERROR: permission denied for relation lock_table
-ROLLBACK;
-\c
-REVOKE INSERT ON lock_table FROM locktable_user;
--- LOCK TABLE and UPDATE permission
-GRANT UPDATE ON lock_table TO locktable_user;
-SET SESSION AUTHORIZATION locktable_user;
-BEGIN;
-LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
-COMMIT;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ERROR: permission denied for relation lock_table
-ROLLBACK;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
-COMMIT;
-\c
-REVOKE UPDATE ON lock_table FROM locktable_user;
--- LOCK TABLE and DELETE permission
-GRANT DELETE ON lock_table TO locktable_user;
-SET SESSION AUTHORIZATION locktable_user;
-BEGIN;
-LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
-COMMIT;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ERROR: permission denied for relation lock_table
-ROLLBACK;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
-COMMIT;
-\c
-REVOKE DELETE ON lock_table FROM locktable_user;
--- LOCK TABLE and TRUNCATE permission
-GRANT TRUNCATE ON lock_table TO locktable_user;
-SET SESSION AUTHORIZATION locktable_user;
-BEGIN;
-LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
-COMMIT;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ERROR: permission denied for relation lock_table
-ROLLBACK;
-BEGIN;
-LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
-COMMIT;
-\c
-REVOKE TRUNCATE ON lock_table FROM locktable_user;
--- clean up
-DROP TABLE lock_table;
-DROP USER locktable_user;
+++ /dev/null
-SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%' ORDER BY name;
- name | setting
-----------------------------+---------
- enable_bitmapscan | on
- enable_fast_query_shipping | on
- enable_hashagg | on
- enable_hashjoin | on
- enable_indexonlyscan | on
- enable_indexscan | on
- enable_material | on
- enable_mergejoin | on
- enable_nestloop | on
- enable_remotegroup | on
- enable_remotejoin | on
- enable_seqscan | on
- enable_sort | on
- enable_tidscan | on
-(14 rows)
-
-CREATE TABLE foo2(fooid int, f2 int);
-INSERT INTO foo2 VALUES(1, 11);
-INSERT INTO foo2 VALUES(2, 22);
-INSERT INTO foo2 VALUES(1, 111);
-CREATE FUNCTION foot(int) returns setof foo2 as 'SELECT * FROM foo2 WHERE fooid = $1;' LANGUAGE SQL;
--- supposed to fail with ERROR
-select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
-ERROR: function expression in FROM cannot refer to other relations of same query level
-LINE 1: select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
- ^
--- function in subselect
-select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = foo2.fooid) ORDER BY 1,2;
- fooid | f2
--------+-----
- 1 | 11
- 1 | 111
- 2 | 22
-(3 rows)
-
--- function in subselect
-select * from foo2 where f2 in (select f2 from foot(1) z where z.fooid = foo2.fooid) ORDER BY 1,2;
- fooid | f2
--------+-----
- 1 | 11
- 1 | 111
-(2 rows)
-
--- function in subselect
-select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = 1) ORDER BY 1,2;
- fooid | f2
--------+-----
- 1 | 11
- 1 | 111
-(2 rows)
-
--- nested functions
-select foot.fooid, foot.f2 from foot(sin(pi()/2)::int) ORDER BY 1,2;
- fooid | f2
--------+-----
- 1 | 11
- 1 | 111
-(2 rows)
-
-CREATE TABLE foo (fooid int, foosubid int, fooname text, primary key(fooid,foosubid));
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
-INSERT INTO foo VALUES(1,1,'Joe');
-INSERT INTO foo VALUES(1,2,'Ed');
-INSERT INTO foo VALUES(2,1,'Mary');
--- sql, proretset = f, prorettype = b
-CREATE FUNCTION getfoo(int) RETURNS int AS 'SELECT $1;' LANGUAGE SQL;
-SELECT * FROM getfoo(1) AS t1;
- t1
-----
- 1
-(1 row)
-
-CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
-SELECT * FROM vw_getfoo;
- getfoo
---------
- 1
-(1 row)
-
--- sql, proretset = t, prorettype = b
-DROP VIEW vw_getfoo;
-DROP FUNCTION getfoo(int);
-CREATE FUNCTION getfoo(int) RETURNS setof int AS 'SELECT fooid FROM foo WHERE fooid = $1;' LANGUAGE SQL;
-SELECT * FROM getfoo(1) AS t1;
- t1
-----
- 1
- 1
-(2 rows)
-
-CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
-SELECT * FROM vw_getfoo;
- getfoo
---------
- 1
- 1
-(2 rows)
-
--- sql, proretset = t, prorettype = b
-DROP VIEW vw_getfoo;
-DROP FUNCTION getfoo(int);
-CREATE FUNCTION getfoo(int) RETURNS setof text AS 'SELECT fooname FROM foo WHERE fooid = $1;' LANGUAGE SQL;
-SELECT * FROM getfoo(1) AS t1 ORDER BY 1;
- t1
------
- Ed
- Joe
-(2 rows)
-
-CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
-SELECT * FROM vw_getfoo ORDER BY 1;
- getfoo
---------
- Ed
- Joe
-(2 rows)
-
--- sql, proretset = f, prorettype = c
-DROP VIEW vw_getfoo;
-DROP FUNCTION getfoo(int);
-CREATE FUNCTION getfoo(int) RETURNS foo AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
-SELECT * FROM getfoo(1) AS t1;
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
-(1 row)
-
-CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
-SELECT * FROM vw_getfoo;
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
-(1 row)
-
--- sql, proretset = t, prorettype = c
-DROP VIEW vw_getfoo;
-DROP FUNCTION getfoo(int);
-CREATE FUNCTION getfoo(int) RETURNS setof foo AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
-SELECT * FROM getfoo(1) AS t1 ORDER BY foosubid;
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
- 1 | 2 | Ed
-(2 rows)
-
-CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
-SELECT * FROM vw_getfoo ORDER BY foosubid;
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
- 1 | 2 | Ed
-(2 rows)
-
--- sql, proretset = f, prorettype = record
-DROP VIEW vw_getfoo;
-DROP FUNCTION getfoo(int);
-CREATE FUNCTION getfoo(int) RETURNS RECORD AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
-SELECT * FROM getfoo(1) AS t1(fooid int, foosubid int, fooname text);
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
-(1 row)
-
-CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1) AS
-(fooid int, foosubid int, fooname text);
-SELECT * FROM vw_getfoo;
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
-(1 row)
-
--- sql, proretset = t, prorettype = record
-DROP VIEW vw_getfoo;
-DROP FUNCTION getfoo(int);
-CREATE FUNCTION getfoo(int) RETURNS setof record AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
-SELECT * FROM getfoo(1) AS t1(fooid int, foosubid int, fooname text) ORDER BY foosubid;
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
- 1 | 2 | Ed
-(2 rows)
-
-CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1) AS
-(fooid int, foosubid int, fooname text);
-SELECT * FROM vw_getfoo ORDER BY foosubid;
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
- 1 | 2 | Ed
-(2 rows)
-
--- plpgsql, proretset = f, prorettype = b
-DROP VIEW vw_getfoo;
-DROP FUNCTION getfoo(int);
-CREATE FUNCTION getfoo(int) RETURNS int AS 'DECLARE fooint int; BEGIN SELECT fooid into fooint FROM foo WHERE fooid = $1; RETURN fooint; END;' LANGUAGE plpgsql;
-SELECT * FROM getfoo(1) AS t1;
- t1
-----
- 1
-(1 row)
-
-CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
-SELECT * FROM vw_getfoo;
- getfoo
---------
- 1
-(1 row)
-
--- plpgsql, proretset = f, prorettype = c
-DROP VIEW vw_getfoo;
-DROP FUNCTION getfoo(int);
-CREATE FUNCTION getfoo(int) RETURNS foo AS 'DECLARE footup foo%ROWTYPE; BEGIN SELECT * into footup FROM foo WHERE fooid = $1; RETURN footup; END;' LANGUAGE plpgsql;
-SELECT * FROM getfoo(1) AS t1;
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
-(1 row)
-
-CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
-SELECT * FROM vw_getfoo;
- fooid | foosubid | fooname
--------+----------+---------
- 1 | 1 | Joe
-(1 row)
-
-DROP VIEW vw_getfoo;
-DROP FUNCTION getfoo(int);
-DROP FUNCTION foot(int);
-DROP TABLE foo2;
-DROP TABLE foo;
--- Rescan tests --
-CREATE TABLE foorescan (fooid int, foosubid int, fooname text, primary key(fooid,foosubid));
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foorescan_pkey" for table "foorescan"
-INSERT INTO foorescan values(5000,1,'abc.5000.1');
-INSERT INTO foorescan values(5001,1,'abc.5001.1');
-INSERT INTO foorescan values(5002,1,'abc.5002.1');
-INSERT INTO foorescan values(5003,1,'abc.5003.1');
-INSERT INTO foorescan values(5004,1,'abc.5004.1');
-INSERT INTO foorescan values(5005,1,'abc.5005.1');
-INSERT INTO foorescan values(5006,1,'abc.5006.1');
-INSERT INTO foorescan values(5007,1,'abc.5007.1');
-INSERT INTO foorescan values(5008,1,'abc.5008.1');
-INSERT INTO foorescan values(5009,1,'abc.5009.1');
-INSERT INTO foorescan values(5000,2,'abc.5000.2');
-INSERT INTO foorescan values(5001,2,'abc.5001.2');
-INSERT INTO foorescan values(5002,2,'abc.5002.2');
-INSERT INTO foorescan values(5003,2,'abc.5003.2');
-INSERT INTO foorescan values(5004,2,'abc.5004.2');
-INSERT INTO foorescan values(5005,2,'abc.5005.2');
-INSERT INTO foorescan values(5006,2,'abc.5006.2');
-INSERT INTO foorescan values(5007,2,'abc.5007.2');
-INSERT INTO foorescan values(5008,2,'abc.5008.2');
-INSERT INTO foorescan values(5009,2,'abc.5009.2');
-INSERT INTO foorescan values(5000,3,'abc.5000.3');
-INSERT INTO foorescan values(5001,3,'abc.5001.3');
-INSERT INTO foorescan values(5002,3,'abc.5002.3');
-INSERT INTO foorescan values(5003,3,'abc.5003.3');
-INSERT INTO foorescan values(5004,3,'abc.5004.3');
-INSERT INTO foorescan values(5005,3,'abc.5005.3');
-INSERT INTO foorescan values(5006,3,'abc.5006.3');
-INSERT INTO foorescan values(5007,3,'abc.5007.3');
-INSERT INTO foorescan values(5008,3,'abc.5008.3');
-INSERT INTO foorescan values(5009,3,'abc.5009.3');
-INSERT INTO foorescan values(5000,4,'abc.5000.4');
-INSERT INTO foorescan values(5001,4,'abc.5001.4');
-INSERT INTO foorescan values(5002,4,'abc.5002.4');
-INSERT INTO foorescan values(5003,4,'abc.5003.4');
-INSERT INTO foorescan values(5004,4,'abc.5004.4');
-INSERT INTO foorescan values(5005,4,'abc.5005.4');
-INSERT INTO foorescan values(5006,4,'abc.5006.4');
-INSERT INTO foorescan values(5007,4,'abc.5007.4');
-INSERT INTO foorescan values(5008,4,'abc.5008.4');
-INSERT INTO foorescan values(5009,4,'abc.5009.4');
-INSERT INTO foorescan values(5000,5,'abc.5000.5');
-INSERT INTO foorescan values(5001,5,'abc.5001.5');
-INSERT INTO foorescan values(5002,5,'abc.5002.5');
-INSERT INTO foorescan values(5003,5,'abc.5003.5');
-INSERT INTO foorescan values(5004,5,'abc.5004.5');
-INSERT INTO foorescan values(5005,5,'abc.5005.5');
-INSERT INTO foorescan values(5006,5,'abc.5006.5');
-INSERT INTO foorescan values(5007,5,'abc.5007.5');
-INSERT INTO foorescan values(5008,5,'abc.5008.5');
-INSERT INTO foorescan values(5009,5,'abc.5009.5');
-CREATE FUNCTION foorescan(int,int) RETURNS setof foorescan AS 'SELECT * FROM foorescan WHERE fooid >= $1 and fooid < $2 ;' LANGUAGE SQL;
---invokes ExecReScanFunctionScan
-SELECT * FROM foorescan f WHERE f.fooid IN (SELECT fooid FROM foorescan(5002,5004)) ORDER BY 1,2;
- fooid | foosubid | fooname
--------+----------+------------
- 5002 | 1 | abc.5002.1
- 5002 | 2 | abc.5002.2
- 5002 | 3 | abc.5002.3
- 5002 | 4 | abc.5002.4
- 5002 | 5 | abc.5002.5
- 5003 | 1 | abc.5003.1
- 5003 | 2 | abc.5003.2
- 5003 | 3 | abc.5003.3
- 5003 | 4 | abc.5003.4
- 5003 | 5 | abc.5003.5
-(10 rows)
-
-CREATE VIEW vw_foorescan AS SELECT * FROM foorescan(5002,5004);
---invokes ExecReScanFunctionScan
-SELECT * FROM foorescan f WHERE f.fooid IN (SELECT fooid FROM vw_foorescan) ORDER BY 1,2;
- fooid | foosubid | fooname
--------+----------+------------
- 5002 | 1 | abc.5002.1
- 5002 | 2 | abc.5002.2
- 5002 | 3 | abc.5002.3
- 5002 | 4 | abc.5002.4
- 5002 | 5 | abc.5002.5
- 5003 | 1 | abc.5003.1
- 5003 | 2 | abc.5003.2
- 5003 | 3 | abc.5003.3
- 5003 | 4 | abc.5003.4
- 5003 | 5 | abc.5003.5
-(10 rows)
-
-CREATE TABLE barrescan (fooid int primary key);
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "barrescan_pkey" for table "barrescan"
-INSERT INTO barrescan values(5003);
-INSERT INTO barrescan values(5004);
-INSERT INTO barrescan values(5005);
-INSERT INTO barrescan values(5006);
-INSERT INTO barrescan values(5007);
-INSERT INTO barrescan values(5008);
-CREATE FUNCTION foorescan(int) RETURNS setof foorescan AS 'SELECT * FROM foorescan WHERE fooid = $1;' LANGUAGE SQL;
---invokes ExecReScanFunctionScan with chgParam != NULL
-SELECT f.* FROM barrescan b, foorescan f WHERE f.fooid = b.fooid AND b.fooid IN (SELECT fooid FROM foorescan(b.fooid)) ORDER BY 1,2;
- fooid | foosubid | fooname
--------+----------+------------
- 5003 | 1 | abc.5003.1
- 5003 | 2 | abc.5003.2
- 5003 | 3 | abc.5003.3
- 5003 | 4 | abc.5003.4
- 5003 | 5 | abc.5003.5
- 5004 | 1 | abc.5004.1
- 5004 | 2 | abc.5004.2
- 5004 | 3 | abc.5004.3
- 5004 | 4 | abc.5004.4
- 5004 | 5 | abc.5004.5
- 5005 | 1 | abc.5005.1
- 5005 | 2 | abc.5005.2
- 5005 | 3 | abc.5005.3
- 5005 | 4 | abc.5005.4
- 5005 | 5 | abc.5005.5
- 5006 | 1 | abc.5006.1
- 5006 | 2 | abc.5006.2
- 5006 | 3 | abc.5006.3
- 5006 | 4 | abc.5006.4
- 5006 | 5 | abc.5006.5
- 5007 | 1 | abc.5007.1
- 5007 | 2 | abc.5007.2
- 5007 | 3 | abc.5007.3
- 5007 | 4 | abc.5007.4
- 5007 | 5 | abc.5007.5
- 5008 | 1 | abc.5008.1
- 5008 | 2 | abc.5008.2
- 5008 | 3 | abc.5008.3
- 5008 | 4 | abc.5008.4
- 5008 | 5 | abc.5008.5
-(30 rows)
-
-SELECT b.fooid, max(f.foosubid) FROM barrescan b, foorescan f WHERE f.fooid = b.fooid AND b.fooid IN (SELECT fooid FROM foorescan(b.fooid)) GROUP BY b.fooid ORDER BY 1,2;
- fooid | max
--------+-----
- 5003 | 5
- 5004 | 5
- 5005 | 5
- 5006 | 5
- 5007 | 5
- 5008 | 5
-(6 rows)
-
-CREATE VIEW fooview1 AS SELECT f.* FROM barrescan b, foorescan f WHERE f.fooid = b.fooid AND b.fooid IN (SELECT fooid FROM foorescan(b.fooid)) ORDER BY 1,2;
-SELECT * FROM fooview1 AS fv WHERE fv.fooid = 5004;
- fooid | foosubid | fooname
--------+----------+------------
- 5004 | 1 | abc.5004.1
- 5004 | 2 | abc.5004.2
- 5004 | 3 | abc.5004.3
- 5004 | 4 | abc.5004.4
- 5004 | 5 | abc.5004.5
-(5 rows)
-
-CREATE VIEW fooview2 AS SELECT b.fooid, max(f.foosubid) AS maxsubid FROM barrescan b, foorescan f WHERE f.fooid = b.fooid AND b.fooid IN (SELECT fooid FROM foorescan(b.fooid)) GROUP BY b.fooid ORDER BY 1,2;
-SELECT * FROM fooview2 AS fv WHERE fv.maxsubid = 5;
- fooid | maxsubid
--------+----------
- 5003 | 5
- 5004 | 5
- 5005 | 5
- 5006 | 5
- 5007 | 5
- 5008 | 5
-(6 rows)
-
-DROP VIEW vw_foorescan;
-DROP VIEW fooview1;
-DROP VIEW fooview2;
-DROP FUNCTION foorescan(int,int);
-DROP FUNCTION foorescan(int);
-DROP TABLE foorescan;
-DROP TABLE barrescan;
---
--- Test cases involving OUT parameters
---
-CREATE FUNCTION foo(in f1 int, out f2 int)
-AS 'select $1+1' LANGUAGE sql;
-SELECT foo(42);
- foo
------
- 43
-(1 row)
-
-SELECT * FROM foo(42);
- f2
-----
- 43
-(1 row)
-
-SELECT * FROM foo(42) AS p(x);
- x
-----
- 43
-(1 row)
-
--- explicit spec of return type is OK
-CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int) RETURNS int
-AS 'select $1+1' LANGUAGE sql;
--- error, wrong result type
-CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int) RETURNS float
-AS 'select $1+1' LANGUAGE sql;
-ERROR: function result type must be integer because of OUT parameters
--- with multiple OUT params you must get a RECORD result
-CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int, out f3 text) RETURNS int
-AS 'select $1+1' LANGUAGE sql;
-ERROR: function result type must be record because of OUT parameters
-CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int, out f3 text)
-RETURNS record
-AS 'select $1+1' LANGUAGE sql;
-ERROR: cannot change return type of existing function
-HINT: Use DROP FUNCTION first.
-CREATE OR REPLACE FUNCTION foor(in f1 int, out f2 int, out text)
-AS $$select $1-1, $1::text || 'z'$$ LANGUAGE sql;
-SELECT f1, foor(f1) FROM int4_tbl ORDER BY 1, 2;
- f1 | foor
--------------+----------------------------
- -2147483647 | (-2147483648,-2147483647z)
- -123456 | (-123457,-123456z)
- 0 | (-1,0z)
- 123456 | (123455,123456z)
- 2147483647 | (2147483646,2147483647z)
-(5 rows)
-
-SELECT * FROM foor(42);
- f2 | column2
-----+---------
- 41 | 42z
-(1 row)
-
-SELECT * FROM foor(42) AS p(a,b);
- a | b
-----+-----
- 41 | 42z
-(1 row)
-
-CREATE OR REPLACE FUNCTION foob(in f1 int, inout f2 int, out text)
-AS $$select $2-1, $1::text || 'z'$$ LANGUAGE sql;
-SELECT f1, foob(f1, f1/2) FROM int4_tbl ORDER BY 1, 2;
- f1 | foob
--------------+----------------------------
- -2147483647 | (-1073741824,-2147483647z)
- -123456 | (-61729,-123456z)
- 0 | (-1,0z)
- 123456 | (61727,123456z)
- 2147483647 | (1073741822,2147483647z)
-(5 rows)
-
-SELECT * FROM foob(42, 99);
- f2 | column2
-----+---------
- 98 | 42z
-(1 row)
-
-SELECT * FROM foob(42, 99) AS p(a,b);
- a | b
-----+-----
- 98 | 42z
-(1 row)
-
--- Can reference function with or without OUT params for DROP, etc
-DROP FUNCTION foo(int);
-DROP FUNCTION foor(in f2 int, out f1 int, out text);
-DROP FUNCTION foob(in f1 int, inout f2 int);
---
--- For my next trick, polymorphic OUT parameters
---
-CREATE FUNCTION dup (f1 anyelement, f2 out anyelement, f3 out anyarray)
-AS 'select $1, array[$1,$1]' LANGUAGE sql;
-SELECT dup(22);
- dup
-----------------
- (22,"{22,22}")
-(1 row)
-
-SELECT dup('xyz'); -- fails
-ERROR: could not determine polymorphic type because input has type "unknown"
-SELECT dup('xyz'::text);
- dup
--------------------
- (xyz,"{xyz,xyz}")
-(1 row)
-
-SELECT * FROM dup('xyz'::text);
- f2 | f3
------+-----------
- xyz | {xyz,xyz}
-(1 row)
-
--- fails, as we are attempting to rename first argument
-CREATE OR REPLACE FUNCTION dup (inout f2 anyelement, out f3 anyarray)
-AS 'select $1, array[$1,$1]' LANGUAGE sql;
-ERROR: cannot change name of input parameter "f1"
-HINT: Use DROP FUNCTION first.
-DROP FUNCTION dup(anyelement);
--- equivalent behavior, though different name exposed for input arg
-CREATE OR REPLACE FUNCTION dup (inout f2 anyelement, out f3 anyarray)
-AS 'select $1, array[$1,$1]' LANGUAGE sql;
-SELECT dup(22);
- dup
-----------------
- (22,"{22,22}")
-(1 row)
-
-DROP FUNCTION dup(anyelement);
--- fails, no way to deduce outputs
-CREATE FUNCTION bad (f1 int, out f2 anyelement, out f3 anyarray)
-AS 'select $1, array[$1,$1]' LANGUAGE sql;
-ERROR: cannot determine result data type
-DETAIL: A function returning a polymorphic type must have at least one polymorphic argument.
---
--- table functions
---
-CREATE OR REPLACE FUNCTION foo()
-RETURNS TABLE(a int)
-AS $$ SELECT a FROM generate_series(1,5) a(a) $$ LANGUAGE sql;
-SELECT * FROM foo() ORDER BY 1;
- a
----
- 1
- 2
- 3
- 4
- 5
-(5 rows)
-
-DROP FUNCTION foo();
-CREATE OR REPLACE FUNCTION foo(int)
-RETURNS TABLE(a int, b int)
-AS $$ SELECT a, b
- FROM generate_series(1,$1) a(a),
- generate_series(1,$1) b(b) $$ LANGUAGE sql;
-SELECT * FROM foo(3) ORDER BY 1, 2;
- a | b
----+---
- 1 | 1
- 1 | 2
- 1 | 3
- 2 | 1
- 2 | 2
- 2 | 3
- 3 | 1
- 3 | 2
- 3 | 3
-(9 rows)
-
-DROP FUNCTION foo(int);
---
--- some tests on SQL functions with RETURNING
---
-create temp table tt(f1 serial, data text);
-NOTICE: CREATE TABLE will create implicit sequence "tt_f1_seq" for serial column "tt.f1"
-create function insert_tt(text) returns int as
-$$ insert into tt(data) values($1) returning f1 $$
-language sql;
-select insert_tt('foo');
- insert_tt
------------
- 1
-(1 row)
-
-select insert_tt('bar');
- insert_tt
------------
- 2
-(1 row)
-
-select * from tt order by 1, 2;
- f1 | data
-----+------
- 1 | foo
- 2 | bar
-(2 rows)
-
--- insert will execute to completion even if function needs just 1 row
-create or replace function insert_tt(text) returns int as
-$$ insert into tt(data) values($1),($1||$1) returning f1 $$
-language sql;
-select insert_tt('fool');
- insert_tt
------------
- 3
-(1 row)
-
-select * from tt order by 1, 2;
- f1 | data
-----+----------
- 1 | foo
- 2 | bar
- 3 | fool
- 4 | foolfool
-(4 rows)
-
--- setof does what's expected
-create or replace function insert_tt2(text,text) returns setof int as
-$$ insert into tt(data) values($1),($2) returning f1 $$
-language sql;
-select insert_tt2('foolish','barrish');
- insert_tt2
-------------
- 5
- 6
-(2 rows)
-
-select * from insert_tt2('baz','quux') order by 1;
- insert_tt2
-------------
- 7
- 8
-(2 rows)
-
-select * from tt order by 1, 2;
- f1 | data
-----+----------
- 1 | foo
- 2 | bar
- 3 | fool
- 4 | foolfool
- 5 | foolish
- 6 | barrish
- 7 | baz
- 8 | quux
-(8 rows)
-
--- limit doesn't prevent execution to completion
-select insert_tt2('foolish','barrish') limit 1;
- insert_tt2
-------------
- 9
-(1 row)
-
-select * from tt order by 1, 2;
- f1 | data
-----+----------
- 1 | foo
- 2 | bar
- 3 | fool
- 4 | foolfool
- 5 | foolish
- 6 | barrish
- 7 | baz
- 8 | quux
- 9 | foolish
- 10 | barrish
-(10 rows)
-
--- triggers will fire, too
-create function noticetrigger() returns trigger as $$
-begin
- raise notice 'noticetrigger % %', new.f1, new.data;
- return null;
-end $$ language plpgsql;
-create trigger tnoticetrigger after insert on tt for each row
-execute procedure noticetrigger();
-ERROR: Postgres-XL does not support TRIGGER yet
-DETAIL: The feature is not currently supported
-select insert_tt2('foolme','barme') limit 1;
- insert_tt2
-------------
- 11
-(1 row)
-
-select * from tt order by 1, 2;
- f1 | data
-----+----------
- 1 | foo
- 2 | bar
- 3 | fool
- 4 | foolfool
- 5 | foolish
- 6 | barrish
- 7 | baz
- 8 | quux
- 9 | foolish
- 10 | barrish
- 11 | foolme
- 12 | barme
-(12 rows)
-
--- and rules work
-create temp table tt_log(f1 int, data text);
-create rule insert_tt_rule as on insert to tt do also
- insert into tt_log values(new.*);
-select insert_tt2('foollog','barlog') limit 1;
- insert_tt2
-------------
- 13
-(1 row)
-
-select * from tt order by 1, 2;
- f1 | data
-----+----------
- 1 | foo
- 2 | bar
- 3 | fool
- 4 | foolfool
- 5 | foolish
- 6 | barrish
- 7 | baz
- 8 | quux
- 9 | foolish
- 10 | barrish
- 11 | foolme
- 12 | barme
- 13 | foollog
- 14 | barlog
-(14 rows)
-
--- note that nextval() gets executed a second time in the rule expansion,
--- which is expected.
-select * from tt_log order by 1, 2;
- f1 | data
-----+---------
- 15 | foollog
- 16 | barlog
-(2 rows)
-
--- test case for a whole-row-variable bug
-create function foo1(n integer, out a text, out b text)
- returns setof record
- language sql
- as $$ select 'foo ' || i, 'bar ' || i from generate_series(1,$1) i $$;
-set work_mem='64kB';
-select t.a, t, t.a from foo1(10000) t limit 1;
- a | t | a
--------+-------------------+-------
- foo 1 | ("foo 1","bar 1") | foo 1
-(1 row)
-
-reset work_mem;
-select t.a, t, t.a from foo1(10000) t limit 1;
- a | t | a
--------+-------------------+-------
- foo 1 | ("foo 1","bar 1") | foo 1
-(1 row)
-
-drop function foo1(n integer);
--- test use of SQL functions returning record
--- this is supported in some cases where the query doesn't specify
--- the actual record type ...
-create function array_to_set(anyarray) returns setof record as $$
- select i AS "index", $1[i] AS "value" from generate_subscripts($1, 1) i
-$$ language sql strict immutable;
-select array_to_set(array['one', 'two']);
- array_to_set
---------------
- (1,one)
- (2,two)
-(2 rows)
-
-select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text) order by 1, 2;
- f1 | f2
-----+-----
- 1 | one
- 2 | two
-(2 rows)
-
-select * from array_to_set(array['one', 'two']); -- fail
-ERROR: a column definition list is required for functions returning "record"
-LINE 1: select * from array_to_set(array['one', 'two']);
- ^
-create temp table foo(f1 int8, f2 int8);
-create function testfoo() returns record as $$
- insert into foo values (1,2) returning *;
-$$ language sql;
-select testfoo();
- testfoo
----------
- (1,2)
-(1 row)
-
-select * from testfoo() as t(f1 int8,f2 int8);
- f1 | f2
-----+----
- 1 | 2
-(1 row)
-
-select * from testfoo(); -- fail
-ERROR: a column definition list is required for functions returning "record"
-LINE 1: select * from testfoo();
- ^
-drop function testfoo();
-create function testfoo() returns setof record as $$
- insert into foo values (1,2), (3,4) returning *;
-$$ language sql;
-select testfoo();
- testfoo
----------
- (1,2)
- (3,4)
-(2 rows)
-
-select * from testfoo() as t(f1 int8,f2 int8) order by 1, 2;
- f1 | f2
-----+----
- 1 | 2
- 3 | 4
-(2 rows)
-
-select * from testfoo(); -- fail
-ERROR: a column definition list is required for functions returning "record"
-LINE 1: select * from testfoo();
- ^
-drop function testfoo();
---
--- Check some cases involving dropped columns in a rowtype result
---
-create temp table users (userid text, email text, todrop bool, enabled bool);
-insert into users values ('id','email',true,true);
-insert into users values ('id2','email2',true,true);
-alter table users drop column todrop;
-create or replace function get_first_user() returns users as
-$$ SELECT * FROM users ORDER BY userid LIMIT 1; $$
-language sql stable;
-SELECT get_first_user();
- get_first_user
-----------------
- (id,email,t)
-(1 row)
-
-SELECT * FROM get_first_user();
- userid | email | enabled
---------+-------+---------
- id | email | t
-(1 row)
-
-create or replace function get_users() returns setof users as
-$$ SELECT * FROM users ORDER BY userid; $$
-language sql stable;
-SELECT get_users();
- get_users
-----------------
- (id,email,t)
- (id2,email2,t)
-(2 rows)
-
-SELECT * FROM get_users();
- userid | email | enabled
---------+--------+---------
- id | email | t
- id2 | email2 | t
-(2 rows)
-
-drop function get_first_user();
-drop function get_users();
-drop table users;
--- this won't get inlined because of type coercion, but it shouldn't fail
-create or replace function foobar() returns setof text as
-$$ select 'foo'::varchar union all select 'bar'::varchar ; $$
-language sql stable;
-select foobar();
- foobar
---------
- foo
- bar
-(2 rows)
-
-select * from foobar();
- foobar
---------
- foo
- bar
-(2 rows)
-
-drop function foobar();
--- check handling of a SQL function with multiple OUT params (bug #5777)
-create or replace function foobar(out integer, out numeric) as
-$$ select (1, 2.1) $$ language sql;
-select * from foobar();
- column1 | column2
----------+---------
- 1 | 2.1
-(1 row)
-
-create or replace function foobar(out integer, out numeric) as
-$$ select (1, 2) $$ language sql;
-select * from foobar(); -- fail
-ERROR: function return row and query-specified return row do not match
-DETAIL: Returned type integer at ordinal position 2, but query expects numeric.
-create or replace function foobar(out integer, out numeric) as
-$$ select (1, 2.1, 3) $$ language sql;
-select * from foobar(); -- fail
-ERROR: function return row and query-specified return row do not match
-DETAIL: Returned row contains 3 attributes, but query expects 2.
-drop function foobar();
+++ /dev/null
---
--- Test INSERT/UPDATE/DELETE RETURNING
---
--- Simple cases
-CREATE TEMP TABLE foo (f1 serial, f2 text, f3 int default 42);
-NOTICE: CREATE TABLE will create implicit sequence "foo_f1_seq" for serial column "foo.f1"
-INSERT INTO foo (f2,f3)
- VALUES ('test', DEFAULT), ('More', 11), (upper('more'), 7+9)
- RETURNING *, f1+f3 AS sum;
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3
-----+----+----
-(0 rows)
-
-UPDATE foo SET f2 = lower(f2), f3 = DEFAULT RETURNING foo.*, f1+f3 AS sum13;
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3
-----+----+----
-(0 rows)
-
-DELETE FROM foo WHERE f1 > 2 RETURNING f3, f2, f1, least(f1,f3);
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3
-----+----+----
-(0 rows)
-
--- Subplans and initplans in the RETURNING list
-INSERT INTO foo SELECT f1+10, f2, f3+99 FROM foo
- RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan,
- EXISTS(SELECT * FROM int4_tbl) AS initplan;
-ERROR: RETURNING clause not yet supported
-UPDATE foo SET f3 = f3 * 2
- WHERE f1 > 10
- RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan,
- EXISTS(SELECT * FROM int4_tbl) AS initplan;
-ERROR: RETURNING clause not yet supported
-DELETE FROM foo
- WHERE f1 > 10
- RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan,
- EXISTS(SELECT * FROM int4_tbl) AS initplan;
-ERROR: RETURNING clause not yet supported
--- Joins
-UPDATE foo SET f3 = f3*2
- FROM int4_tbl i
- WHERE foo.f1 + 123455 = i.f1
- RETURNING foo.*, i.f1 as "i.f1";
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3
-----+----+----
-(0 rows)
-
-DELETE FROM foo
- USING int4_tbl i
- WHERE foo.f1 + 123455 = i.f1
- RETURNING foo.*, i.f1 as "i.f1";
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3
-----+----+----
-(0 rows)
-
--- Check inheritance cases
-CREATE TEMP TABLE foochild (fc int) INHERITS (foo);
-INSERT INTO foochild VALUES(123,'child',999,-123);
-ALTER TABLE foo ADD COLUMN f4 int8 DEFAULT 99;
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3 | f4
------+-------+-----+----
- 123 | child | 999 | 99
-(1 row)
-
-SELECT * FROM foochild ORDER BY f1;
- f1 | f2 | f3 | fc | f4
------+-------+-----+------+----
- 123 | child | 999 | -123 | 99
-(1 row)
-
-UPDATE foo SET f4 = f4 + f3 WHERE f4 = 99 RETURNING *;
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3 | f4
------+-------+-----+----
- 123 | child | 999 | 99
-(1 row)
-
-SELECT * FROM foochild ORDER BY f1;
- f1 | f2 | f3 | fc | f4
------+-------+-----+------+----
- 123 | child | 999 | -123 | 99
-(1 row)
-
-UPDATE foo SET f3 = f3*2
- FROM int8_tbl i
- WHERE foo.f1 = i.q2
- RETURNING *;
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3 | f4
------+-------+-----+----
- 123 | child | 999 | 99
-(1 row)
-
-SELECT * FROM foochild ORDER BY f1;
- f1 | f2 | f3 | fc | f4
------+-------+-----+------+----
- 123 | child | 999 | -123 | 99
-(1 row)
-
-DELETE FROM foo
- USING int8_tbl i
- WHERE foo.f1 = i.q2
- RETURNING *;
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3 | f4
------+-------+-----+----
- 123 | child | 999 | 99
-(1 row)
-
-SELECT * FROM foochild ORDER BY f1;
- f1 | f2 | f3 | fc | f4
------+-------+-----+------+----
- 123 | child | 999 | -123 | 99
-(1 row)
-
-DROP TABLE foochild;
--- Rules and views
-CREATE TEMP VIEW voo AS SELECT f1, f2 FROM foo;
-CREATE RULE voo_i AS ON INSERT TO voo DO INSTEAD
- INSERT INTO foo VALUES(new.*, 57);
-INSERT INTO voo VALUES(11,'zit');
--- fails:
-INSERT INTO voo VALUES(12,'zoo') RETURNING *, f1*2;
-ERROR: cannot perform INSERT RETURNING on relation "voo"
-HINT: You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause.
--- fails, incompatible list:
-CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD
- INSERT INTO foo VALUES(new.*, 57) RETURNING *;
-ERROR: RETURNING list has too many entries
-CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD
- INSERT INTO foo VALUES(new.*, 57) RETURNING f1, f2;
--- should still work
-INSERT INTO voo VALUES(13,'zit2');
--- works now
-INSERT INTO voo VALUES(14,'zoo2') RETURNING *;
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3 | f4
-----+------+----+----
- 11 | zit | 57 | 99
- 13 | zit2 | 57 | 99
-(2 rows)
-
-SELECT * FROM voo ORDER BY f1;
- f1 | f2
-----+------
- 11 | zit
- 13 | zit2
-(2 rows)
-
-CREATE OR REPLACE RULE voo_u AS ON UPDATE TO voo DO INSTEAD
- UPDATE foo SET f1 = new.f1, f2 = new.f2 WHERE f1 = old.f1
- RETURNING f1, f2;
-update voo set f1 = f1 + 1 where f2 = 'zoo2';
-ERROR: Partition column can't be updated in current version
-update voo set f1 = f1 + 1 where f2 = 'zoo2' RETURNING *, f1*2;
-ERROR: Partition column can't be updated in current version
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3 | f4
-----+------+----+----
- 11 | zit | 57 | 99
- 13 | zit2 | 57 | 99
-(2 rows)
-
-SELECT * FROM voo ORDER BY f1;
- f1 | f2
-----+------
- 11 | zit
- 13 | zit2
-(2 rows)
-
-CREATE OR REPLACE RULE voo_d AS ON DELETE TO voo DO INSTEAD
- DELETE FROM foo WHERE f1 = old.f1
- RETURNING f1, f2;
-DELETE FROM foo WHERE f1 = 13;
-DELETE FROM foo WHERE f2 = 'zit' RETURNING *;
-ERROR: RETURNING clause not yet supported
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3 | f4
-----+-----+----+----
- 11 | zit | 57 | 99
-(1 row)
-
-SELECT * FROM voo ORDER BY f1;
- f1 | f2
-----+-----
- 11 | zit
-(1 row)
-
--- Try a join case
-CREATE TEMP TABLE joinme (f2j text, other int);
-INSERT INTO joinme VALUES('more', 12345);
-INSERT INTO joinme VALUES('zoo2', 54321);
-INSERT INTO joinme VALUES('other', 0);
-CREATE TEMP VIEW joinview AS
- SELECT foo.*, other FROM foo JOIN joinme ON (f2 = f2j);
-SELECT * FROM joinview ORDER BY f1;
- f1 | f2 | f3 | f4 | other
-----+----+----+----+-------
-(0 rows)
-
-CREATE RULE joinview_u AS ON UPDATE TO joinview DO INSTEAD
- UPDATE foo SET f1 = new.f1, f3 = new.f3
- FROM joinme WHERE f2 = f2j AND f2 = old.f2
- RETURNING foo.*, other;
-UPDATE joinview SET f1 = f1 + 1 WHERE f3 = 57 RETURNING *, other + 1;
-ERROR: Partition column can't be updated in current version
-SELECT * FROM joinview ORDER BY f1;
- f1 | f2 | f3 | f4 | other
-----+----+----+----+-------
-(0 rows)
-
-SELECT * FROM foo ORDER BY f1;
- f1 | f2 | f3 | f4
-----+-----+----+----
- 11 | zit | 57 | 99
-(1 row)
-
-SELECT * FROM voo ORDER BY f1;
- f1 | f2
-----+-----
- 11 | zit
-(1 row)
-
+++ /dev/null
---
--- SELECT
---
--- btree index
--- awk '{if($1<10){print;}else{next;}}' onek.data | sort +0n -1
---
-SELECT * FROM onek
- WHERE onek.unique1 < 10
- ORDER BY onek.unique1;
- unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4
----------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+---------
- 0 | 998 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | AAAAAA | KMBAAA | OOOOxx
- 1 | 214 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 3 | BAAAAA | GIAAAA | OOOOxx
- 2 | 326 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 4 | 5 | CAAAAA | OMAAAA | OOOOxx
- 3 | 431 | 1 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 6 | 7 | DAAAAA | PQAAAA | VVVVxx
- 4 | 833 | 0 | 0 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 8 | 9 | EAAAAA | BGBAAA | HHHHxx
- 5 | 541 | 1 | 1 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 10 | 11 | FAAAAA | VUAAAA | HHHHxx
- 6 | 978 | 0 | 2 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 12 | 13 | GAAAAA | QLBAAA | OOOOxx
- 7 | 647 | 1 | 3 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 14 | 15 | HAAAAA | XYAAAA | VVVVxx
- 8 | 653 | 0 | 0 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 16 | 17 | IAAAAA | DZAAAA | HHHHxx
- 9 | 49 | 1 | 1 | 9 | 9 | 9 | 9 | 9 | 9 | 9 | 18 | 19 | JAAAAA | XBAAAA | HHHHxx
-(10 rows)
-
---
--- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1
---
-SELECT onek.unique1, onek.stringu1 FROM onek
- WHERE onek.unique1 < 20
- ORDER BY unique1 using >;
- unique1 | stringu1
----------+----------
- 19 | TAAAAA
- 18 | SAAAAA
- 17 | RAAAAA
- 16 | QAAAAA
- 15 | PAAAAA
- 14 | OAAAAA
- 13 | NAAAAA
- 12 | MAAAAA
- 11 | LAAAAA
- 10 | KAAAAA
- 9 | JAAAAA
- 8 | IAAAAA
- 7 | HAAAAA
- 6 | GAAAAA
- 5 | FAAAAA
- 4 | EAAAAA
- 3 | DAAAAA
- 2 | CAAAAA
- 1 | BAAAAA
- 0 | AAAAAA
-(20 rows)
-
---
--- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2
---
-SELECT onek.unique1, onek.stringu1 FROM onek
- WHERE onek.unique1 > 980
- ORDER BY stringu1 using <;
- unique1 | stringu1
----------+----------
- 988 | AMAAAA
- 989 | BMAAAA
- 990 | CMAAAA
- 991 | DMAAAA
- 992 | EMAAAA
- 993 | FMAAAA
- 994 | GMAAAA
- 995 | HMAAAA
- 996 | IMAAAA
- 997 | JMAAAA
- 998 | KMAAAA
- 999 | LMAAAA
- 981 | TLAAAA
- 982 | ULAAAA
- 983 | VLAAAA
- 984 | WLAAAA
- 985 | XLAAAA
- 986 | YLAAAA
- 987 | ZLAAAA
-(19 rows)
-
---
--- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data |
--- sort +1d -2 +0nr -1
---
-SELECT onek.unique1, onek.string4 FROM onek
- WHERE onek.unique1 > 980
- ORDER BY string4 using <, unique1 using >;
- unique1 | string4
----------+---------
- 999 | AAAAxx
- 995 | AAAAxx
- 983 | AAAAxx
- 982 | AAAAxx
- 981 | AAAAxx
- 998 | HHHHxx
- 997 | HHHHxx
- 993 | HHHHxx
- 990 | HHHHxx
- 986 | HHHHxx
- 996 | OOOOxx
- 991 | OOOOxx
- 988 | OOOOxx
- 987 | OOOOxx
- 985 | OOOOxx
- 994 | VVVVxx
- 992 | VVVVxx
- 989 | VVVVxx
- 984 | VVVVxx
-(19 rows)
-
---
--- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data |
--- sort +1dr -2 +0n -1
---
-SELECT onek.unique1, onek.string4 FROM onek
- WHERE onek.unique1 > 980
- ORDER BY string4 using >, unique1 using <;
- unique1 | string4
----------+---------
- 984 | VVVVxx
- 989 | VVVVxx
- 992 | VVVVxx
- 994 | VVVVxx
- 985 | OOOOxx
- 987 | OOOOxx
- 988 | OOOOxx
- 991 | OOOOxx
- 996 | OOOOxx
- 986 | HHHHxx
- 990 | HHHHxx
- 993 | HHHHxx
- 997 | HHHHxx
- 998 | HHHHxx
- 981 | AAAAxx
- 982 | AAAAxx
- 983 | AAAAxx
- 995 | AAAAxx
- 999 | AAAAxx
-(19 rows)
-
---
--- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data |
--- sort +0nr -1 +1d -2
---
-SELECT onek.unique1, onek.string4 FROM onek
- WHERE onek.unique1 < 20
- ORDER BY unique1 using >, string4 using <;
- unique1 | string4
----------+---------
- 19 | OOOOxx
- 18 | VVVVxx
- 17 | HHHHxx
- 16 | OOOOxx
- 15 | VVVVxx
- 14 | AAAAxx
- 13 | OOOOxx
- 12 | AAAAxx
- 11 | OOOOxx
- 10 | AAAAxx
- 9 | HHHHxx
- 8 | HHHHxx
- 7 | VVVVxx
- 6 | OOOOxx
- 5 | HHHHxx
- 4 | HHHHxx
- 3 | VVVVxx
- 2 | OOOOxx
- 1 | OOOOxx
- 0 | OOOOxx
-(20 rows)
-
---
--- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data |
--- sort +0n -1 +1dr -2
---
-SELECT onek.unique1, onek.string4 FROM onek
- WHERE onek.unique1 < 20
- ORDER BY unique1 using <, string4 using >;
- unique1 | string4
----------+---------
- 0 | OOOOxx
- 1 | OOOOxx
- 2 | OOOOxx
- 3 | VVVVxx
- 4 | HHHHxx
- 5 | HHHHxx
- 6 | OOOOxx
- 7 | VVVVxx
- 8 | HHHHxx
- 9 | HHHHxx
- 10 | AAAAxx
- 11 | OOOOxx
- 12 | AAAAxx
- 13 | OOOOxx
- 14 | AAAAxx
- 15 | VVVVxx
- 16 | OOOOxx
- 17 | HHHHxx
- 18 | VVVVxx
- 19 | OOOOxx
-(20 rows)
-
---
--- test partial btree indexes
---
--- As of 7.2, planner probably won't pick an indexscan without stats,
--- so ANALYZE first. Also, we want to prevent it from picking a bitmapscan
--- followed by sort, because that could hide index ordering problems.
---
-ANALYZE onek2;
-SET enable_seqscan TO off;
-SET enable_bitmapscan TO off;
-SET enable_sort TO off;
---
--- awk '{if($1<10){print $0;}else{next;}}' onek.data | sort +0n -1
---
-SELECT onek2.* FROM onek2 WHERE onek2.unique1 < 10 ORDER BY unique1;
- unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4
----------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+---------
- 0 | 998 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | AAAAAA | KMBAAA | OOOOxx
- 1 | 214 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 3 | BAAAAA | GIAAAA | OOOOxx
- 2 | 326 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 4 | 5 | CAAAAA | OMAAAA | OOOOxx
- 3 | 431 | 1 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 6 | 7 | DAAAAA | PQAAAA | VVVVxx
- 4 | 833 | 0 | 0 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 8 | 9 | EAAAAA | BGBAAA | HHHHxx
- 5 | 541 | 1 | 1 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 10 | 11 | FAAAAA | VUAAAA | HHHHxx
- 6 | 978 | 0 | 2 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 12 | 13 | GAAAAA | QLBAAA | OOOOxx
- 7 | 647 | 1 | 3 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 14 | 15 | HAAAAA | XYAAAA | VVVVxx
- 8 | 653 | 0 | 0 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 16 | 17 | IAAAAA | DZAAAA | HHHHxx
- 9 | 49 | 1 | 1 | 9 | 9 | 9 | 9 | 9 | 9 | 9 | 18 | 19 | JAAAAA | XBAAAA | HHHHxx
-(10 rows)
-
---
--- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1
---
-SELECT onek2.unique1, onek2.stringu1 FROM onek2
- WHERE onek2.unique1 < 20
- ORDER BY unique1 using >;
- unique1 | stringu1
----------+----------
- 19 | TAAAAA
- 18 | SAAAAA
- 17 | RAAAAA
- 16 | QAAAAA
- 15 | PAAAAA
- 14 | OAAAAA
- 13 | NAAAAA
- 12 | MAAAAA
- 11 | LAAAAA
- 10 | KAAAAA
- 9 | JAAAAA
- 8 | IAAAAA
- 7 | HAAAAA
- 6 | GAAAAA
- 5 | FAAAAA
- 4 | EAAAAA
- 3 | DAAAAA
- 2 | CAAAAA
- 1 | BAAAAA
- 0 | AAAAAA
-(20 rows)
-
---
--- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2
---
-SELECT onek2.unique1, onek2.stringu1 FROM onek2
- WHERE onek2.unique1 > 980
- ORDER BY unique1 using <;
- unique1 | stringu1
----------+----------
- 981 | TLAAAA
- 982 | ULAAAA
- 983 | VLAAAA
- 984 | WLAAAA
- 985 | XLAAAA
- 986 | YLAAAA
- 987 | ZLAAAA
- 988 | AMAAAA
- 989 | BMAAAA
- 990 | CMAAAA
- 991 | DMAAAA
- 992 | EMAAAA
- 993 | FMAAAA
- 994 | GMAAAA
- 995 | HMAAAA
- 996 | IMAAAA
- 997 | JMAAAA
- 998 | KMAAAA
- 999 | LMAAAA
-(19 rows)
-
-RESET enable_seqscan;
-RESET enable_bitmapscan;
-RESET enable_sort;
-SELECT two, stringu1, ten, string4
- INTO TABLE tmp
- FROM onek;
---
--- awk '{print $1,$2;}' person.data |
--- awk '{if(NF!=2){print $3,$2;}else{print;}}' - emp.data |
--- awk '{if(NF!=2){print $3,$2;}else{print;}}' - student.data |
--- awk 'BEGIN{FS=" ";}{if(NF!=2){print $4,$5;}else{print;}}' - stud_emp.data
---
--- SELECT name, age FROM person*; ??? check if different
-SELECT p.name, p.age FROM person* p
- ORDER BY p.name, p.age;
- name | age
----------+-----
- alex | 30
- belinda | 38
- bertha | 88
- bill | 20
- carina | 58
- carmen | 78
- chris | 78
- cim | 30
- denise | 24
- diane | 18
- edna | 18
- esther | 98
- fanny | 8
- fred | 28
- gina | 18
- jane | 58
- jean | 28
- jeff | 23
- jenifer | 38
- joan | 18
- joe | 20
- juanita | 58
- julie | 68
- karen | 48
- koko | 88
- larry | 60
- leah | 68
- linda | 19
- lita | 25
- liza | 38
- louise | 98
- martie | 88
- mary | 8
- melissa | 28
- mike | 40
- nan | 28
- pamela | 48
- pat | 18
- paula | 68
- rean | 48
- sally | 34
- sam | 30
- sandra | 19
- sandy | 38
- sarah | 88
- sharon | 25
- sharon | 78
- sue | 50
- sumi | 38
- susan | 78
- teresa | 38
- trisha | 88
- trudy | 88
- uma | 78
- velma | 68
- wendy | 78
- zena | 98
- zola | 58
-(58 rows)
-
---
--- awk '{print $1,$2;}' person.data |
--- awk '{if(NF!=2){print $3,$2;}else{print;}}' - emp.data |
--- awk '{if(NF!=2){print $3,$2;}else{print;}}' - student.data |
--- awk 'BEGIN{FS=" ";}{if(NF!=1){print $4,$5;}else{print;}}' - stud_emp.data |
--- sort +1nr -2
---
-SELECT p.name, p.age FROM person* p ORDER BY age using >, name;
- name | age
----------+-----
- esther | 98
- louise | 98
- zena | 98
- bertha | 88
- koko | 88
- martie | 88
- sarah | 88
- trisha | 88
- trudy | 88
- carmen | 78
- chris | 78
- sharon | 78
- susan | 78
- uma | 78
- wendy | 78
- julie | 68
- leah | 68
- paula | 68
- velma | 68
- larry | 60
- carina | 58
- jane | 58
- juanita | 58
- zola | 58
- sue | 50
- karen | 48
- pamela | 48
- rean | 48
- mike | 40
- belinda | 38
- jenifer | 38
- liza | 38
- sandy | 38
- sumi | 38
- teresa | 38
- sally | 34
- alex | 30
- cim | 30
- sam | 30
- fred | 28
- jean | 28
- melissa | 28
- nan | 28
- lita | 25
- sharon | 25
- denise | 24
- jeff | 23
- bill | 20
- joe | 20
- linda | 19
- sandra | 19
- diane | 18
- edna | 18
- gina | 18
- joan | 18
- pat | 18
- fanny | 8
- mary | 8
-(58 rows)
-
---
--- Test some cases involving whole-row Var referencing a subquery
---
-select foo from (select 1) as foo;
- foo
------
- (1)
-(1 row)
-
-select foo from (select null) as foo;
- foo
------
- ()
-(1 row)
-
-select foo from (select 'xyzzy',1,null) as foo;
- foo
-------------
- (xyzzy,1,)
-(1 row)
-
---
--- Test VALUES lists
---
-select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j)
- WHERE onek.unique1 = v.i and onek.stringu1 = v.j
- ORDER BY unique1;
- unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 | i | j
----------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+---------+-----+--------
- 147 | 0 | 1 | 3 | 7 | 7 | 7 | 47 | 147 | 147 | 147 | 14 | 15 | RFAAAA | AAAAAA | AAAAxx | 147 | RFAAAA
- 931 | 1 | 1 | 3 | 1 | 11 | 1 | 31 | 131 | 431 | 931 | 2 | 3 | VJAAAA | BAAAAA | HHHHxx | 931 | VJAAAA
-(2 rows)
-
--- a more complex case
--- looks like we're coding lisp :-)
-select * from onek,
- (values ((select i from
- (values(10000), (2), (389), (1000), (2000), ((select 10029))) as foo(i)
- order by i asc limit 1))) bar (i)
- where onek.unique1 = bar.i
- ORDER BY unique1;
- unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 | i
----------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+---------+---
- 2 | 326 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 4 | 5 | CAAAAA | OMAAAA | OOOOxx | 2
-(1 row)
-
--- try VALUES in a subquery
-select * from onek
- where (unique1,ten) in (values (1,1), (20,0), (99,9), (17,99))
- order by unique1;
- unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4
----------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+---------
- 1 | 214 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 3 | BAAAAA | GIAAAA | OOOOxx
- 20 | 306 | 0 | 0 | 0 | 0 | 0 | 20 | 20 | 20 | 20 | 0 | 1 | UAAAAA | ULAAAA | OOOOxx
- 99 | 101 | 1 | 3 | 9 | 19 | 9 | 99 | 99 | 99 | 99 | 18 | 19 | VDAAAA | XDAAAA | HHHHxx
-(3 rows)
-
--- VALUES is also legal as a standalone query or a set-operation member
-VALUES (1,2), (3,4+4), (7,77.7);
- column1 | column2
----------+---------
- 1 | 2
- 3 | 8
- 7 | 77.7
-(3 rows)
-
-VALUES (1,2), (3,4+4), (7,77.7)
-UNION ALL
-SELECT 2+2, 57
-UNION ALL
-TABLE int8_tbl
-ORDER BY column1,column2;
- column1 | column2
-------------------+-------------------
- 1 | 2
- 3 | 8
- 4 | 57
- 7 | 77.7
- 123 | 456
- 123 | 4567890123456789
- 4567890123456789 | -4567890123456789
- 4567890123456789 | 123
- 4567890123456789 | 4567890123456789
-(9 rows)
-
---
--- Test ORDER BY options
---
-CREATE TEMP TABLE foo (f1 int);
-INSERT INTO foo VALUES (42),(3),(10),(7),(null),(null),(1);
-SELECT * FROM foo ORDER BY f1;
- f1
-----
- 1
- 3
- 7
- 10
- 42
-
-
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 ASC; -- same thing
- f1
-----
- 1
- 3
- 7
- 10
- 42
-
-
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 NULLS FIRST;
- f1
-----
-
-
- 1
- 3
- 7
- 10
- 42
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 DESC;
- f1
-----
-
-
- 42
- 10
- 7
- 3
- 1
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 DESC NULLS LAST;
- f1
-----
- 42
- 10
- 7
- 3
- 1
-
-
-(7 rows)
-
--- check if indexscans do the right things
-CREATE INDEX fooi ON foo (f1);
-SET enable_sort = false;
-SELECT * FROM foo ORDER BY f1;
- f1
-----
- 1
- 3
- 7
- 10
- 42
-
-
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 NULLS FIRST;
- f1
-----
-
-
- 1
- 3
- 7
- 10
- 42
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 DESC;
- f1
-----
-
-
- 42
- 10
- 7
- 3
- 1
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 DESC NULLS LAST;
- f1
-----
- 42
- 10
- 7
- 3
- 1
-
-
-(7 rows)
-
-DROP INDEX fooi;
-CREATE INDEX fooi ON foo (f1 DESC);
-SELECT * FROM foo ORDER BY f1;
- f1
-----
- 1
- 3
- 7
- 10
- 42
-
-
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 NULLS FIRST;
- f1
-----
-
-
- 1
- 3
- 7
- 10
- 42
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 DESC;
- f1
-----
-
-
- 42
- 10
- 7
- 3
- 1
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 DESC NULLS LAST;
- f1
-----
- 42
- 10
- 7
- 3
- 1
-
-
-(7 rows)
-
-DROP INDEX fooi;
-CREATE INDEX fooi ON foo (f1 DESC NULLS LAST);
-SELECT * FROM foo ORDER BY f1;
- f1
-----
- 1
- 3
- 7
- 10
- 42
-
-
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 NULLS FIRST;
- f1
-----
-
-
- 1
- 3
- 7
- 10
- 42
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 DESC;
- f1
-----
-
-
- 42
- 10
- 7
- 3
- 1
-(7 rows)
-
-SELECT * FROM foo ORDER BY f1 DESC NULLS LAST;
- f1
-----
- 42
- 10
- 7
- 3
- 1
-
-
-(7 rows)
-
---
--- Test some corner cases that have been known to confuse the planner
---
--- ORDER BY on a constant doesn't really need any sorting
-SELECT 1 AS x ORDER BY x;
- x
----
- 1
-(1 row)
-
--- But ORDER BY on a set-valued expression does
-create function sillysrf(int) returns setof int as
- 'values (1),(10),(2),($1)' language sql immutable;
-select sillysrf(42) order by 1;
- sillysrf
-----------
- 1
- 2
- 10
- 42
-(4 rows)
-
-select sillysrf(-1) order by 1;
- sillysrf
-----------
- -1
- 1
- 2
- 10
-(4 rows)
-
-drop function sillysrf(int);
--- X = X isn't a no-op, it's effectively X IS NOT NULL assuming = is strict
--- (see bug #5084)
-select * from (values (2),(null),(1)) v(k) where k = k order by k;
- k
----
- 1
- 2
-(2 rows)
-
-select * from (values (2),(null),(1)) v(k) where k = k order by k desc;
- k
----
- 2
- 1
-(2 rows)
-
+++ /dev/null
---
--- SELECT_IMPLICIT
--- Test cases for queries with ordering terms missing from the target list.
--- This used to be called "junkfilter.sql".
--- The parser uses the term "resjunk" to handle these cases.
--- - thomas 1998-07-09
---
--- load test data
-CREATE TABLE test_missing_target (a int, b int, c char(8), d char);
-INSERT INTO test_missing_target VALUES (0, 1, 'XXXX', 'A');
-INSERT INTO test_missing_target VALUES (1, 2, 'ABAB', 'b');
-INSERT INTO test_missing_target VALUES (2, 2, 'ABAB', 'c');
-INSERT INTO test_missing_target VALUES (3, 3, 'BBBB', 'D');
-INSERT INTO test_missing_target VALUES (4, 3, 'BBBB', 'e');
-INSERT INTO test_missing_target VALUES (5, 3, 'bbbb', 'F');
-INSERT INTO test_missing_target VALUES (6, 4, 'cccc', 'g');
-INSERT INTO test_missing_target VALUES (7, 4, 'cccc', 'h');
-INSERT INTO test_missing_target VALUES (8, 4, 'CCCC', 'I');
-INSERT INTO test_missing_target VALUES (9, 4, 'CCCC', 'j');
--- w/ existing GROUP BY target
-SELECT c, count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c;
- c | count
-----------+-------
- ABAB | 2
- bbbb | 1
- BBBB | 2
- cccc | 2
- CCCC | 2
- XXXX | 1
-(6 rows)
-
--- w/o existing GROUP BY target using a relation name in GROUP BY clause
-SELECT count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c;
- count
--------
- 2
- 1
- 2
- 2
- 2
- 1
-(6 rows)
-
--- w/o existing GROUP BY target and w/o existing a different ORDER BY target
--- failure expected
-SELECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
-ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
-LINE 1: ...ECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
- ^
--- w/o existing GROUP BY target and w/o existing same ORDER BY target
-SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b;
- count
--------
- 1
- 2
- 3
- 4
-(4 rows)
-
--- w/ existing GROUP BY target using a relation name in target
-SELECT test_missing_target.b, count(*)
- FROM test_missing_target GROUP BY b ORDER BY b;
- b | count
----+-------
- 1 | 1
- 2 | 2
- 3 | 3
- 4 | 4
-(4 rows)
-
--- w/o existing GROUP BY target
-SELECT c FROM test_missing_target ORDER BY a;
- c
-----------
- XXXX
- ABAB
- ABAB
- BBBB
- BBBB
- bbbb
- cccc
- cccc
- CCCC
- CCCC
-(10 rows)
-
--- w/o existing ORDER BY target
-SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b desc;
- count
--------
- 4
- 3
- 2
- 1
-(4 rows)
-
--- group using reference number
-SELECT count(*) FROM test_missing_target ORDER BY 1 desc;
- count
--------
- 10
-(1 row)
-
--- order using reference number
-SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1;
- c | count
-----------+-------
- ABAB | 2
- bbbb | 1
- BBBB | 2
- cccc | 2
- CCCC | 2
- XXXX | 1
-(6 rows)
-
--- group using reference number out of range
--- failure expected
-SELECT c, count(*) FROM test_missing_target GROUP BY 3;
-ERROR: GROUP BY position 3 is not in select list
-LINE 1: SELECT c, count(*) FROM test_missing_target GROUP BY 3;
- ^
--- group w/o existing GROUP BY and ORDER BY target under ambiguous condition
--- failure expected
-SELECT count(*) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY b ORDER BY b;
-ERROR: column reference "b" is ambiguous
-LINE 3: GROUP BY b ORDER BY b;
- ^
--- order w/ target under ambiguous condition
--- failure NOT expected
-SELECT a, a FROM test_missing_target
- ORDER BY a;
- a | a
----+---
- 0 | 0
- 1 | 1
- 2 | 2
- 3 | 3
- 4 | 4
- 5 | 5
- 6 | 6
- 7 | 7
- 8 | 8
- 9 | 9
-(10 rows)
-
--- order expression w/ target under ambiguous condition
--- failure NOT expected
-SELECT a/2, a/2 FROM test_missing_target
- ORDER BY a/2;
- ?column? | ?column?
-----------+----------
- 0 | 0
- 0 | 0
- 1 | 1
- 1 | 1
- 2 | 2
- 2 | 2
- 3 | 3
- 3 | 3
- 4 | 4
- 4 | 4
-(10 rows)
-
--- group expression w/ target under ambiguous condition
--- failure NOT expected
-SELECT a/2, a/2 FROM test_missing_target
- GROUP BY a/2 ORDER BY a/2;
- ?column? | ?column?
-----------+----------
- 0 | 0
- 1 | 1
- 2 | 2
- 3 | 3
- 4 | 4
-(5 rows)
-
--- group w/ existing GROUP BY target under ambiguous condition
-SELECT x.b, count(*) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b ORDER BY x.b;
- b | count
----+-------
- 1 | 1
- 2 | 2
- 3 | 3
- 4 | 4
-(4 rows)
-
--- group w/o existing GROUP BY target under ambiguous condition
-SELECT count(*) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b ORDER BY x.b;
- count
--------
- 1
- 2
- 3
- 4
-(4 rows)
-
--- group w/o existing GROUP BY target under ambiguous condition
--- into a table
-SELECT count(*) INTO TABLE test_missing_target2
-FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b ORDER BY x.b;
-SELECT * FROM test_missing_target2 ORDER BY 1;
- count
--------
- 1
- 2
- 3
- 4
-(4 rows)
-
--- Functions and expressions
--- w/ existing GROUP BY target
-SELECT a%2, count(b) FROM test_missing_target
-GROUP BY test_missing_target.a%2
-ORDER BY test_missing_target.a%2;
- ?column? | count
-----------+-------
- 0 | 5
- 1 | 5
-(2 rows)
-
--- w/o existing GROUP BY target using a relation name in GROUP BY clause
-SELECT count(c) FROM test_missing_target
-GROUP BY lower(test_missing_target.c)
-ORDER BY lower(test_missing_target.c);
- count
--------
- 2
- 3
- 4
- 1
-(4 rows)
-
--- w/o existing GROUP BY target and w/o existing a different ORDER BY target
--- failure expected
-SELECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
-ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
-LINE 1: ...ECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
- ^
--- w/o existing GROUP BY target and w/o existing same ORDER BY target
-SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2;
- count
--------
- 1
- 5
- 4
-(3 rows)
-
--- w/ existing GROUP BY target using a relation name in target
-SELECT lower(test_missing_target.c), count(c)
- FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c);
- lower | count
--------+-------
- abab | 2
- bbbb | 3
- cccc | 4
- xxxx | 1
-(4 rows)
-
--- w/o existing GROUP BY target
-SELECT a FROM test_missing_target ORDER BY upper(d);
- a
----
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-(10 rows)
-
--- w/o existing ORDER BY target
-SELECT count(b) FROM test_missing_target
- GROUP BY (b + 1) / 2 ORDER BY (b + 1) / 2 desc;
- count
--------
- 7
- 3
-(2 rows)
-
--- group w/o existing GROUP BY and ORDER BY target under ambiguous condition
--- failure expected
-SELECT count(x.a) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY b/2 ORDER BY b/2;
-ERROR: column reference "b" is ambiguous
-LINE 3: GROUP BY b/2 ORDER BY b/2;
- ^
--- group w/ existing GROUP BY target under ambiguous condition
-SELECT x.b/2, count(x.b) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b/2 ORDER BY x.b/2;
- ?column? | count
-----------+-------
- 0 | 1
- 1 | 5
- 2 | 4
-(3 rows)
-
--- group w/o existing GROUP BY target under ambiguous condition
--- failure expected due to ambiguous b in count(b)
-SELECT count(b) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b/2;
-ERROR: column reference "b" is ambiguous
-LINE 1: SELECT count(b) FROM test_missing_target x, test_missing_tar...
- ^
--- group w/o existing GROUP BY target under ambiguous condition
--- into a table
-SELECT count(x.b) INTO TABLE test_missing_target3
-FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b/2 ORDER BY x.b/2;
-SELECT * FROM test_missing_target3 ORDER BY 1;
- count
--------
- 1
- 4
- 5
-(3 rows)
-
--- Cleanup
-DROP TABLE test_missing_target;
-DROP TABLE test_missing_target2;
-DROP TABLE test_missing_target3;
+++ /dev/null
---
--- SELECT_IMPLICIT
--- Test cases for queries with ordering terms missing from the target list.
--- This used to be called "junkfilter.sql".
--- The parser uses the term "resjunk" to handle these cases.
--- - thomas 1998-07-09
---
--- load test data
-CREATE TABLE test_missing_target (a int, b int, c char(8), d char);
-INSERT INTO test_missing_target VALUES (0, 1, 'XXXX', 'A');
-INSERT INTO test_missing_target VALUES (1, 2, 'ABAB', 'b');
-INSERT INTO test_missing_target VALUES (2, 2, 'ABAB', 'c');
-INSERT INTO test_missing_target VALUES (3, 3, 'BBBB', 'D');
-INSERT INTO test_missing_target VALUES (4, 3, 'BBBB', 'e');
-INSERT INTO test_missing_target VALUES (5, 3, 'bbbb', 'F');
-INSERT INTO test_missing_target VALUES (6, 4, 'cccc', 'g');
-INSERT INTO test_missing_target VALUES (7, 4, 'cccc', 'h');
-INSERT INTO test_missing_target VALUES (8, 4, 'CCCC', 'I');
-INSERT INTO test_missing_target VALUES (9, 4, 'CCCC', 'j');
--- w/ existing GROUP BY target
-SELECT c, count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c;
- c | count
-----------+-------
- ABAB | 2
- BBBB | 2
- CCCC | 2
- XXXX | 1
- bbbb | 1
- cccc | 2
-(6 rows)
-
--- w/o existing GROUP BY target using a relation name in GROUP BY clause
-SELECT count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c;
- count
--------
- 2
- 2
- 2
- 1
- 1
- 2
-(6 rows)
-
--- w/o existing GROUP BY target and w/o existing a different ORDER BY target
--- failure expected
-SELECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
-ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
-LINE 1: ...ECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
- ^
--- w/o existing GROUP BY target and w/o existing same ORDER BY target
-SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b;
- count
--------
- 1
- 2
- 3
- 4
-(4 rows)
-
--- w/ existing GROUP BY target using a relation name in target
-SELECT test_missing_target.b, count(*)
- FROM test_missing_target GROUP BY b ORDER BY b;
- b | count
----+-------
- 1 | 1
- 2 | 2
- 3 | 3
- 4 | 4
-(4 rows)
-
--- w/o existing GROUP BY target
-SELECT c FROM test_missing_target ORDER BY a;
- c
-----------
- XXXX
- ABAB
- ABAB
- BBBB
- BBBB
- bbbb
- cccc
- cccc
- CCCC
- CCCC
-(10 rows)
-
--- w/o existing ORDER BY target
-SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b desc;
- count
--------
- 4
- 3
- 2
- 1
-(4 rows)
-
--- group using reference number
-SELECT count(*) FROM test_missing_target ORDER BY 1 desc;
- count
--------
- 10
-(1 row)
-
--- order using reference number
-SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1;
- c | count
-----------+-------
- ABAB | 2
- BBBB | 2
- CCCC | 2
- XXXX | 1
- bbbb | 1
- cccc | 2
-(6 rows)
-
--- group using reference number out of range
--- failure expected
-SELECT c, count(*) FROM test_missing_target GROUP BY 3;
-ERROR: GROUP BY position 3 is not in select list
-LINE 1: SELECT c, count(*) FROM test_missing_target GROUP BY 3;
- ^
--- group w/o existing GROUP BY and ORDER BY target under ambiguous condition
--- failure expected
-SELECT count(*) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY b ORDER BY b;
-ERROR: column reference "b" is ambiguous
-LINE 3: GROUP BY b ORDER BY b;
- ^
--- order w/ target under ambiguous condition
--- failure NOT expected
-SELECT a, a FROM test_missing_target
- ORDER BY a;
- a | a
----+---
- 0 | 0
- 1 | 1
- 2 | 2
- 3 | 3
- 4 | 4
- 5 | 5
- 6 | 6
- 7 | 7
- 8 | 8
- 9 | 9
-(10 rows)
-
--- order expression w/ target under ambiguous condition
--- failure NOT expected
-SELECT a/2, a/2 FROM test_missing_target
- ORDER BY a/2;
- ?column? | ?column?
-----------+----------
- 0 | 0
- 0 | 0
- 1 | 1
- 1 | 1
- 2 | 2
- 2 | 2
- 3 | 3
- 3 | 3
- 4 | 4
- 4 | 4
-(10 rows)
-
--- group expression w/ target under ambiguous condition
--- failure NOT expected
-SELECT a/2, a/2 FROM test_missing_target
- GROUP BY a/2 ORDER BY a/2;
- ?column? | ?column?
-----------+----------
- 0 | 0
- 1 | 1
- 2 | 2
- 3 | 3
- 4 | 4
-(5 rows)
-
--- group w/ existing GROUP BY target under ambiguous condition
-SELECT x.b, count(*) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b ORDER BY x.b;
- b | count
----+-------
- 1 | 1
- 2 | 2
- 3 | 3
- 4 | 4
-(4 rows)
-
--- group w/o existing GROUP BY target under ambiguous condition
-SELECT count(*) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b ORDER BY x.b;
- count
--------
- 1
- 2
- 3
- 4
-(4 rows)
-
--- group w/o existing GROUP BY target under ambiguous condition
--- into a table
-SELECT count(*) INTO TABLE test_missing_target2
-FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b ORDER BY x.b;
-SELECT * FROM test_missing_target2 ORDER BY 1;
- count
--------
- 1
- 2
- 3
- 4
-(4 rows)
-
--- Functions and expressions
--- w/ existing GROUP BY target
-SELECT a%2, count(b) FROM test_missing_target
-GROUP BY test_missing_target.a%2
-ORDER BY test_missing_target.a%2;
- ?column? | count
-----------+-------
- 0 | 5
- 1 | 5
-(2 rows)
-
--- w/o existing GROUP BY target using a relation name in GROUP BY clause
-SELECT count(c) FROM test_missing_target
-GROUP BY lower(test_missing_target.c)
-ORDER BY lower(test_missing_target.c);
- count
--------
- 2
- 3
- 4
- 1
-(4 rows)
-
--- w/o existing GROUP BY target and w/o existing a different ORDER BY target
--- failure expected
-SELECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
-ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
-LINE 1: ...ECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
- ^
--- w/o existing GROUP BY target and w/o existing same ORDER BY target
-SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2;
- count
--------
- 1
- 5
- 4
-(3 rows)
-
--- w/ existing GROUP BY target using a relation name in target
-SELECT lower(test_missing_target.c), count(c)
- FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c);
- lower | count
--------+-------
- abab | 2
- bbbb | 3
- cccc | 4
- xxxx | 1
-(4 rows)
-
--- w/o existing GROUP BY target
-SELECT a FROM test_missing_target ORDER BY upper(d);
- a
----
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-(10 rows)
-
--- w/o existing ORDER BY target
-SELECT count(b) FROM test_missing_target
- GROUP BY (b + 1) / 2 ORDER BY (b + 1) / 2 desc;
- count
--------
- 7
- 3
-(2 rows)
-
--- group w/o existing GROUP BY and ORDER BY target under ambiguous condition
--- failure expected
-SELECT count(x.a) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY b/2 ORDER BY b/2;
-ERROR: column reference "b" is ambiguous
-LINE 3: GROUP BY b/2 ORDER BY b/2;
- ^
--- group w/ existing GROUP BY target under ambiguous condition
-SELECT x.b/2, count(x.b) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b/2 ORDER BY x.b/2;
- ?column? | count
-----------+-------
- 0 | 1
- 1 | 5
- 2 | 4
-(3 rows)
-
--- group w/o existing GROUP BY target under ambiguous condition
--- failure expected due to ambiguous b in count(b)
-SELECT count(b) FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b/2;
-ERROR: column reference "b" is ambiguous
-LINE 1: SELECT count(b) FROM test_missing_target x, test_missing_tar...
- ^
--- group w/o existing GROUP BY target under ambiguous condition
--- into a table
-SELECT count(x.b) INTO TABLE test_missing_target3
-FROM test_missing_target x, test_missing_target y
- WHERE x.a = y.a
- GROUP BY x.b/2 ORDER BY x.b/2;
-SELECT * FROM test_missing_target3 ORDER BY 1;
- count
--------
- 1
- 4
- 5
-(3 rows)
-
--- Cleanup
-DROP TABLE test_missing_target;
-DROP TABLE test_missing_target2;
-DROP TABLE test_missing_target3;
+++ /dev/null
---
--- SELECT_VIEWS
--- test the views defined in CREATE_VIEWS
---
-SELECT * FROM street ORDER BY name,cname,thepath::text;
- name | thepath | cname
-------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------
- 100th Ave | [(-122.1657,37.429),(-122.1647,37.432)] | Oakland
- 107th Ave | [(-122.1555,37.403),(-122.1531,37.41)] | Oakland
- 14th St | [(-122.299,37.147),(-122.3,37.148)] | Lafayette
- 19th Ave | [(-122.2366,37.897),(-122.2359,37.905)] | Berkeley
- 1st St | [(-121.75508,37.89294),(-121.753581,37.90031)] | Oakland
- 5th St | [(-122.296,37.615),(-122.2953,37.598)] | Berkeley
- 5th St | [(-122.278,37),(-122.2792,37.005),(-122.2803,37.009)] | Lafayette
- 82nd Ave | [(-122.1695,37.596),(-122.1681,37.603)] | Berkeley
- 85th Ave | [(-122.1877,37.466),(-122.186,37.476)] | Oakland
- 89th Ave | [(-122.1822,37.459),(-122.1803,37.471)] | Oakland
- 98th Ave | [(-122.2001,37.258),(-122.1974,37.27)] | Lafayette
- 98th Ave | [(-122.1568,37.498),(-122.1558,37.502)] | Oakland
- 98th Ave | [(-122.1693,37.438),(-122.1682,37.444)] | Oakland
- Access Rd 25 | [(-121.9283,37.894),(-121.9283,37.9)] | Oakland
- Ada St | [(-122.2487,37.398),(-122.2496,37.401)] | Lafayette
- Agua Fria Creek | [(-121.9254,37.922),(-121.9281,37.889)] | Oakland
- Allen Ct | [(-122.0131,37.602),(-122.0117,37.597)] | Berkeley
- Alvarado Niles Road | [(-122.0325,37.903),(-122.0316,37.9)] | Berkeley
- Andrea Cir | [(-121.733218,37.88641),(-121.733286,37.90617)] | Oakland
- Apricot Lane | [(-121.9471,37.401),(-121.9456,37.392)] | Oakland
- Apricot Lane | [(-121.9471,37.401),(-121.9456,37.392)] | Oakland
- Arden Road | [(-122.0978,37.177),(-122.1,37.177)] | Oakland
- Arizona St | [(-122.0381,37.901),(-122.0367,37.898)] | Berkeley
- Arlington Dr | [(-121.8802,37.408),(-121.8807,37.394)] | Oakland
- Arlington Dr | [(-121.8802,37.408),(-121.8807,37.394)] | Oakland
- Arlington Road | [(-121.7957,37.898),(-121.7956,37.906)] | Oakland
- Arroyo Las Positas | [(-121.7973,37.997),(-121.7957,37.005)] | Oakland
- Arroyo Las Positas | [(-121.7973,37.997),(-121.7957,37.005)] | Oakland
- Arroyo Seco | [(-121.7073,37.766),(-121.6997,37.729)] | Oakland
- Ash St | [(-122.0408,37.31),(-122.04,37.292)] | Oakland
- Avenue 134th | [(-122.1823,37.002),(-122.1851,37.992)] | Berkeley
- Avenue 134th | [(-122.1823,37.002),(-122.1851,37.992)] | Oakland
- Avenue 140th | [(-122.1656,37.003),(-122.1691,37.988)] | Berkeley
- Avenue 140th | [(-122.1656,37.003),(-122.1691,37.988)] | Oakland
- Avenue D | [(-122.298,37.848),(-122.3024,37.849)] | Berkeley
- B St | [(-122.1749,37.451),(-122.1743,37.443)] | Oakland
- Bancroft Ave | [(-122.15714,37.4242),(-122.156,37.409)] | Oakland
- Bancroft Ave | [(-122.1643,37.523),(-122.1631,37.508),(-122.1621,37.493)] | Oakland
- Birch St | [(-122.1617,37.425),(-122.1614,37.417)] | Oakland
- Birch St | [(-122.1673,37.509),(-122.1661,37.492)] | Oakland
- Blacow Road | [(-122.0179,37.469),(-122.0167,37.465)] | Oakland
- Bridgepointe Dr | [(-122.0514,37.305),(-122.0509,37.299)] | Oakland
- Broadmore Ave | [(-122.095,37.522),(-122.0936,37.497)] | Oakland
- Broadway | [(-122.2409,37.586),(-122.2395,37.601)] | Berkeley
- Buckingham Blvd | [(-122.2231,37.59),(-122.2214,37.606)] | Berkeley
- Butterfield Dr | [(-122.0838,37.002),(-122.0834,37.987)] | Berkeley
- Butterfield Dr | [(-122.0838,37.002),(-122.0834,37.987)] | Oakland
- Butterfield Dr | [(-122.0838,37.002),(-122.0834,37.987)] | Oakland
- C St | [(-122.1768,37.46),(-122.1749,37.435)] | Oakland
- Calaveras Creek | [(-121.8203,37.035),(-121.8207,37.931)] | Oakland
- Calaveras Creek | [(-121.8203,37.035),(-121.8207,37.931)] | Oakland
- California St | [(-122.2032,37.005),(-122.2016,37.996)] | Berkeley
- California St | [(-122.2032,37.005),(-122.2016,37.996)] | Lafayette
- Cameron Ave | [(-122.1316,37.502),(-122.1327,37.481)] | Oakland
- Campus Dr | [(-122.1704,37.905),(-122.1678,37.868),(-122.1671,37.865)] | Berkeley
- Capricorn Ave | [(-122.2176,37.404),(-122.2164,37.384)] | Lafayette
- Carson St | [(-122.1846,37.9),(-122.1843,37.901)] | Berkeley
- Cedar Blvd | [(-122.0282,37.446),(-122.0265,37.43)] | Oakland
- Cedar St | [(-122.3011,37.737),(-122.2999,37.739)] | Berkeley
- Celia St | [(-122.0611,37.3),(-122.0616,37.299)] | Oakland
- Central Ave | [(-122.2343,37.602),(-122.2331,37.595)] | Berkeley
- Chambers Dr | [(-122.2004,37.352),(-122.1972,37.368)] | Lafayette
- Chambers Lane | [(-122.2001,37.359),(-122.1975,37.371)] | Lafayette
- Champion St | [(-122.214,37.991),(-122.2147,37.002)] | Berkeley
- Champion St | [(-122.214,37.991),(-122.2147,37.002)] | Lafayette
- Chapman Dr | [(-122.0421,37.504),(-122.0414,37.498)] | Oakland
- Charles St | [(-122.0255,37.505),(-122.0252,37.499)] | Oakland
- Cherry St | [(-122.0437,37.42),(-122.0434,37.413)] | Oakland
- Claremont Pl | [(-122.0542,37.995),(-122.0542,37.008)] | Berkeley
- Claremont Pl | [(-122.0542,37.995),(-122.0542,37.008)] | Oakland
- Claremont Pl | [(-122.0542,37.995),(-122.0542,37.008)] | Oakland
- Coliseum Way | [(-122.2113,37.626),(-122.2085,37.592),(-122.2063,37.568)] | Berkeley
- Coliseum Way | [(-122.2001,37.47),(-122.1978,37.516)] | Oakland
- Coolidge Ave | [(-122.2007,37.058),(-122.1992,37.06)] | Lafayette
- Cornell Ave | [(-122.2956,37.925),(-122.2949,37.906),(-122.2939,37.875)] | Berkeley
- Corriea Way | [(-121.9501,37.402),(-121.9505,37.398)] | Oakland
- Corriea Way | [(-121.9501,37.402),(-121.9505,37.398)] | Oakland
- Cowing Road | [(-122.0002,37.934),(-121.9772,37.782)] | Oakland
- Creston Road | [(-122.2639,37.002),(-122.2613,37.986),(-122.2602,37.978),(-122.2598,37.973)] | Berkeley
- Creston Road | [(-122.2639,37.002),(-122.2613,37.986),(-122.2602,37.978),(-122.2598,37.973)] | Lafayette
- Crow Canyon Creek | [(-122.043,37.905),(-122.0368,37.71)] | Berkeley
- Crystaline Dr | [(-121.925856,37),(-121.925869,37.00527)] | Oakland
- Cull Canyon Road | [(-122.0536,37.435),(-122.0499,37.315)] | Oakland
- Cull Creek | [(-122.0624,37.875),(-122.0582,37.527)] | Berkeley
- D St | [(-122.1811,37.505),(-122.1805,37.497)] | Oakland
- Decoto Road | [(-122.0159,37.006),(-122.016,37.002),(-122.0164,37.993)] | Berkeley
- Decoto Road | [(-122.0159,37.006),(-122.016,37.002),(-122.0164,37.993)] | Oakland
- Decoto Road | [(-122.0159,37.006),(-122.016,37.002),(-122.0164,37.993)] | Oakland
- Deering St | [(-122.2146,37.904),(-122.2126,37.897)] | Berkeley
- Dimond Ave | [(-122.2167,37.994),(-122.2162,37.006)] | Berkeley
- Dimond Ave | [(-122.2167,37.994),(-122.2162,37.006)] | Lafayette
- Donna Way | [(-122.1333,37.606),(-122.1316,37.599)] | Berkeley
- Driftwood Dr | [(-122.0109,37.482),(-122.0113,37.477)] | Oakland
- Driscoll Road | [(-121.9482,37.403),(-121.948451,37.39995)] | Oakland
- Driscoll Road | [(-121.9482,37.403),(-121.948451,37.39995)] | Oakland
- E St | [(-122.1832,37.505),(-122.1826,37.498),(-122.182,37.49)] | Oakland
- Eden Ave | [(-122.1143,37.505),(-122.1142,37.491)] | Oakland
- Eden Creek | [(-122.022037,37.00675),(-122.0221,37.998)] | Berkeley
- Eden Creek | [(-122.022037,37.00675),(-122.0221,37.998)] | Oakland
- Eden Creek | [(-122.022037,37.00675),(-122.0221,37.998)] | Oakland
- Edgewater Dr | [(-122.201,37.379),(-122.2042,37.41)] | Lafayette
- Enos Way | [(-121.7677,37.896),(-121.7673,37.91)] | Oakland
- Euclid Ave | [(-122.2671,37.009),(-122.2666,37.987)] | Berkeley
- Euclid Ave | [(-122.2671,37.009),(-122.2666,37.987)] | Lafayette
- Fairview Ave | [(-121.999,37.428),(-121.9863,37.351)] | Oakland
- Fairview Ave | [(-121.999,37.428),(-121.9863,37.351)] | Oakland
- Foothill Blvd | [(-122.2414,37.9),(-122.2403,37.893)] | Berkeley
- Fountain St | [(-122.2306,37.593),(-122.2293,37.605)] | Berkeley
- Gading Road | [(-122.0801,37.343),(-122.08,37.336)] | Oakland
- Grizzly Peak Blvd | [(-122.2213,37.638),(-122.2127,37.581)] | Berkeley
- Grove Way | [(-122.0643,37.884),(-122.062679,37.89162),(-122.061796,37.89578),(-122.0609,37.9)] | Berkeley
- Harris Road | [(-122.0659,37.372),(-122.0675,37.363)] | Oakland
- Heartwood Dr | [(-122.2006,37.341),(-122.1992,37.338)] | Lafayette
- Hegenberger Exwy | [(-122.1946,37.52),(-122.1947,37.497)] | Oakland
- Herrier St | [(-122.1943,37.006),(-122.1936,37.998)] | Berkeley
- Herrier St | [(-122.1943,37.006),(-122.1936,37.998)] | Oakland
- Hesperian Blvd | [(-122.1132,37.6),(-122.1123,37.586)] | Berkeley
- Hesperian Blvd | [(-122.097,37.333),(-122.0956,37.31),(-122.0946,37.293)] | Oakland
- Hesperian Blvd | [(-122.097,37.333),(-122.0956,37.31),(-122.0946,37.293)] | Oakland
- Hollis St | [(-122.2885,37.397),(-122.289,37.414)] | Lafayette
- I- 580 | [(-122.1108,37.023),(-122.1101,37.02),(-122.108103,37.00764),(-122.108,37.007),(-122.1069,37.998),(-122.1064,37.994),(-122.1053,37.982),(-122.1048,37.977),(-122.1032,37.958),(-122.1026,37.953),(-122.1013,37.938),(-122.0989,37.911),(-122.0984,37.91),(-122.098,37.908)] | Berkeley
- I- 580 | [(-122.1543,37.703),(-122.1535,37.694),(-122.1512,37.655),(-122.1475,37.603),(-122.1468,37.583),(-122.1472,37.569),(-122.149044,37.54874),(-122.1493,37.546),(-122.1501,37.532),(-122.1506,37.509),(-122.1495,37.482),(-122.1487,37.467),(-122.1477,37.447),(-122.1414,37.383),(-122.1404,37.376),(-122.1398,37.372),(-122.139,37.356),(-122.1388,37.353),(-122.1385,37.34),(-122.1382,37.33),(-122.1378,37.316)] | Berkeley
- I- 580 | [(-122.2197,37.99),(-122.22,37.99),(-122.222092,37.99523),(-122.2232,37.998),(-122.224146,37.99963),(-122.2261,37.003),(-122.2278,37.007),(-122.2302,37.026),(-122.2323,37.043),(-122.2344,37.059),(-122.235405,37.06427),(-122.2365,37.07)] | Berkeley
- I- 580 | [(-122.2197,37.99),(-122.22,37.99),(-122.222092,37.99523),(-122.2232,37.998),(-122.224146,37.99963),(-122.2261,37.003),(-122.2278,37.007),(-122.2302,37.026),(-122.2323,37.043),(-122.2344,37.059),(-122.235405,37.06427),(-122.2365,37.07)] | Lafayette
- I- 580 | [(-121.727,37.074),(-121.7229,37.093),(-121.722301,37.09522),(-121.721001,37.10005),(-121.7194,37.106),(-121.7188,37.109),(-121.7168,37.12),(-121.7163,37.123),(-121.7145,37.127),(-121.7096,37.148),(-121.707731,37.1568),(-121.7058,37.166),(-121.7055,37.168),(-121.7044,37.174),(-121.7038,37.172),(-121.7037,37.172),(-121.7027,37.175),(-121.7001,37.181),(-121.6957,37.191),(-121.6948,37.192),(-121.6897,37.204),(-121.6697,37.185)] | Oakland
- I- 580 | [(-121.9322,37.989),(-121.9243,37.006),(-121.9217,37.014)] | Oakland
- I- 580 | [(-121.9322,37.989),(-121.9243,37.006),(-121.9217,37.014)] | Oakland
- I- 580 | [(-122.018,37.019),(-122.0009,37.032),(-121.9787,37.983),(-121.958,37.984),(-121.9571,37.986)] | Oakland
- I- 580 | [(-122.018,37.019),(-122.0009,37.032),(-121.9787,37.983),(-121.958,37.984),(-121.9571,37.986)] | Oakland
- I- 580 | [(-122.1108,37.023),(-122.1101,37.02),(-122.108103,37.00764),(-122.108,37.007),(-122.1069,37.998),(-122.1064,37.994),(-122.1053,37.982),(-122.1048,37.977),(-122.1032,37.958),(-122.1026,37.953),(-122.1013,37.938),(-122.0989,37.911),(-122.0984,37.91),(-122.098,37.908)] | Oakland
- I- 580 | [(-122.1543,37.703),(-122.1535,37.694),(-122.1512,37.655),(-122.1475,37.603),(-122.1468,37.583),(-122.1472,37.569),(-122.149044,37.54874),(-122.1493,37.546),(-122.1501,37.532),(-122.1506,37.509),(-122.1495,37.482),(-122.1487,37.467),(-122.1477,37.447),(-122.1414,37.383),(-122.1404,37.376),(-122.1398,37.372),(-122.139,37.356),(-122.1388,37.353),(-122.1385,37.34),(-122.1382,37.33),(-122.1378,37.316)] | Oakland
- I- 580 Ramp | [(-122.093241,37.90351),(-122.09364,37.89634),(-122.093788,37.89212)] | Berkeley
- I- 580 Ramp | [(-122.0934,37.896),(-122.09257,37.89961),(-122.0911,37.906)] | Berkeley
- I- 580 Ramp | [(-122.0941,37.897),(-122.0943,37.902)] | Berkeley
- I- 580 Ramp | [(-122.096,37.888),(-122.0962,37.891),(-122.0964,37.9)] | Berkeley
- I- 580 Ramp | [(-122.101,37.898),(-122.1005,37.902),(-122.0989,37.911)] | Berkeley
- I- 580 Ramp | [(-122.1086,37.003),(-122.1068,37.993),(-122.1066,37.992),(-122.1053,37.982)] | Berkeley
- I- 580 Ramp | [(-121.8521,37.011),(-121.8479,37.999),(-121.8476,37.999),(-121.8456,37.01),(-121.8455,37.011)] | Oakland
- I- 580 Ramp | [(-121.8521,37.011),(-121.8479,37.999),(-121.8476,37.999),(-121.8456,37.01),(-121.8455,37.011)] | Oakland
- I- 580 Ramp | [(-121.8743,37.014),(-121.8722,37.999),(-121.8714,37.999)] | Oakland
- I- 580 Ramp | [(-121.8743,37.014),(-121.8722,37.999),(-121.8714,37.999)] | Oakland
- I- 580 Ramp | [(-121.9043,37.998),(-121.9036,37.013),(-121.902632,37.0174),(-121.9025,37.018)] | Oakland
- I- 580 Ramp | [(-121.9043,37.998),(-121.9036,37.013),(-121.902632,37.0174),(-121.9025,37.018)] | Oakland
- I- 580 Ramp | [(-121.9368,37.986),(-121.936483,37.98832),(-121.9353,37.997),(-121.93504,37.00035),(-121.9346,37.006),(-121.933764,37.00031),(-121.9333,37.997),(-121.9322,37.989)] | Oakland
- I- 580 Ramp | [(-121.9368,37.986),(-121.936483,37.98832),(-121.9353,37.997),(-121.93504,37.00035),(-121.9346,37.006),(-121.933764,37.00031),(-121.9333,37.997),(-121.9322,37.989)] | Oakland
- I- 580 Ramp | [(-122.1086,37.003),(-122.1068,37.993),(-122.1066,37.992),(-122.1053,37.982)] | Oakland
- I- 580 Ramp | [(-122.1414,37.383),(-122.1407,37.376),(-122.1403,37.372),(-122.139,37.356)] | Oakland
- I- 580/I-680 Ramp | ((-121.9207,37.988),(-121.9192,37.016)) | Oakland
- I- 580/I-680 Ramp | ((-121.9207,37.988),(-121.9192,37.016)) | Oakland
- I- 680 | ((-121.939,37.15),(-121.9387,37.145),(-121.9373,37.125),(-121.934242,37.07643),(-121.933886,37.0709),(-121.9337,37.068),(-121.933122,37.06139),(-121.932736,37.05698),(-121.93222,37.05108),(-121.931844,37.04678),(-121.930113,37.027),(-121.926829,37),(-121.9265,37.998),(-121.9217,37.96),(-121.9203,37.949),(-121.9184,37.934)) | Oakland
- I- 680 | ((-121.939,37.15),(-121.9387,37.145),(-121.9373,37.125),(-121.934242,37.07643),(-121.933886,37.0709),(-121.9337,37.068),(-121.933122,37.06139),(-121.932736,37.05698),(-121.93222,37.05108),(-121.931844,37.04678),(-121.930113,37.027),(-121.926829,37),(-121.9265,37.998),(-121.9217,37.96),(-121.9203,37.949),(-121.9184,37.934)) | Oakland
- I- 680 | [(-121.9101,37.715),(-121.911269,37.74682),(-121.9119,37.764),(-121.9124,37.776),(-121.9174,37.905),(-121.9194,37.957),(-121.9207,37.988)] | Oakland
- I- 680 | [(-121.9184,37.934),(-121.917,37.913),(-121.9122,37.83),(-121.9052,37.702)] | Oakland
- I- 680 Ramp | [(-121.8833,37.376),(-121.8833,37.392),(-121.883,37.4),(-121.8835,37.402),(-121.8852,37.422)] | Oakland
- I- 680 Ramp | [(-121.8833,37.376),(-121.8833,37.392),(-121.883,37.4),(-121.8835,37.402),(-121.8852,37.422)] | Oakland
- I- 680 Ramp | [(-121.92,37.438),(-121.9218,37.424),(-121.9238,37.408),(-121.9252,37.392)] | Oakland
- I- 680 Ramp | [(-121.92,37.438),(-121.9218,37.424),(-121.9238,37.408),(-121.9252,37.392)] | Oakland
- I- 680 Ramp | [(-121.9238,37.402),(-121.9234,37.395),(-121.923,37.399)] | Oakland
- I- 680 Ramp | [(-121.9238,37.402),(-121.9234,37.395),(-121.923,37.399)] | Oakland
- I- 80 | ((-122.2937,37.277),(-122.3016,37.262)) | Lafayette
- I- 80 | ((-122.2962,37.273),(-122.3004,37.264)) | Lafayette
- I- 80 Ramp | [(-122.2962,37.413),(-122.2959,37.382),(-122.2951,37.372)] | Lafayette
- I- 880 | [(-122.0375,37.632),(-122.0359,37.619),(-122.0358,37.616),(-122.034514,37.60409),(-122.031876,37.57965),(-122.031193,37.57332),(-122.03016,37.56375),(-122.02943,37.55698),(-122.028689,37.54929),(-122.027833,37.53908),(-122.025979,37.51698),(-122.0238,37.491)] | Berkeley
- I- 880 | [(-122.0612,37.003),(-122.0604,37.991),(-122.0596,37.982),(-122.0585,37.967),(-122.0583,37.961),(-122.0553,37.918),(-122.053635,37.89475),(-122.050759,37.8546),(-122.05,37.844),(-122.0485,37.817),(-122.0483,37.813),(-122.0482,37.811)] | Berkeley
- I- 880 | [(-122.1365,37.902),(-122.1358,37.898),(-122.1333,37.881),(-122.1323,37.874),(-122.1311,37.866),(-122.1308,37.865),(-122.1307,37.864),(-122.1289,37.851),(-122.1277,37.843),(-122.1264,37.834),(-122.1231,37.812),(-122.1165,37.766),(-122.1104,37.72),(-122.109695,37.71094),(-122.109,37.702),(-122.108312,37.69168),(-122.1076,37.681)] | Berkeley
- I- 880 | [(-122.1755,37.185),(-122.1747,37.178),(-122.1742,37.173),(-122.1692,37.126),(-122.167792,37.11594),(-122.16757,37.11435),(-122.1671,37.111),(-122.1655,37.1),(-122.165169,37.09811),(-122.1641,37.092),(-122.1596,37.061),(-122.158381,37.05275),(-122.155991,37.03657),(-122.1531,37.017),(-122.1478,37.98),(-122.1407,37.932),(-122.1394,37.924),(-122.1389,37.92),(-122.1376,37.91)] | Berkeley
- I- 880 | [(-122.2214,37.711),(-122.2202,37.699),(-122.2199,37.695),(-122.219,37.682),(-122.2184,37.672),(-122.2173,37.652),(-122.2159,37.638),(-122.2144,37.616),(-122.2138,37.612),(-122.2135,37.609),(-122.212,37.592),(-122.2116,37.586),(-122.2111,37.581)] | Berkeley
- I- 880 | [(-122.2707,37.975),(-122.2693,37.972),(-122.2681,37.966),(-122.267,37.962),(-122.2659,37.957),(-122.2648,37.952),(-122.2636,37.946),(-122.2625,37.935),(-122.2617,37.927),(-122.2607,37.921),(-122.2593,37.916),(-122.258,37.911),(-122.2536,37.898),(-122.2432,37.858),(-122.2408,37.845),(-122.2386,37.827),(-122.2374,37.811)] | Berkeley
- I- 880 | ((-121.9669,37.075),(-121.9663,37.071),(-121.9656,37.065),(-121.9618,37.037),(-121.95689,37),(-121.948,37.933)) | Oakland
- I- 880 | ((-121.9669,37.075),(-121.9663,37.071),(-121.9656,37.065),(-121.9618,37.037),(-121.95689,37),(-121.948,37.933)) | Oakland
- I- 880 | [(-121.948,37.933),(-121.9471,37.925),(-121.9467,37.923),(-121.946,37.918),(-121.9452,37.912),(-121.937,37.852)] | Oakland
- I- 880 | [(-122.0219,37.466),(-122.0205,37.447),(-122.020331,37.44447),(-122.020008,37.43962),(-122.0195,37.432),(-122.0193,37.429),(-122.0164,37.393),(-122.010219,37.34771),(-122.0041,37.313)] | Oakland
- I- 880 | [(-122.0375,37.632),(-122.0359,37.619),(-122.0358,37.616),(-122.034514,37.60409),(-122.031876,37.57965),(-122.031193,37.57332),(-122.03016,37.56375),(-122.02943,37.55698),(-122.028689,37.54929),(-122.027833,37.53908),(-122.025979,37.51698),(-122.0238,37.491)] | Oakland
- I- 880 | [(-122.0612,37.003),(-122.0604,37.991),(-122.0596,37.982),(-122.0585,37.967),(-122.0583,37.961),(-122.0553,37.918),(-122.053635,37.89475),(-122.050759,37.8546),(-122.05,37.844),(-122.0485,37.817),(-122.0483,37.813),(-122.0482,37.811)] | Oakland
- I- 880 | [(-122.0612,37.003),(-122.0604,37.991),(-122.0596,37.982),(-122.0585,37.967),(-122.0583,37.961),(-122.0553,37.918),(-122.053635,37.89475),(-122.050759,37.8546),(-122.05,37.844),(-122.0485,37.817),(-122.0483,37.813),(-122.0482,37.811)] | Oakland
- I- 880 | [(-122.0831,37.312),(-122.0819,37.296),(-122.081,37.285),(-122.0786,37.248),(-122.078,37.24),(-122.077642,37.23496),(-122.076983,37.22567),(-122.076599,37.22026),(-122.076229,37.21505),(-122.0758,37.209)] | Oakland
- I- 880 | [(-122.0978,37.528),(-122.096,37.496),(-122.0931,37.453),(-122.09277,37.4496),(-122.090189,37.41442),(-122.0896,37.405),(-122.085,37.34)] | Oakland
- I- 880 | [(-122.1755,37.185),(-122.1747,37.178),(-122.1742,37.173),(-122.1692,37.126),(-122.167792,37.11594),(-122.16757,37.11435),(-122.1671,37.111),(-122.1655,37.1),(-122.165169,37.09811),(-122.1641,37.092),(-122.1596,37.061),(-122.158381,37.05275),(-122.155991,37.03657),(-122.1531,37.017),(-122.1478,37.98),(-122.1407,37.932),(-122.1394,37.924),(-122.1389,37.92),(-122.1376,37.91)] | Oakland
- I- 880 Ramp | [(-122.059,37.982),(-122.0577,37.984),(-122.0612,37.003)] | Berkeley
- I- 880 Ramp | [(-122.0618,37.011),(-122.0631,37.982),(-122.0585,37.967)] | Berkeley
- I- 880 Ramp | [(-122.1029,37.61),(-122.1013,37.587),(-122.0999,37.569)] | Berkeley
- I- 880 Ramp | [(-122.1379,37.891),(-122.1383,37.897),(-122.1377,37.902)] | Berkeley
- I- 880 Ramp | [(-122.1379,37.931),(-122.137597,37.92736),(-122.1374,37.925),(-122.1373,37.924),(-122.1369,37.914),(-122.1358,37.905),(-122.1365,37.908),(-122.1358,37.898)] | Berkeley
- I- 880 Ramp | [(-122.2536,37.898),(-122.254,37.902)] | Berkeley
- I- 880 Ramp | [(-122.2771,37.002),(-122.278,37)] | Lafayette
- I- 880 Ramp | [(-122.0019,37.301),(-122.002,37.293)] | Oakland
- I- 880 Ramp | [(-122.0041,37.313),(-122.0018,37.315),(-122.0007,37.315),(-122.0005,37.313),(-122.0002,37.308),(-121.9995,37.289)] | Oakland
- I- 880 Ramp | [(-122.0041,37.313),(-122.0038,37.308),(-122.0039,37.284),(-122.0013,37.287),(-121.9995,37.289)] | Oakland
- I- 880 Ramp | [(-122.0236,37.488),(-122.0231,37.458),(-122.0227,37.458),(-122.0223,37.452),(-122.0205,37.447)] | Oakland
- I- 880 Ramp | [(-122.0238,37.491),(-122.0215,37.483),(-122.0211,37.477),(-122.0205,37.447)] | Oakland
- I- 880 Ramp | [(-122.059,37.982),(-122.0577,37.984),(-122.0612,37.003)] | Oakland
- I- 880 Ramp | [(-122.059,37.982),(-122.0577,37.984),(-122.0612,37.003)] | Oakland
- I- 880 Ramp | [(-122.0618,37.011),(-122.0631,37.982),(-122.0585,37.967)] | Oakland
- I- 880 Ramp | [(-122.0618,37.011),(-122.0631,37.982),(-122.0585,37.967)] | Oakland
- I- 880 Ramp | [(-122.085,37.34),(-122.0801,37.316),(-122.081,37.285)] | Oakland
- I- 880 Ramp | [(-122.085,37.34),(-122.0801,37.316),(-122.081,37.285)] | Oakland
- I- 880 Ramp | [(-122.085,37.34),(-122.0866,37.316),(-122.0819,37.296)] | Oakland
- I- 880 Ramp | [(-122.085,37.34),(-122.0866,37.316),(-122.0819,37.296)] | Oakland
- Indian Way | [(-122.2066,37.398),(-122.2045,37.411)] | Lafayette
- Jackson St | [(-122.0845,37.6),(-122.0842,37.606)] | Berkeley
- Johnson Dr | [(-121.9145,37.901),(-121.915,37.877)] | Oakland
- Joyce St | [(-122.0792,37.604),(-122.0774,37.581)] | Berkeley
- Juniper St | [(-121.7823,37.897),(-121.7815,37.9)] | Oakland
- Kaiser Dr | [(-122.067163,37.47821),(-122.060402,37.51961)] | Oakland
- Keeler Ave | [(-122.2578,37.906),(-122.2579,37.899)] | Berkeley
- Kildare Road | [(-122.0968,37.016),(-122.0959,37)] | Oakland
- La Playa Dr | [(-122.1039,37.545),(-122.101,37.493)] | Oakland
- Laguna Ave | [(-122.2099,37.989),(-122.2089,37)] | Berkeley
- Laguna Ave | [(-122.2099,37.989),(-122.2089,37)] | Lafayette
- Lakehurst Cir | [(-122.284729,37.89025),(-122.286096,37.90364)] | Berkeley
- Lakeshore Ave | [(-122.2586,37.99),(-122.2556,37.006)] | Berkeley
- Lakeshore Ave | [(-122.2586,37.99),(-122.2556,37.006)] | Lafayette
- Las Positas Road | [(-121.764488,37.99199),(-121.75569,37.02022)] | Oakland
- Las Positas Road | [(-121.764488,37.99199),(-121.75569,37.02022)] | Oakland
- Linden St | [(-122.2867,37.998),(-122.2864,37.008)] | Berkeley
- Linden St | [(-122.2867,37.998),(-122.2864,37.008)] | Lafayette
- Livermore Ave | [(-121.7687,37.448),(-121.769,37.375)] | Oakland
- Livermore Ave | [(-121.7687,37.448),(-121.769,37.375)] | Oakland
- Livermore Ave | [(-121.772719,37.99085),(-121.7728,37.001)] | Oakland
- Livermore Ave | [(-121.772719,37.99085),(-121.7728,37.001)] | Oakland
- Locust St | [(-122.1606,37.007),(-122.1593,37.987)] | Berkeley
- Locust St | [(-122.1606,37.007),(-122.1593,37.987)] | Oakland
- Logan Ct | [(-122.0053,37.492),(-122.0061,37.484)] | Oakland
- Magnolia St | [(-122.0971,37.5),(-122.0962,37.484)] | Oakland
- Mandalay Road | [(-122.2322,37.397),(-122.2321,37.403)] | Lafayette
- Marin Ave | [(-122.2741,37.894),(-122.272,37.901)] | Berkeley
- Martin Luther King Jr Way | [(-122.2712,37.608),(-122.2711,37.599)] | Berkeley
- Mattos Dr | [(-122.0005,37.502),(-122.000898,37.49683)] | Oakland
- Maubert Ave | [(-122.1114,37.009),(-122.1096,37.995)] | Berkeley
- Maubert Ave | [(-122.1114,37.009),(-122.1096,37.995)] | Oakland
- McClure Ave | [(-122.1431,37.001),(-122.1436,37.998)] | Berkeley
- McClure Ave | [(-122.1431,37.001),(-122.1436,37.998)] | Oakland
- Medlar Dr | [(-122.0627,37.378),(-122.0625,37.375)] | Oakland
- Mildred Ct | [(-122.0002,37.388),(-121.9998,37.386)] | Oakland
- Miller Road | [(-122.0902,37.645),(-122.0865,37.545)] | Berkeley
- Miramar Ave | [(-122.1009,37.025),(-122.099089,37.03209)] | Oakland
- Mission Blvd | [(-122.0006,37.896),(-121.9989,37.88)] | Berkeley
- Mission Blvd | [(-121.918886,37),(-121.9194,37.976),(-121.9198,37.975)] | Oakland
- Mission Blvd | [(-121.918886,37),(-121.9194,37.976),(-121.9198,37.975)] | Oakland
- Mission Blvd | [(-122.0006,37.896),(-121.9989,37.88)] | Oakland
- Moores Ave | [(-122.0087,37.301),(-122.0094,37.292)] | Oakland
- National Ave | [(-122.1192,37.5),(-122.1281,37.489)] | Oakland
- Navajo Ct | [(-121.8779,37.901),(-121.8783,37.9)] | Oakland
- Newark Blvd | [(-122.0352,37.438),(-122.0341,37.423)] | Oakland
- Oakland Inner Harbor | [(-122.2625,37.913),(-122.260016,37.89484)] | Berkeley
- Oakridge Road | [(-121.8316,37.049),(-121.828382,37)] | Oakland
- Oneil Ave | [(-122.076754,37.62476),(-122.0745,37.595)] | Berkeley
- Parkridge Dr | [(-122.1438,37.884),(-122.1428,37.9)] | Berkeley
- Parkside Dr | [(-122.0475,37.603),(-122.0443,37.596)] | Berkeley
- Paseo Padre Pkwy | [(-122.0021,37.639),(-121.996,37.628)] | Berkeley
- Paseo Padre Pkwy | [(-121.9143,37.005),(-121.913522,37)] | Oakland
- Paseo Padre Pkwy | [(-122.0021,37.639),(-121.996,37.628)] | Oakland
- Pearl St | [(-122.2383,37.594),(-122.2366,37.615)] | Berkeley
- Periwinkle Road | [(-122.0451,37.301),(-122.044758,37.29844)] | Oakland
- Pimlico Dr | [(-121.8616,37.998),(-121.8618,37.008)] | Oakland
- Pimlico Dr | [(-121.8616,37.998),(-121.8618,37.008)] | Oakland
- Portsmouth Ave | [(-122.1064,37.315),(-122.1064,37.308)] | Oakland
- Proctor Ave | [(-122.2267,37.406),(-122.2251,37.386)] | Lafayette
- Railroad Ave | [(-122.0245,37.013),(-122.0234,37.003),(-122.0223,37.993)] | Berkeley
- Railroad Ave | [(-122.0245,37.013),(-122.0234,37.003),(-122.0223,37.993)] | Oakland
- Railroad Ave | [(-122.0245,37.013),(-122.0234,37.003),(-122.0223,37.993)] | Oakland
- Ranspot Dr | [(-122.0972,37.999),(-122.0959,37)] | Berkeley
- Ranspot Dr | [(-122.0972,37.999),(-122.0959,37)] | Oakland
- Ranspot Dr | [(-122.0972,37.999),(-122.0959,37)] | Oakland
- Redding St | [(-122.1978,37.901),(-122.1975,37.895)] | Berkeley
- Redwood Road | [(-122.1493,37.98),(-122.1437,37.001)] | Berkeley
- Redwood Road | [(-122.1493,37.98),(-122.1437,37.001)] | Oakland
- Roca Dr | [(-122.0335,37.609),(-122.0314,37.599)] | Berkeley
- Rosedale Ct | [(-121.9232,37.9),(-121.924,37.897)] | Oakland
- Sacramento St | [(-122.2799,37.606),(-122.2797,37.597)] | Berkeley
- Saddle Brook Dr | [(-122.1478,37.909),(-122.1454,37.904),(-122.1451,37.888)] | Berkeley
- Saginaw Ct | [(-121.8803,37.898),(-121.8806,37.901)] | Oakland
- San Andreas Dr | [(-122.0609,37.9),(-122.0614,37.895)] | Berkeley
- Santa Maria Ave | [(-122.0773,37),(-122.0773,37.98)] | Berkeley
- Santa Maria Ave | [(-122.0773,37),(-122.0773,37.98)] | Oakland
- Santa Maria Ave | [(-122.0773,37),(-122.0773,37.98)] | Oakland
- Shattuck Ave | [(-122.2686,37.904),(-122.2686,37.897)] | Berkeley
- Sheridan Road | [(-122.2279,37.425),(-122.2253,37.411),(-122.2223,37.377)] | Lafayette
- Shoreline Dr | [(-122.2657,37.603),(-122.2648,37.6)] | Berkeley
- Skyline Blvd | [(-122.1738,37.01),(-122.1714,37.996)] | Berkeley
- Skyline Blvd | [(-122.1738,37.01),(-122.1714,37.996)] | Oakland
- Skyline Dr | [(-122.0277,37.5),(-122.0284,37.498)] | Oakland
- Skywest Dr | [(-122.1161,37.62),(-122.1123,37.586)] | Berkeley
- Southern Pacific Railroad | [(-122.3002,37.674),(-122.2999,37.661)] | Berkeley
- Sp Railroad | [(-122.0734,37.001),(-122.0734,37.997)] | Berkeley
- Sp Railroad | [(-122.0914,37.601),(-122.087,37.56),(-122.086408,37.5551)] | Berkeley
- Sp Railroad | [(-122.137792,37.003),(-122.1365,37.992),(-122.131257,37.94612)] | Berkeley
- Sp Railroad | [(-121.893564,37.99009),(-121.897,37.016)] | Oakland
- Sp Railroad | [(-121.893564,37.99009),(-121.897,37.016)] | Oakland
- Sp Railroad | [(-121.9565,37.898),(-121.9562,37.9)] | Oakland
- Sp Railroad | [(-122.0734,37.001),(-122.0734,37.997)] | Oakland
- Sp Railroad | [(-122.0734,37.001),(-122.0734,37.997)] | Oakland
- Sp Railroad | [(-122.137792,37.003),(-122.1365,37.992),(-122.131257,37.94612)] | Oakland
- Sp Railroad | [(-122.1947,37.497),(-122.193328,37.4848)] | Oakland
- Stanton Ave | [(-122.100392,37.0697),(-122.099513,37.06052)] | Oakland
- State Hwy 123 | [(-122.3004,37.986),(-122.2998,37.969),(-122.2995,37.962),(-122.2992,37.952),(-122.299,37.942),(-122.2987,37.935),(-122.2984,37.924),(-122.2982,37.92),(-122.2976,37.904),(-122.297,37.88),(-122.2966,37.869),(-122.2959,37.848),(-122.2961,37.843)] | Berkeley
- State Hwy 13 | [(-122.1797,37.943),(-122.179871,37.91849),(-122.18,37.9),(-122.179023,37.86615),(-122.1787,37.862),(-122.1781,37.851),(-122.1777,37.845),(-122.1773,37.839),(-122.177,37.833)] | Berkeley
- State Hwy 13 | [(-122.2049,37.2),(-122.20328,37.17975),(-122.1989,37.125),(-122.198078,37.11641),(-122.1975,37.11)] | Lafayette
- State Hwy 13 Ramp | [(-122.2244,37.427),(-122.223,37.414),(-122.2214,37.396),(-122.2213,37.388)] | Lafayette
- State Hwy 238 | ((-122.098,37.908),(-122.0983,37.907),(-122.099,37.905),(-122.101,37.898),(-122.101535,37.89711),(-122.103173,37.89438),(-122.1046,37.892),(-122.106,37.89)) | Berkeley
- State Hwy 238 Ramp | [(-122.1288,37.9),(-122.1293,37.895),(-122.1296,37.906)] | Berkeley
- State Hwy 24 | [(-122.2674,37.246),(-122.2673,37.248),(-122.267,37.261),(-122.2668,37.271),(-122.2663,37.298),(-122.2659,37.315),(-122.2655,37.336),(-122.265007,37.35882),(-122.264443,37.37286),(-122.2641,37.381),(-122.2638,37.388),(-122.2631,37.396),(-122.2617,37.405),(-122.2615,37.407),(-122.2605,37.412)] | Lafayette
- State Hwy 84 | [(-121.9565,37.898),(-121.956589,37.89911),(-121.9569,37.903),(-121.956,37.91),(-121.9553,37.919)] | Oakland
- State Hwy 84 | [(-122.0671,37.426),(-122.07,37.402),(-122.074,37.37),(-122.0773,37.338)] | Oakland
- State Hwy 92 | [(-122.1085,37.326),(-122.1095,37.322),(-122.1111,37.316),(-122.1119,37.313),(-122.1125,37.311),(-122.1131,37.308),(-122.1167,37.292),(-122.1187,37.285),(-122.12,37.28)] | Oakland
- State Hwy 92 Ramp | [(-122.1086,37.321),(-122.1089,37.315),(-122.1111,37.316)] | Oakland
- Stuart St | [(-122.2518,37.6),(-122.2507,37.601),(-122.2491,37.606)] | Berkeley
- Sunol Ridge Trl | [(-121.9419,37.455),(-121.9345,37.38)] | Oakland
- Sunol Ridge Trl | [(-121.9419,37.455),(-121.9345,37.38)] | Oakland
- Tassajara Creek | [(-121.87866,37.98898),(-121.8782,37.015)] | Oakland
- Tassajara Creek | [(-121.87866,37.98898),(-121.8782,37.015)] | Oakland
- Taurus Ave | [(-122.2159,37.416),(-122.2128,37.389)] | Lafayette
- Tennyson Road | [(-122.0891,37.317),(-122.0927,37.317)] | Oakland
- Thackeray Ave | [(-122.072,37.305),(-122.0715,37.298)] | Oakland
- Theresa Way | [(-121.7289,37.906),(-121.728,37.899)] | Oakland
- Tissiack Way | [(-121.920364,37),(-121.9208,37.995)] | Oakland
- Tissiack Way | [(-121.920364,37),(-121.9208,37.995)] | Oakland
- Tupelo Ter | [(-122.059087,37.6113),(-122.057021,37.59942)] | Berkeley
- Vallecitos Road | [(-121.8699,37.916),(-121.8703,37.891)] | Oakland
- Warm Springs Blvd | [(-121.933956,37),(-121.9343,37.97)] | Oakland
- Warm Springs Blvd | [(-121.933956,37),(-121.9343,37.97)] | Oakland
- Welch Creek Road | [(-121.7695,37.386),(-121.7737,37.413)] | Oakland
- Welch Creek Road | [(-121.7695,37.386),(-121.7737,37.413)] | Oakland
- West Loop Road | [(-122.0576,37.604),(-122.0602,37.586)] | Berkeley
- Western Pacific Railroad Spur | [(-122.0394,37.018),(-122.0394,37.961)] | Berkeley
- Western Pacific Railroad Spur | [(-122.0394,37.018),(-122.0394,37.961)] | Oakland
- Western Pacific Railroad Spur | [(-122.0394,37.018),(-122.0394,37.961)] | Oakland
- Whitlock Creek | [(-121.74683,37.91276),(-121.733107,37)] | Oakland
- Whitlock Creek | [(-121.74683,37.91276),(-121.733107,37)] | Oakland
- Willimet Way | [(-122.0964,37.517),(-122.0949,37.493)] | Oakland
- Wisconsin St | [(-122.1994,37.017),(-122.1975,37.998),(-122.1971,37.994)] | Berkeley
- Wisconsin St | [(-122.1994,37.017),(-122.1975,37.998),(-122.1971,37.994)] | Oakland
- Wp Railroad | [(-122.254,37.902),(-122.2506,37.891)] | Berkeley
-(333 rows)
-
-SELECT name, #thepath FROM iexit ORDER BY 1, 2;
- name | ?column?
-------------------------------------+----------
- I- 580 | 2
- I- 580 | 2
- I- 580 | 2
- I- 580 | 2
- I- 580 | 2
- I- 580 | 2
- I- 580 | 2
- I- 580 | 2
- I- 580 | 2
- I- 580 | 2
- I- 580 | 2
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 3
- I- 580 | 4
- I- 580 | 4
- I- 580 | 4
- I- 580 | 4
- I- 580 | 5
- I- 580 | 5
- I- 580 | 5
- I- 580 | 5
- I- 580 | 5
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 6
- I- 580 | 7
- I- 580 | 7
- I- 580 | 7
- I- 580 | 7
- I- 580 | 7
- I- 580 | 7
- I- 580 | 7
- I- 580 | 8
- I- 580 | 8
- I- 580 | 8
- I- 580 | 8
- I- 580 | 8
- I- 580 | 8
- I- 580 | 8
- I- 580 | 8
- I- 580 | 8
- I- 580 | 9
- I- 580 | 9
- I- 580 | 9
- I- 580 | 9
- I- 580 | 9
- I- 580 | 12
- I- 580 | 12
- I- 580 | 12
- I- 580 | 12
- I- 580 | 12
- I- 580 | 12
- I- 580 | 12
- I- 580 | 12
- I- 580 | 12
- I- 580 | 12
- I- 580 | 13
- I- 580 | 13
- I- 580 | 13
- I- 580 | 13
- I- 580 | 13
- I- 580 | 13
- I- 580 | 14
- I- 580 | 14
- I- 580 | 14
- I- 580 | 14
- I- 580 | 14
- I- 580 | 14
- I- 580 | 14
- I- 580 | 14
- I- 580 | 18
- I- 580 | 18
- I- 580 | 18
- I- 580 | 18
- I- 580 | 18
- I- 580 | 18
- I- 580 | 21
- I- 580 | 21
- I- 580 | 21
- I- 580 | 21
- I- 580 | 21
- I- 580 | 21
- I- 580 | 21
- I- 580 | 21
- I- 580 | 21
- I- 580 | 21
- I- 580 | 22
- I- 580 | 22
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 2
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 3
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 4
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 5
- I- 580 Ramp | 6
- I- 580 Ramp | 6
- I- 580 Ramp | 6
- I- 580 Ramp | 7
- I- 580 Ramp | 8
- I- 580 Ramp | 8
- I- 580 Ramp | 8
- I- 580 Ramp | 8
- I- 580 Ramp | 8
- I- 580 Ramp | 8
- I- 580/I-680 Ramp | 2
- I- 580/I-680 Ramp | 2
- I- 580/I-680 Ramp | 2
- I- 580/I-680 Ramp | 2
- I- 580/I-680 Ramp | 2
- I- 580/I-680 Ramp | 2
- I- 580/I-680 Ramp | 4
- I- 580/I-680 Ramp | 4
- I- 580/I-680 Ramp | 4
- I- 580/I-680 Ramp | 4
- I- 580/I-680 Ramp | 5
- I- 580/I-680 Ramp | 6
- I- 580/I-680 Ramp | 6
- I- 580/I-680 Ramp | 6
- I- 680 | 2
- I- 680 | 2
- I- 680 | 2
- I- 680 | 2
- I- 680 | 2
- I- 680 | 2
- I- 680 | 2
- I- 680 | 3
- I- 680 | 3
- I- 680 | 3
- I- 680 | 4
- I- 680 | 4
- I- 680 | 4
- I- 680 | 5
- I- 680 | 5
- I- 680 | 5
- I- 680 | 7
- I- 680 | 7
- I- 680 | 7
- I- 680 | 7
- I- 680 | 8
- I- 680 | 8
- I- 680 | 8
- I- 680 | 8
- I- 680 | 10
- I- 680 | 10
- I- 680 | 10
- I- 680 | 10
- I- 680 | 10
- I- 680 | 10
- I- 680 | 10
- I- 680 | 16
- I- 680 | 16
- I- 680 | 16
- I- 680 | 16
- I- 680 | 16
- I- 680 | 16
- I- 680 | 16
- I- 680 | 16
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 2
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 3
- I- 680 Ramp | 4
- I- 680 Ramp | 4
- I- 680 Ramp | 4
- I- 680 Ramp | 5
- I- 680 Ramp | 5
- I- 680 Ramp | 5
- I- 680 Ramp | 5
- I- 680 Ramp | 5
- I- 680 Ramp | 5
- I- 680 Ramp | 6
- I- 680 Ramp | 6
- I- 680 Ramp | 6
- I- 680 Ramp | 6
- I- 680 Ramp | 7
- I- 680 Ramp | 7
- I- 680 Ramp | 7
- I- 680 Ramp | 7
- I- 680 Ramp | 8
- I- 680 Ramp | 8
- I- 680 Ramp | 8
- I- 680 Ramp | 8
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 2
- I- 80 | 3
- I- 80 | 3
- I- 80 | 3
- I- 80 | 4
- I- 80 | 4
- I- 80 | 4
- I- 80 | 4
- I- 80 | 4
- I- 80 | 5
- I- 80 | 5
- I- 80 | 5
- I- 80 | 5
- I- 80 | 5
- I- 80 | 5
- I- 80 | 5
- I- 80 | 5
- I- 80 | 5
- I- 80 | 11
- I- 80 | 11
- I- 80 | 11
- I- 80 | 11
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 2
- I- 80 Ramp | 3
- I- 80 Ramp | 3
- I- 80 Ramp | 3
- I- 80 Ramp | 3
- I- 80 Ramp | 3
- I- 80 Ramp | 3
- I- 80 Ramp | 3
- I- 80 Ramp | 3
- I- 80 Ramp | 3
- I- 80 Ramp | 4
- I- 80 Ramp | 4
- I- 80 Ramp | 4
- I- 80 Ramp | 4
- I- 80 Ramp | 5
- I- 80 Ramp | 5
- I- 80 Ramp | 5
- I- 80 Ramp | 5
- I- 80 Ramp | 5
- I- 80 Ramp | 5
- I- 80 Ramp | 5
- I- 80 Ramp | 7
- I- 80 Ramp | 7
- I- 80 Ramp | 7
- I- 80 Ramp | 7
- I- 880 | 2
- I- 880 | 2
- I- 880 | 2
- I- 880 | 2
- I- 880 | 2
- I- 880 | 5
- I- 880 | 5
- I- 880 | 5
- I- 880 | 5
- I- 880 | 5
- I- 880 | 5
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 6
- I- 880 | 7
- I- 880 | 7
- I- 880 | 7
- I- 880 | 7
- I- 880 | 7
- I- 880 | 7
- I- 880 | 7
- I- 880 | 9
- I- 880 | 9
- I- 880 | 9
- I- 880 | 9
- I- 880 | 9
- I- 880 | 9
- I- 880 | 9
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 10
- I- 880 | 12
- I- 880 | 12
- I- 880 | 12
- I- 880 | 12
- I- 880 | 12
- I- 880 | 12
- I- 880 | 12
- I- 880 | 12
- I- 880 | 12
- I- 880 | 12
- I- 880 | 12
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 13
- I- 880 | 14
- I- 880 | 14
- I- 880 | 14
- I- 880 | 14
- I- 880 | 14
- I- 880 | 14
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 17
- I- 880 | 19
- I- 880 | 19
- I- 880 | 19
- I- 880 | 19
- I- 880 | 19
- I- 880 | 19
- I- 880 | 19
- I- 880 | 19
- I- 880 | 19
- I- 880 | 19
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 2
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 3
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 4
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 5
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 6
- I- 880 Ramp | 8
- I- 880 Ramp | 8
- I- 880 Ramp | 8
- I- 980 | 2
- I- 980 | 2
- I- 980 | 2
- I- 980 | 2
- I- 980 | 2
- I- 980 | 2
- I- 980 | 2
- I- 980 | 2
- I- 980 | 3
- I- 980 | 3
- I- 980 | 3
- I- 980 | 3
- I- 980 | 3
- I- 980 | 3
- I- 980 | 3
- I- 980 | 3
- I- 980 | 3
- I- 980 | 4
- I- 980 | 4
- I- 980 | 5
- I- 980 | 5
- I- 980 | 7
- I- 980 | 7
- I- 980 | 7
- I- 980 | 7
- I- 980 | 12
- I- 980 Ramp | 3
- I- 980 Ramp | 3
- I- 980 Ramp | 3
- I- 980 Ramp | 7
-(896 rows)
-
-SELECT * FROM toyemp WHERE name = 'sharon';
- name | age | location | annualsal
---------+-----+----------+-----------
- sharon | 25 | (15,12) | 12000
-(1 row)
-
---
--- Test for Leaky view scenario
---
-CREATE ROLE regress_alice;
-CREATE FUNCTION f_leak (text)
- RETURNS bool LANGUAGE 'plpgsql' COST 0.0000001
- AS 'BEGIN RAISE NOTICE ''f_leak => %'', $1; RETURN true; END';
-CREATE TABLE customer (
- cid int primary key,
- name text not null,
- tel text,
- passwd text
-);
-CREATE TABLE credit_card (
- cid int references customer(cid),
- cnum text,
- climit int
-);
-CREATE TABLE credit_usage (
- cid int references customer(cid),
- ymd date,
- usage int
-);
-INSERT INTO customer
- VALUES (101, 'regress_alice', '+81-12-3456-7890', 'passwd123'),
- (102, 'regress_bob', '+01-234-567-8901', 'beafsteak'),
- (103, 'regress_eve', '+49-8765-43210', 'hamburger');
-INSERT INTO credit_card
- VALUES (101, '1111-2222-3333-4444', 4000),
- (102, '5555-6666-7777-8888', 3000),
- (103, '9801-2345-6789-0123', 2000);
-INSERT INTO credit_usage
- VALUES (101, '2011-09-15', 120),
- (101, '2011-10-05', 90),
- (101, '2011-10-18', 110),
- (101, '2011-10-21', 200),
- (101, '2011-11-10', 80),
- (102, '2011-09-22', 300),
- (102, '2011-10-12', 120),
- (102, '2011-10-28', 200),
- (103, '2011-10-15', 480);
-CREATE VIEW my_property_normal AS
- SELECT * FROM customer WHERE name = current_user;
-CREATE VIEW my_property_secure WITH (security_barrier) AS
- SELECT * FROM customer WHERE name = current_user;
-CREATE VIEW my_credit_card_normal AS
- SELECT * FROM customer l NATURAL JOIN credit_card r
- WHERE l.name = current_user;
-CREATE VIEW my_credit_card_secure WITH (security_barrier) AS
- SELECT * FROM customer l NATURAL JOIN credit_card r
- WHERE l.name = current_user;
-CREATE VIEW my_credit_card_usage_normal AS
- SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r;
-CREATE VIEW my_credit_card_usage_secure WITH (security_barrier) AS
- SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r;
-GRANT SELECT ON my_property_normal TO public;
-GRANT SELECT ON my_property_secure TO public;
-GRANT SELECT ON my_credit_card_normal TO public;
-GRANT SELECT ON my_credit_card_secure TO public;
-GRANT SELECT ON my_credit_card_usage_normal TO public;
-GRANT SELECT ON my_credit_card_usage_secure TO public;
---
--- Run leaky view scenarios
---
-SET SESSION AUTHORIZATION regress_alice;
---
--- scenario: if a qualifier with tiny-cost is given, it shall be launched
--- prior to the security policy of the view.
---
-SELECT * FROM my_property_normal WHERE f_leak(passwd);
- cid | name | tel | passwd
------+---------------+------------------+-----------
- 101 | regress_alice | +81-12-3456-7890 | passwd123
-(1 row)
-
-EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal WHERE f_leak(passwd);
- QUERY PLAN
-------------------------------------------------------------------------
- Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Seq Scan on customer
- Filter: (f_leak(passwd) AND (name = ("current_user"())::text))
-(3 rows)
-
-SELECT * FROM my_property_secure WHERE f_leak(passwd);
- cid | name | tel | passwd
------+---------------+------------------+-----------
- 101 | regress_alice | +81-12-3456-7890 | passwd123
-(1 row)
-
-EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd);
- QUERY PLAN
----------------------------------------------------------
- Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Subquery Scan on my_property_secure
- Filter: f_leak(my_property_secure.passwd)
- -> Seq Scan on customer
- Filter: (name = ("current_user"())::text)
-(5 rows)
-
---
--- scenario: qualifiers can be pushed down if they contain leaky functions,
--- provided they aren't passed data from inside the view.
---
-SELECT * FROM my_property_normal v
- WHERE f_leak('passwd') AND f_leak(passwd);
- cid | name | tel | passwd
------+---------------+------------------+-----------
- 101 | regress_alice | +81-12-3456-7890 | passwd123
-(1 row)
-
-EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal v
- WHERE f_leak('passwd') AND f_leak(passwd);
- QUERY PLAN
----------------------------------------------------------------------------------------------------
- Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Seq Scan on customer
- Filter: (f_leak('passwd'::text) AND f_leak(passwd) AND (name = ("current_user"())::text))
-(3 rows)
-
-SELECT * FROM my_property_secure v
- WHERE f_leak('passwd') AND f_leak(passwd);
- cid | name | tel | passwd
------+---------------+------------------+-----------
- 101 | regress_alice | +81-12-3456-7890 | passwd123
-(1 row)
-
-EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure v
- WHERE f_leak('passwd') AND f_leak(passwd);
- QUERY PLAN
---------------------------------------------------------------------------------------
- Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Subquery Scan on v
- Filter: f_leak(v.passwd)
- -> Seq Scan on customer
- Filter: (f_leak('passwd'::text) AND (name = ("current_user"())::text))
-(5 rows)
-
---
--- scenario: if a qualifier references only one-side of a particular join-
--- tree, it shall be distributed to the most deep scan plan as
--- possible as we can.
---
-SELECT * FROM my_credit_card_normal WHERE f_leak(cnum);
- cid | name | tel | passwd | cnum | climit
------+---------------+------------------+-----------+---------------------+--------
- 101 | regress_alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000
-(1 row)
-
-EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_normal WHERE f_leak(cnum);
- QUERY PLAN
----------------------------------------------------------------
- Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Hash Join
- Hash Cond: (r.cid = l.cid)
- -> Seq Scan on credit_card r
- Filter: f_leak(cnum)
- -> Hash
- -> Seq Scan on customer l
- Filter: (name = ("current_user"())::text)
-(8 rows)
-
-SELECT * FROM my_credit_card_secure WHERE f_leak(cnum);
- cid | name | tel | passwd | cnum | climit
------+---------------+------------------+-----------+---------------------+--------
- 101 | regress_alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000
-(1 row)
-
-EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum);
- QUERY PLAN
----------------------------------------------------------------------
- Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Subquery Scan on my_credit_card_secure
- Filter: f_leak(my_credit_card_secure.cnum)
- -> Hash Join
- Hash Cond: (r.cid = l.cid)
- -> Seq Scan on credit_card r
- -> Hash
- -> Seq Scan on customer l
- Filter: (name = ("current_user"())::text)
-(9 rows)
-
---
--- scenario: an external qualifier can be pushed-down by in-front-of the
--- views with "security_barrier" attribute, except for operators
--- implemented with leakproof functions.
---
-SELECT * FROM my_credit_card_usage_normal
- WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01';
- cid | name | tel | passwd | cnum | climit | ymd | usage
------+---------------+------------------+-----------+---------------------+--------+------------+-------
- 101 | regress_alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 2011-10-05 | 90
- 101 | regress_alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 2011-10-18 | 110
- 101 | regress_alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 2011-10-21 | 200
-(3 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_normal
- WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01';
- QUERY PLAN
-------------------------------------------------------------------------------------
- Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Nested Loop
- Join Filter: (l.cid = r.cid)
- -> Seq Scan on credit_usage r
- Filter: ((ymd >= '10-01-2011'::date) AND (ymd < '11-01-2011'::date))
- -> Materialize
- -> Subquery Scan on l
- Filter: f_leak(l.cnum)
- -> Hash Join
- Hash Cond: (r_1.cid = l_1.cid)
- -> Seq Scan on credit_card r_1
- -> Hash
- -> Seq Scan on customer l_1
- Filter: (name = ("current_user"())::text)
-(14 rows)
-
-SELECT * FROM my_credit_card_usage_secure
- WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01';
- cid | name | tel | passwd | cnum | climit | ymd | usage
------+---------------+------------------+-----------+---------------------+--------+------------+-------
- 101 | regress_alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 2011-10-05 | 90
- 101 | regress_alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 2011-10-18 | 110
- 101 | regress_alice | +81-12-3456-7890 | passwd123 | 1111-2222-3333-4444 | 4000 | 2011-10-21 | 200
-(3 rows)
-
-EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_secure
- WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01';
- QUERY PLAN
-------------------------------------------------------------------------------------------
- Remote Subquery Scan on all (datanode_1,datanode_2)
- -> Subquery Scan on my_credit_card_usage_secure
- Filter: f_leak(my_credit_card_usage_secure.cnum)
- -> Nested Loop
- Join Filter: (l.cid = r.cid)
- -> Seq Scan on credit_usage r
- Filter: ((ymd >= '10-01-2011'::date) AND (ymd < '11-01-2011'::date))
- -> Materialize
- -> Hash Join
- Hash Cond: (r_1.cid = l.cid)
- -> Seq Scan on credit_card r_1
- -> Hash
- -> Seq Scan on customer l
- Filter: (name = ("current_user"())::text)
-(14 rows)
-
---
--- Test for the case when security_barrier gets changed between rewriter
--- and planner stage.
---
-PREPARE p1 AS SELECT * FROM my_property_normal WHERE f_leak(passwd);
-PREPARE p2 AS SELECT * FROM my_property_secure WHERE f_leak(passwd);
-EXECUTE p1;
- cid | name | tel | passwd
------+---------------+------------------+-----------
- 101 | regress_alice | +81-12-3456-7890 | passwd123
-(1 row)
-
-EXECUTE p2;
- cid | name | tel | passwd
------+---------------+------------------+-----------
- 101 | regress_alice | +81-12-3456-7890 | passwd123
-(1 row)
-
-RESET SESSION AUTHORIZATION;
-ALTER VIEW my_property_normal SET (security_barrier=true);
-ALTER VIEW my_property_secure SET (security_barrier=false);
-SET SESSION AUTHORIZATION regress_alice;
-EXECUTE p1; -- To be perform as a view with security-barrier
- cid | name | tel | passwd
------+---------------+------------------+-----------
- 101 | regress_alice | +81-12-3456-7890 | passwd123
-(1 row)
-
-EXECUTE p2; -- To be perform as a view without security-barrier
- cid | name | tel | passwd
------+---------------+------------------+-----------
- 101 | regress_alice | +81-12-3456-7890 | passwd123
-(1 row)
-
--- Cleanup.
-RESET SESSION AUTHORIZATION;
-DROP ROLE regress_alice;
+++ /dev/null
--- Test basic TRUNCATE functionality.
-CREATE TABLE truncate_a (col1 integer primary key);
-INSERT INTO truncate_a VALUES (1);
-INSERT INTO truncate_a VALUES (2);
-SELECT * FROM truncate_a ORDER BY 1;
- col1
-------
- 1
- 2
-(2 rows)
-
--- Roll truncate back
-BEGIN;
-TRUNCATE truncate_a;
-ROLLBACK;
-SELECT * FROM truncate_a ORDER BY 1;
- col1
-------
- 1
- 2
-(2 rows)
-
--- Commit the truncate this time
-BEGIN;
-TRUNCATE truncate_a;
-COMMIT;
-SELECT * FROM truncate_a ORDER BY 1;
- col1
-------
-(0 rows)
-
--- Test foreign-key checks
-CREATE TABLE trunc_b (a int REFERENCES truncate_a);
-CREATE TABLE trunc_c (a serial PRIMARY KEY) DISTRIBUTE BY REPLICATION;
-CREATE TABLE trunc_d (a int REFERENCES trunc_c);
-CREATE TABLE trunc_e (a int REFERENCES truncate_a, b int REFERENCES trunc_c);
-TRUNCATE TABLE truncate_a; -- fail
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_b" references "truncate_a".
-HINT: Truncate table "trunc_b" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE truncate_a,trunc_b; -- fail
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_e" references "truncate_a".
-HINT: Truncate table "trunc_e" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE truncate_a,trunc_b,trunc_e; -- ok
-TRUNCATE TABLE truncate_a,trunc_e; -- fail
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_b" references "truncate_a".
-HINT: Truncate table "trunc_b" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE trunc_c; -- fail
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_d" references "trunc_c".
-HINT: Truncate table "trunc_d" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE trunc_c,trunc_d; -- fail
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_e" references "trunc_c".
-HINT: Truncate table "trunc_e" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE trunc_c,trunc_d,trunc_e; -- ok
-TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a; -- fail
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_b" references "truncate_a".
-HINT: Truncate table "trunc_b" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a,trunc_b; -- ok
-TRUNCATE TABLE truncate_a RESTRICT; -- fail
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_b" references "truncate_a".
-HINT: Truncate table "trunc_b" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE truncate_a CASCADE; -- ok
-NOTICE: truncate cascades to table "trunc_b"
-NOTICE: truncate cascades to table "trunc_e"
--- circular references
-ALTER TABLE truncate_a ADD FOREIGN KEY (col1) REFERENCES trunc_c;
--- Add some data to verify that truncating actually works ...
-INSERT INTO trunc_c VALUES (1);
-INSERT INTO truncate_a VALUES (1);
-INSERT INTO trunc_b VALUES (1);
-INSERT INTO trunc_d VALUES (1);
-INSERT INTO trunc_e VALUES (1,1);
-TRUNCATE TABLE trunc_c;
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "truncate_a" references "trunc_c".
-HINT: Truncate table "truncate_a" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE trunc_c,truncate_a;
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_d" references "trunc_c".
-HINT: Truncate table "trunc_d" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE trunc_c,truncate_a,trunc_d;
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_e" references "trunc_c".
-HINT: Truncate table "trunc_e" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE trunc_c,truncate_a,trunc_d,trunc_e;
-ERROR: cannot truncate a table referenced in a foreign key constraint
-DETAIL: Table "trunc_b" references "truncate_a".
-HINT: Truncate table "trunc_b" at the same time, or use TRUNCATE ... CASCADE.
-TRUNCATE TABLE trunc_c,truncate_a,trunc_d,trunc_e,trunc_b;
--- Verify that truncating did actually work
-SELECT * FROM truncate_a
- UNION ALL
- SELECT * FROM trunc_c
- UNION ALL
- SELECT * FROM trunc_b
- UNION ALL
- SELECT * FROM trunc_d;
- col1
-------
-(0 rows)
-
-SELECT * FROM trunc_e;
- a | b
----+---
-(0 rows)
-
--- Add data again to test TRUNCATE ... CASCADE
-INSERT INTO trunc_c VALUES (1);
-INSERT INTO truncate_a VALUES (1);
-INSERT INTO trunc_b VALUES (1);
-INSERT INTO trunc_d VALUES (1);
-INSERT INTO trunc_e VALUES (1,1);
-TRUNCATE TABLE trunc_c CASCADE; -- ok
-NOTICE: truncate cascades to table "truncate_a"
-NOTICE: truncate cascades to table "trunc_d"
-NOTICE: truncate cascades to table "trunc_e"
-NOTICE: truncate cascades to table "trunc_b"
-SELECT * FROM truncate_a
- UNION ALL
- SELECT * FROM trunc_c
- UNION ALL
- SELECT * FROM trunc_b
- UNION ALL
- SELECT * FROM trunc_d;
- col1
-------
-(0 rows)
-
-SELECT * FROM trunc_e;
- a | b
----+---
-(0 rows)
-
-DROP TABLE truncate_a,trunc_c,trunc_b,trunc_d,trunc_e CASCADE;
--- Test TRUNCATE with inheritance
-CREATE TABLE trunc_f (col1 integer primary key);
-INSERT INTO trunc_f VALUES (1);
-INSERT INTO trunc_f VALUES (2);
-CREATE TABLE trunc_fa (col2a text) INHERITS (trunc_f);
-INSERT INTO trunc_fa VALUES (3, 'three');
-CREATE TABLE trunc_fb (col2b int) INHERITS (trunc_f);
-INSERT INTO trunc_fb VALUES (4, 444);
-CREATE TABLE trunc_faa (col3 text) INHERITS (trunc_fa);
-INSERT INTO trunc_faa VALUES (5, 'five', 'FIVE');
-BEGIN;
-SELECT * FROM trunc_f ORDER BY 1;
- col1
-------
- 1
- 2
- 3
- 4
- 5
-(5 rows)
-
-TRUNCATE trunc_f;
-SELECT * FROM trunc_f ORDER BY 1;
- col1
-------
-(0 rows)
-
-ROLLBACK;
-BEGIN;
-SELECT * FROM trunc_f ORDER BY 1;
- col1
-------
- 1
- 2
- 3
- 4
- 5
-(5 rows)
-
-TRUNCATE ONLY trunc_f;
-SELECT * FROM trunc_f ORDER BY 1;
- col1
-------
- 3
- 4
- 5
-(3 rows)
-
-ROLLBACK;
-BEGIN;
-SELECT * FROM trunc_f ORDER BY 1;
- col1
-------
- 1
- 2
- 3
- 4
- 5
-(5 rows)
-
-SELECT * FROM trunc_fa ORDER BY 1, 2;
- col1 | col2a
-------+-------
- 3 | three
- 5 | five
-(2 rows)
-
-SELECT * FROM trunc_faa ORDER BY 1, 2;
- col1 | col2a | col3
-------+-------+------
- 5 | five | FIVE
-(1 row)
-
-TRUNCATE ONLY trunc_fb, ONLY trunc_fa;
-SELECT * FROM trunc_f ORDER BY 1;
- col1
-------
- 1
- 2
- 5
-(3 rows)
-
-SELECT * FROM trunc_fa ORDER BY 1, 2;
- col1 | col2a
-------+-------
- 5 | five
-(1 row)
-
-SELECT * FROM trunc_faa ORDER BY 1, 2;
- col1 | col2a | col3
-------+-------+------
- 5 | five | FIVE
-(1 row)
-
-ROLLBACK;
-BEGIN;
-SELECT * FROM trunc_f ORDER BY 1;
- col1
-------
- 1
- 2
- 3
- 4
- 5
-(5 rows)
-
-SELECT * FROM trunc_fa ORDER BY 1, 2;
- col1 | col2a
-------+-------
- 3 | three
- 5 | five
-(2 rows)
-
-SELECT * FROM trunc_faa ORDER BY 1, 2;
- col1 | col2a | col3
-------+-------+------
- 5 | five | FIVE
-(1 row)
-
-TRUNCATE ONLY trunc_fb, trunc_fa;
-SELECT * FROM trunc_f ORDER BY 1;
- col1
-------
- 1
- 2
-(2 rows)
-
-SELECT * FROM trunc_fa ORDER BY 1, 2;
- col1 | col2a
-------+-------
-(0 rows)
-
-SELECT * FROM trunc_faa ORDER BY 1, 2;
- col1 | col2a | col3
-------+-------+------
-(0 rows)
-
-ROLLBACK;
-DROP TABLE trunc_f CASCADE;
-NOTICE: drop cascades to 3 other objects
-DETAIL: drop cascades to table trunc_fa
-drop cascades to table trunc_faa
-drop cascades to table trunc_fb
--- Test ON TRUNCATE triggers
-CREATE TABLE trunc_trigger_test (f1 int, f2 text, f3 text);
-CREATE TABLE trunc_trigger_log (tgop text, tglevel text, tgwhen text,
- tgargv text, tgtable name, rowcount bigint);
-CREATE FUNCTION trunctrigger() RETURNS trigger as $$
-declare c bigint;
-begin
- execute 'select count(*) from ' || quote_ident(tg_table_name) into c;
- insert into trunc_trigger_log values
- (TG_OP, TG_LEVEL, TG_WHEN, TG_ARGV[0], tg_table_name, c);
- return null;
-end;
-$$ LANGUAGE plpgsql;
--- basic before trigger
-INSERT INTO trunc_trigger_test VALUES(1, 'foo', 'bar'), (2, 'baz', 'quux');
-CREATE TRIGGER t
-BEFORE TRUNCATE ON trunc_trigger_test
-FOR EACH STATEMENT
-EXECUTE PROCEDURE trunctrigger('before trigger truncate');
-ERROR: Postgres-XL does not support TRIGGER yet
-DETAIL: The feature is not currently supported
-SELECT count(*) as "Row count in test table" FROM trunc_trigger_test;
- Row count in test table
--------------------------
- 2
-(1 row)
-
-SELECT * FROM trunc_trigger_log;
- tgop | tglevel | tgwhen | tgargv | tgtable | rowcount
-------+---------+--------+--------+---------+----------
-(0 rows)
-
-TRUNCATE trunc_trigger_test;
-SELECT count(*) as "Row count in test table" FROM trunc_trigger_test;
- Row count in test table
--------------------------
- 0
-(1 row)
-
-SELECT * FROM trunc_trigger_log;
- tgop | tglevel | tgwhen | tgargv | tgtable | rowcount
-------+---------+--------+--------+---------+----------
-(0 rows)
-
-DROP TRIGGER t ON trunc_trigger_test;
-ERROR: trigger "t" for table "trunc_trigger_test" does not exist
-truncate trunc_trigger_log;
--- same test with an after trigger
-INSERT INTO trunc_trigger_test VALUES(1, 'foo', 'bar'), (2, 'baz', 'quux');
-CREATE TRIGGER tt
-AFTER TRUNCATE ON trunc_trigger_test
-FOR EACH STATEMENT
-EXECUTE PROCEDURE trunctrigger('after trigger truncate');
-ERROR: Postgres-XL does not support TRIGGER yet
-DETAIL: The feature is not currently supported
-SELECT count(*) as "Row count in test table" FROM trunc_trigger_test;
- Row count in test table
--------------------------
- 2
-(1 row)
-
-SELECT * FROM trunc_trigger_log;
- tgop | tglevel | tgwhen | tgargv | tgtable | rowcount
-------+---------+--------+--------+---------+----------
-(0 rows)
-
-TRUNCATE trunc_trigger_test;
-SELECT count(*) as "Row count in test table" FROM trunc_trigger_test;
- Row count in test table
--------------------------
- 0
-(1 row)
-
-SELECT * FROM trunc_trigger_log;
- tgop | tglevel | tgwhen | tgargv | tgtable | rowcount
-------+---------+--------+--------+---------+----------
-(0 rows)
-
-DROP TABLE trunc_trigger_test;
-DROP TABLE trunc_trigger_log;
-DROP FUNCTION trunctrigger();
--- test TRUNCATE ... RESTART IDENTITY
-CREATE SEQUENCE truncate_a_id1 START WITH 33;
-CREATE TABLE truncate_a (id serial,
- id1 integer default nextval('truncate_a_id1'));
-ALTER SEQUENCE truncate_a_id1 OWNED BY truncate_a.id1;
-INSERT INTO truncate_a DEFAULT VALUES;
-INSERT INTO truncate_a DEFAULT VALUES;
-SELECT * FROM truncate_a ORDER BY id;
- id | id1
-----+-----
- 1 | 33
- 2 | 34
-(2 rows)
-
-TRUNCATE truncate_a;
-INSERT INTO truncate_a DEFAULT VALUES;
-INSERT INTO truncate_a DEFAULT VALUES;
-SELECT * FROM truncate_a ORDER BY id;
- id | id1
-----+-----
- 3 | 35
- 4 | 36
-(2 rows)
-
-TRUNCATE truncate_a RESTART IDENTITY;
-ERROR: PGXC does not support RESTART IDENTITY yet
-DETAIL: The feature is not supported currently
-INSERT INTO truncate_a DEFAULT VALUES;
-INSERT INTO truncate_a DEFAULT VALUES;
-SELECT * FROM truncate_a ORDER BY id;
- id | id1
-----+-----
- 3 | 35
- 4 | 36
- 5 | 37
- 6 | 38
-(4 rows)
-
--- check rollback of a RESTART IDENTITY operation
-BEGIN;
-TRUNCATE truncate_a RESTART IDENTITY;
-ERROR: PGXC does not support RESTART IDENTITY yet
-DETAIL: The feature is not supported currently
-INSERT INTO truncate_a DEFAULT VALUES;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-SELECT * FROM truncate_a;
-ERROR: current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK;
-INSERT INTO truncate_a DEFAULT VALUES;
-INSERT INTO truncate_a DEFAULT VALUES;
-SELECT * FROM truncate_a;
- id | id1
-----+-----
- 5 | 37
- 6 | 38
- 8 | 40
- 3 | 35
- 4 | 36
- 7 | 39
-(6 rows)
-
-DROP TABLE truncate_a;
-SELECT nextval('truncate_a_id1'); -- fail, seq should have been dropped
-ERROR: relation "truncate_a_id1" does not exist
-LINE 1: SELECT nextval('truncate_a_id1');
- ^
+++ /dev/null
---
--- Sanity checks for text search catalogs
---
--- NB: we assume the oidjoins test will have caught any dangling links,
--- that is OID or REGPROC fields that are not zero and do not match some
--- row in the linked-to table. However, if we want to enforce that a link
--- field can't be 0, we have to check it here.
--- Find unexpected zero link entries
-SELECT oid, prsname
-FROM pg_ts_parser
-WHERE prsnamespace = 0 OR prsstart = 0 OR prstoken = 0 OR prsend = 0 OR
- -- prsheadline is optional
- prslextype = 0;
- oid | prsname
------+---------
-(0 rows)
-
-SELECT oid, dictname
-FROM pg_ts_dict
-WHERE dictnamespace = 0 OR dictowner = 0 OR dicttemplate = 0;
- oid | dictname
------+----------
-(0 rows)
-
-SELECT oid, tmplname
-FROM pg_ts_template
-WHERE tmplnamespace = 0 OR tmpllexize = 0; -- tmplinit is optional
- oid | tmplname
------+----------
-(0 rows)
-
-SELECT oid, cfgname
-FROM pg_ts_config
-WHERE cfgnamespace = 0 OR cfgowner = 0 OR cfgparser = 0;
- oid | cfgname
------+---------
-(0 rows)
-
-SELECT mapcfg, maptokentype, mapseqno
-FROM pg_ts_config_map
-WHERE mapcfg = 0 OR mapdict = 0;
- mapcfg | maptokentype | mapseqno
---------+--------------+----------
-(0 rows)
-
--- Look for pg_ts_config_map entries that aren't one of parser's token types
-SELECT * FROM
- ( SELECT oid AS cfgid, (ts_token_type(cfgparser)).tokid AS tokid
- FROM pg_ts_config ) AS tt
-RIGHT JOIN pg_ts_config_map AS m
- ON (tt.cfgid=m.mapcfg AND tt.tokid=m.maptokentype)
-WHERE
- tt.cfgid IS NULL OR tt.tokid IS NULL;
- cfgid | tokid | mapcfg | maptokentype | mapseqno | mapdict
--------+-------+--------+--------------+----------+---------
-(0 rows)
-
--- test basic text search behavior without indexes, then with
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
- count
--------
- 158
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
- count
--------
- 17
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
- count
--------
- 6
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
- count
--------
- 98
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
- count
--------
- 23
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
- count
--------
- 39
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*';
- count
--------
- 494
-(1 row)
-
-create index wowidx on test_tsvector using gist (a);
-SET enable_seqscan=OFF;
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
- count
--------
- 158
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
- count
--------
- 17
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
- count
--------
- 6
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
- count
--------
- 98
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
- count
--------
- 23
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
- count
--------
- 39
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*';
- count
--------
- 494
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}');
- count
--------
- 158
-(1 row)
-
-RESET enable_seqscan;
-DROP INDEX wowidx;
-CREATE INDEX wowidx ON test_tsvector USING gin (a);
-SET enable_seqscan=OFF;
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
- count
--------
- 158
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
- count
--------
- 17
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
- count
--------
- 6
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
- count
--------
- 98
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
- count
--------
- 23
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
- count
--------
- 39
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*';
- count
--------
- 494
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}');
- count
--------
- 158
-(1 row)
-
-RESET enable_seqscan;
-INSERT INTO test_tsvector VALUES ('???', 'DFG:1A,2B,6C,10 FGH');
-SELECT * FROM ts_stat('SELECT a FROM test_tsvector') ORDER BY ndoc DESC, nentry DESC, word LIMIT 10;
- word | ndoc | nentry
-------+------+--------
- qq | 108 | 108
- qt | 102 | 102
- qe | 100 | 100
- qh | 98 | 98
- qw | 98 | 98
- qa | 97 | 97
- ql | 94 | 94
- qs | 94 | 94
- qi | 92 | 92
- qr | 92 | 92
-(10 rows)
-
-SELECT * FROM ts_stat('SELECT a FROM test_tsvector', 'AB') ORDER BY ndoc DESC, nentry DESC, word;
- word | ndoc | nentry
-------+------+--------
- DFG | 1 | 2
-(1 row)
-
---dictionaries and to_tsvector
-SELECT ts_lexize('english_stem', 'skies');
- ts_lexize
------------
- {sky}
-(1 row)
-
-SELECT ts_lexize('english_stem', 'identity');
- ts_lexize
------------
- {ident}
-(1 row)
-
-SELECT * FROM ts_token_type('default') ORDER BY tokid;
- tokid | alias | description
--------+-----------------+------------------------------------------
- 1 | asciiword | Word, all ASCII
- 2 | word | Word, all letters
- 3 | numword | Word, letters and digits
- 4 | email | Email address
- 5 | url | URL
- 6 | host | Host
- 7 | sfloat | Scientific notation
- 8 | version | Version number
- 9 | hword_numpart | Hyphenated word part, letters and digits
- 10 | hword_part | Hyphenated word part, all letters
- 11 | hword_asciipart | Hyphenated word part, all ASCII
- 12 | blank | Space symbols
- 13 | tag | XML tag
- 14 | protocol | Protocol head
- 15 | numhword | Hyphenated word, letters and digits
- 16 | asciihword | Hyphenated word, all ASCII
- 17 | hword | Hyphenated word, all letters
- 18 | url_path | URL path
- 19 | file | File or path name
- 20 | float | Decimal notation
- 21 | int | Signed integer
- 22 | uint | Unsigned integer
- 23 | entity | XML entity
-(23 rows)
-
-SELECT * FROM ts_parse('default', '345
[email protected] '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005
[email protected] qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
-/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
-<i <b> wow < jqw <> qwerty') ORDER BY tokid,token;
- tokid | token
--------+--------------------------------------
- 1 | ad
- 1 | asdf
- 1 | dw
- 1 | hjwer
- 1 | i
- 1 | jf
- 1 | jqw
- 1 | qwe
- 1 | qwe
- 1 | qwe
- 1 | qwe
- 1 | qwer
- 1 | qwerty
- 1 | qwqwe
- 1 | readline
- 1 | readline
- 1 | readline
- 1 | sdjk
- 1 | we
- 1 | wefjn
- 1 | wow
- 3 | ewr1
- 3 | ewri2
- 5 | 1aew.werc.ewr/?ad=qwe&dw
- 5 | 3aew.werc.ewr/?ad=qwe&dw
- 5 | 5aew.werc.ewr:8100/?
- 5 | 6aew.werc.ewr:8100/?ad=qwe&dw
- 5 | 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32
- 5 | aew.werc.ewr/?ad=qwe&dw
- 6 | 1aew.werc.ewr
- 6 | 2aew.werc.ewr
- 6 | 3aew.werc.ewr
- 6 | 4aew.werc.ewr
- 6 | 5aew.werc.ewr:8100
- 6 | 6aew.werc.ewr:8100
- 6 | 7aew.werc.ewr:8100
- 6 | aew.werc.ewr
- 6 | www.com
- 7 | +4.0e-10
- 11 | qwe
- 11 | wer
- 12 | <
- 12 | <
- 12 | <>
- 12 | <
- 12 | =
- 12 | >
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 | '
- 12 | -
- 12 | ,
- 12 | /
- 12 | .
- 12 | .
- 12 | .
- 12 | @
- 12 | &
- 12 | +
- |
- 12 | +
- |
- 13 | <a href="qwe<qwe>">
- 13 | <b>
- 13 | <fr>
- 13 | <werrwe>
- 14 | http://
- 14 | http://
- 14 | http://
- 14 | http://
- 14 | http://
- 16 | qwe-wer
- 18 | /?
- 18 | /?ad=qwe&dw
- 18 | /?ad=qwe&dw
- 18 | /?ad=qwe&dw
- 18 | /?ad=qwe&dw
- 18 | /?ad=qwe&dw=%20%32
- 19 | /awdf/dwqe/4325
- 19 | efd.r
- 19 | gist.c
- 19 | gist.h
- 19 | gist.h.c
- 19 | rewt/ewr
- 19 | /usr/local/fff
- 19 | /wqe-324/ewr
- 20 | 234.435
- 20 | -4.2
- 20 | -4.2
- 20 | 4.2
- 20 | 4.2
- 20 | 4.2
- 20 | 5.005
- 22 | 234
- 22 | 345
- 22 | 455
-(133 rows)
-
-SELECT to_tsvector('english', '345
[email protected] '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005
[email protected] qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
-/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
-<i <b> wow < jqw <> qwerty');
- to_tsvector
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- '+4.0e-10':28 '-4.2':60,62 '/?':18 '/?ad=qwe&dw':7,10,14,24 '/?ad=qwe&dw=%20%32':27 '/awdf/dwqe/4325':48 '/usr/local/fff':47 '/wqe-324/ewr':51 '1aew.werc.ewr':9 '1aew.werc.ewr/?ad=qwe&dw':8 '234':63 '234.435':32 '2aew.werc.ewr':11 '345':1 '3aew.werc.ewr':13 '3aew.werc.ewr/?ad=qwe&dw':12 '4.2':56,57,58 '455':33 '4aew.werc.ewr':15 '5.005':34 '5aew.werc.ewr:8100':17 '5aew.werc.ewr:8100/?':16 '6aew.werc.ewr:8100':23 '6aew.werc.ewr:8100/?ad=qwe&dw':22 '7aew.werc.ewr:8100':26 '7aew.werc.ewr:8100/?ad=qwe&dw=%20%32':25 'ad':19 'aew.werc.ewr':6 'aew.werc.ewr/?ad=qwe&dw':5 'asdf':39 'dw':21 'efd.r':3 'ewr1':45 'ewri2':46 'gist.c':54 'gist.h':52 'gist.h.c':53 'hjwer':44 'jf':41 'jqw':66 'qwe':2,20,29,30,37 'qwe-wer':36 'qwer':40 'qwerti':67 'qwqwe':31 'readlin':55,59,61 'rewt/ewr':49 'sdjk':42 '
[email protected]':35 'wefjn':50 'wer':38 'wow':65 'www.com':4
-(1 row)
-
-SELECT length(to_tsvector('english', '345
[email protected] '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005
[email protected] qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
-/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
-<i <b> wow < jqw <> qwerty'));
- length
---------
- 53
-(1 row)
-
--- ts_debug
-SELECT * from ts_debug('english', '<myns:foo-bar_baz.blurfl>abc&nm1;def©ghiõjkl</myns:foo-bar_baz.blurfl>') ORDER BY alias, description, token;
- alias | description | token | dictionaries | dictionary | lexemes
------------+-----------------+----------------------------+----------------+--------------+---------
- asciiword | Word, all ASCII | abc | {english_stem} | english_stem | {abc}
- asciiword | Word, all ASCII | def | {english_stem} | english_stem | {def}
- asciiword | Word, all ASCII | ghi | {english_stem} | english_stem | {ghi}
- asciiword | Word, all ASCII | jkl | {english_stem} | english_stem | {jkl}
- entity | XML entity | õ | {} | |
- entity | XML entity | &nm1; | {} | |
- entity | XML entity | © | {} | |
- tag | XML tag | </myns:foo-bar_baz.blurfl> | {} | |
- tag | XML tag | <myns:foo-bar_baz.blurfl> | {} | |
-(9 rows)
-
--- check parsing of URLs
-SELECT * from ts_debug('english', 'http://www.harewoodsolutions.co.uk/press.aspx</span>');
- alias | description | token | dictionaries | dictionary | lexemes
-----------+---------------+----------------------------------------+--------------+------------+------------------------------------------
- protocol | Protocol head | http:// | {} | |
- url | URL | www.harewoodsolutions.co.uk/press.aspx | {simple} | simple | {www.harewoodsolutions.co.uk/press.aspx}
- host | Host | www.harewoodsolutions.co.uk | {simple} | simple | {www.harewoodsolutions.co.uk}
- url_path | URL path | /press.aspx | {simple} | simple | {/press.aspx}
- tag | XML tag | </span> | {} | |
-(5 rows)
-
-SELECT * from ts_debug('english', 'http://aew.wer0c.ewr/id?ad=qwe&dw<span>');
- alias | description | token | dictionaries | dictionary | lexemes
-----------+---------------+----------------------------+--------------+------------+------------------------------
- protocol | Protocol head | http:// | {} | |
- url | URL | aew.wer0c.ewr/id?ad=qwe&dw | {simple} | simple | {aew.wer0c.ewr/id?ad=qwe&dw}
- host | Host | aew.wer0c.ewr | {simple} | simple | {aew.wer0c.ewr}
- url_path | URL path | /id?ad=qwe&dw | {simple} | simple | {/id?ad=qwe&dw}
- tag | XML tag | <span> | {} | |
-(5 rows)
-
-SELECT * from ts_debug('english', 'http://5aew.werc.ewr:8100/?');
- alias | description | token | dictionaries | dictionary | lexemes
-----------+---------------+----------------------+--------------+------------+------------------------
- protocol | Protocol head | http:// | {} | |
- url | URL | 5aew.werc.ewr:8100/? | {simple} | simple | {5aew.werc.ewr:8100/?}
- host | Host | 5aew.werc.ewr:8100 | {simple} | simple | {5aew.werc.ewr:8100}
- url_path | URL path | /? | {simple} | simple | {/?}
-(4 rows)
-
-SELECT * from ts_debug('english', '5aew.werc.ewr:8100/?xx');
- alias | description | token | dictionaries | dictionary | lexemes
-----------+-------------+------------------------+--------------+------------+--------------------------
- url | URL | 5aew.werc.ewr:8100/?xx | {simple} | simple | {5aew.werc.ewr:8100/?xx}
- host | Host | 5aew.werc.ewr:8100 | {simple} | simple | {5aew.werc.ewr:8100}
- url_path | URL path | /?xx | {simple} | simple | {/?xx}
-(3 rows)
-
--- to_tsquery
-SELECT to_tsquery('english', 'qwe & sKies ');
- to_tsquery
----------------
- 'qwe' & 'sky'
-(1 row)
-
-SELECT to_tsquery('simple', 'qwe & sKies ');
- to_tsquery
------------------
- 'qwe' & 'skies'
-(1 row)
-
-SELECT to_tsquery('english', '''the wether'':dc & '' sKies '':BC ');
- to_tsquery
-------------------------
- 'wether':CD & 'sky':BC
-(1 row)
-
-SELECT to_tsquery('english', 'asd&(and|fghj)');
- to_tsquery
-----------------
- 'asd' & 'fghj'
-(1 row)
-
-SELECT to_tsquery('english', '(asd&and)|fghj');
- to_tsquery
-----------------
- 'asd' | 'fghj'
-(1 row)
-
-SELECT to_tsquery('english', '(asd&!and)|fghj');
- to_tsquery
-----------------
- 'asd' | 'fghj'
-(1 row)
-
-SELECT to_tsquery('english', '(the|and&(i&1))&fghj');
- to_tsquery
---------------
- '1' & 'fghj'
-(1 row)
-
-SELECT plainto_tsquery('english', 'the and z 1))& fghj');
- plainto_tsquery
---------------------
- 'z' & '1' & 'fghj'
-(1 row)
-
-SELECT plainto_tsquery('english', 'foo bar') && plainto_tsquery('english', 'asd');
- ?column?
------------------------
- 'foo' & 'bar' & 'asd'
-(1 row)
-
-SELECT plainto_tsquery('english', 'foo bar') || plainto_tsquery('english', 'asd fg');
- ?column?
-------------------------------
- 'foo' & 'bar' | 'asd' & 'fg'
-(1 row)
-
-SELECT plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'asd fg');
- ?column?
------------------------------------
- 'foo' & 'bar' | !( 'asd' & 'fg' )
-(1 row)
-
-SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg';
- ?column?
-----------------------------------
- 'foo' & 'bar' & ( 'asd' | 'fg' )
-(1 row)
-
-SELECT ts_rank_cd(to_tsvector('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-'), to_tsquery('english', 'paint&water'));
- ts_rank_cd
-------------
- 0.05
-(1 row)
-
-SELECT ts_rank_cd(to_tsvector('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-'), to_tsquery('english', 'breath&motion&water'));
- ts_rank_cd
-------------
- 0.00833333
-(1 row)
-
-SELECT ts_rank_cd(to_tsvector('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-'), to_tsquery('english', 'ocean'));
- ts_rank_cd
-------------
- 0.1
-(1 row)
-
-SELECT ts_rank_cd(strip(to_tsvector('both stripped')),
- to_tsquery('both & stripped'));
- ts_rank_cd
-------------
- 0
-(1 row)
-
-SELECT ts_rank_cd(to_tsvector('unstripped') || strip(to_tsvector('stripped')),
- to_tsquery('unstripped & stripped'));
- ts_rank_cd
-------------
- 0
-(1 row)
-
---headline tests
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'paint&water'));
- ts_headline
------------------------------------------
- <b>painted</b> Ocean. +
- <b>Water</b>, <b>water</b>, every where+
- And all the boards did shrink; +
- <b>Water</b>, <b>water</b>, every
-(1 row)
-
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'breath&motion&water'));
- ts_headline
-----------------------------------
- <b>breath</b> nor <b>motion</b>,+
- As idle as a painted Ship +
- Upon a painted Ocean. +
- <b>Water</b>, <b>water</b>
-(1 row)
-
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'ocean'));
- ts_headline
-----------------------------------
- <b>Ocean</b>. +
- Water, water, every where +
- And all the boards did shrink;+
- Water, water, every where
-(1 row)
-
-SELECT ts_headline('english', '
-<html>
-<!-- some comment -->
-<body>
-Sea view wow <u>foo bar</u> <i>qq</i>
-<a href="http://www.google.com/foo.bar.html" target="_blank">YES </a>
-ff-bg
-<script>
- document.write(15);
-</script>
-</body>
-</html>',
-to_tsquery('english', 'sea&foo'), 'HighlightAll=true');
- ts_headline
------------------------------------------------------------------------------
- +
- <html> +
- <!-- some comment --> +
- <body> +
- <b>Sea</b> view wow <u><b>foo</b> bar</u> <i>qq</i> +
- <a href="http://www.google.com/foo.bar.html" target="_blank">YES </a>+
- ff-bg +
- <script> +
- document.write(15); +
- </script> +
- </body> +
- </html>
-(1 row)
-
---Check if headline fragments work
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'ocean'), 'MaxFragments=1');
- ts_headline
-------------------------------------
- after day, +
- We stuck, nor breath nor motion,+
- As idle as a painted Ship +
- Upon a painted <b>Ocean</b>. +
- Water, water, every where +
- And all the boards did shrink; +
- Water, water, every where, +
- Nor any drop
-(1 row)
-
---Check if more than one fragments are displayed
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2');
- ts_headline
-----------------------------------------------
- after day, day after day, +
- We <b>stuck</b>, nor breath nor motion, +
- As idle as a painted Ship +
- Upon a painted Ocean. +
- Water, water, every where +
- And all the boards did shrink; +
- Water, water, every where ... drop to drink.+
- S. T. <b>Coleridge</b>
-(1 row)
-
---Fragments when there all query words are not in the document
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'ocean & seahorse'), 'MaxFragments=1');
- ts_headline
-------------------------------------
- +
- Day after day, day after day, +
- We stuck, nor breath nor motion,+
- As idle as
-(1 row)
-
---FragmentDelimiter option
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2,FragmentDelimiter=***');
- ts_headline
---------------------------------------------
- after day, day after day, +
- We <b>stuck</b>, nor breath nor motion, +
- As idle as a painted Ship +
- Upon a painted Ocean. +
- Water, water, every where +
- And all the boards did shrink; +
- Water, water, every where***drop to drink.+
- S. T. <b>Coleridge</b>
-(1 row)
-
---Rewrite sub system
-CREATE TABLE test_tsquery (txtkeyword TEXT, txtsample TEXT);
-\set ECHO none
-ALTER TABLE test_tsquery ADD COLUMN keyword tsquery;
-UPDATE test_tsquery SET keyword = to_tsquery('english', txtkeyword);
-ALTER TABLE test_tsquery ADD COLUMN sample tsquery;
-UPDATE test_tsquery SET sample = to_tsquery('english', txtsample::text);
-SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new & york';
- count
--------
- 1
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new & york';
- count
--------
- 2
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new & york';
- count
--------
- 1
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new & york';
- count
--------
- 3
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new & york';
- count
--------
- 2
-(1 row)
-
-CREATE UNIQUE INDEX bt_tsq ON test_tsquery (keyword);
-ERROR: Unique index of partitioned table must contain the hash/modulo distribution column.
-SET enable_seqscan=OFF;
-SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new & york';
- count
--------
- 1
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new & york';
- count
--------
- 2
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new & york';
- count
--------
- 1
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new & york';
- count
--------
- 3
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new & york';
- count
--------
- 2
-(1 row)
-
-RESET enable_seqscan;
-SELECT ts_rewrite('foo & bar & qq & new & york', 'new & york'::tsquery, 'big & apple | nyc | new & york & city');
- ts_rewrite
-----------------------------------------------------------------------------------
- 'foo' & 'bar' & 'qq' & ( 'city' & 'new' & 'york' | ( 'nyc' | 'big' & 'apple' ) )
-(1 row)
-
-SELECT ts_rewrite('moscow', 'SELECT keyword, sample FROM test_tsquery'::text );
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite('moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'::text );
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite('bar & new & qq & foo & york', 'SELECT keyword, sample FROM test_tsquery'::text );
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-SELECT ts_rewrite( 'moscow', 'SELECT keyword, sample FROM test_tsquery');
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( 'moscow & hotel', 'SELECT keyword, sample FROM test_tsquery');
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( 'bar & new & qq & foo & york', 'SELECT keyword, sample FROM test_tsquery');
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword @> 'new';
- keyword
-----------------
- 'new' & 'york'
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow';
- keyword
-----------
- 'moscow'
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword <@ 'new';
- keyword
----------
-(0 rows)
-
-SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow';
- keyword
-----------
- 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query;
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query;
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-CREATE INDEX qq ON test_tsquery USING gist (keyword tsquery_ops);
-SET enable_seqscan=OFF;
-SELECT keyword FROM test_tsquery WHERE keyword @> 'new';
- keyword
-----------------
- 'new' & 'york'
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow';
- keyword
-----------
- 'moscow'
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword <@ 'new';
- keyword
----------
-(0 rows)
-
-SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow';
- keyword
-----------
- 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query;
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query;
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-RESET enable_seqscan;
---test GUC
-SET default_text_search_config=simple;
-SELECT to_tsvector('SKIES My booKs');
- to_tsvector
-----------------------------
- 'books':3 'my':2 'skies':1
-(1 row)
-
-SELECT plainto_tsquery('SKIES My booKs');
- plainto_tsquery
---------------------------
- 'skies' & 'my' & 'books'
-(1 row)
-
-SELECT to_tsquery('SKIES & My | booKs');
- to_tsquery
---------------------------
- 'skies' & 'my' | 'books'
-(1 row)
-
-SET default_text_search_config=english;
-SELECT to_tsvector('SKIES My booKs');
- to_tsvector
-------------------
- 'book':3 'sky':1
-(1 row)
-
-SELECT plainto_tsquery('SKIES My booKs');
- plainto_tsquery
------------------
- 'sky' & 'book'
-(1 row)
-
-SELECT to_tsquery('SKIES & My | booKs');
- to_tsquery
-----------------
- 'sky' | 'book'
-(1 row)
-
---trigger
-CREATE TRIGGER tsvectorupdate
-BEFORE UPDATE OR INSERT ON test_tsvector
-FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(a, 'pg_catalog.english', t);
-ERROR: Postgres-XL does not support TRIGGER yet
-DETAIL: The feature is not currently supported
-SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
- count
--------
- 0
-(1 row)
-
-INSERT INTO test_tsvector (t) VALUES ('345 qwerty');
-SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
- count
--------
- 0
-(1 row)
-
-UPDATE test_tsvector SET t = null WHERE t = '345 qwerty';
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
- count
--------
- 0
-(1 row)
-
-INSERT INTO test_tsvector (t) VALUES ('345 qwerty');
-SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
- count
--------
- 0
-(1 row)
-
--- test finding items in GIN's pending list
-create table pendtest (ts tsvector);
-create index pendtest_idx on pendtest using gin(ts);
-insert into pendtest values (to_tsvector('Lore ipsam'));
-insert into pendtest values (to_tsvector('Lore ipsum'));
-select * from pendtest where 'ipsu:*'::tsquery @@ ts;
- ts
---------------------
- 'ipsum':2 'lore':1
-(1 row)
-
-select * from pendtest where 'ipsa:*'::tsquery @@ ts;
- ts
---------------------
- 'ipsam':2 'lore':1
-(1 row)
-
-select * from pendtest where 'ips:*'::tsquery @@ ts ORDER BY 1;
- ts
---------------------
- 'ipsam':2 'lore':1
- 'ipsum':2 'lore':1
-(2 rows)
-
-select * from pendtest where 'ipt:*'::tsquery @@ ts;
- ts
-----
-(0 rows)
-
-select * from pendtest where 'ipi:*'::tsquery @@ ts;
- ts
-----
-(0 rows)
-
-drop table pendtest;
+++ /dev/null
---
--- Sanity checks for text search catalogs
---
--- NB: we assume the oidjoins test will have caught any dangling links,
--- that is OID or REGPROC fields that are not zero and do not match some
--- row in the linked-to table. However, if we want to enforce that a link
--- field can't be 0, we have to check it here.
--- Find unexpected zero link entries
-SELECT oid, prsname
-FROM pg_ts_parser
-WHERE prsnamespace = 0 OR prsstart = 0 OR prstoken = 0 OR prsend = 0 OR
- -- prsheadline is optional
- prslextype = 0;
- oid | prsname
------+---------
-(0 rows)
-
-SELECT oid, dictname
-FROM pg_ts_dict
-WHERE dictnamespace = 0 OR dictowner = 0 OR dicttemplate = 0;
- oid | dictname
------+----------
-(0 rows)
-
-SELECT oid, tmplname
-FROM pg_ts_template
-WHERE tmplnamespace = 0 OR tmpllexize = 0; -- tmplinit is optional
- oid | tmplname
------+----------
-(0 rows)
-
-SELECT oid, cfgname
-FROM pg_ts_config
-WHERE cfgnamespace = 0 OR cfgowner = 0 OR cfgparser = 0;
- oid | cfgname
------+---------
-(0 rows)
-
-SELECT mapcfg, maptokentype, mapseqno
-FROM pg_ts_config_map
-WHERE mapcfg = 0 OR mapdict = 0;
- mapcfg | maptokentype | mapseqno
---------+--------------+----------
-(0 rows)
-
--- Look for pg_ts_config_map entries that aren't one of parser's token types
-SELECT * FROM
- ( SELECT oid AS cfgid, (ts_token_type(cfgparser)).tokid AS tokid
- FROM pg_ts_config ) AS tt
-RIGHT JOIN pg_ts_config_map AS m
- ON (tt.cfgid=m.mapcfg AND tt.tokid=m.maptokentype)
-WHERE
- tt.cfgid IS NULL OR tt.tokid IS NULL;
- cfgid | tokid | mapcfg | maptokentype | mapseqno | mapdict
--------+-------+--------+--------------+----------+---------
-(0 rows)
-
--- test basic text search behavior without indexes, then with
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
- count
--------
- 158
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
- count
--------
- 17
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
- count
--------
- 6
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
- count
--------
- 98
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
- count
--------
- 23
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
- count
--------
- 39
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*';
- count
--------
- 494
-(1 row)
-
-create index wowidx on test_tsvector using gist (a);
-SET enable_seqscan=OFF;
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
- count
--------
- 158
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
- count
--------
- 17
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
- count
--------
- 6
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
- count
--------
- 98
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
- count
--------
- 23
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
- count
--------
- 39
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*';
- count
--------
- 494
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}');
- count
--------
- 158
-(1 row)
-
-RESET enable_seqscan;
-DROP INDEX wowidx;
-CREATE INDEX wowidx ON test_tsvector USING gin (a);
-SET enable_seqscan=OFF;
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
- count
--------
- 158
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
- count
--------
- 17
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
- count
--------
- 6
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
- count
--------
- 98
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
- count
--------
- 23
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
- count
--------
- 39
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*';
- count
--------
- 494
-(1 row)
-
-SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}');
- count
--------
- 158
-(1 row)
-
-RESET enable_seqscan;
-INSERT INTO test_tsvector VALUES ('???', 'DFG:1A,2B,6C,10 FGH');
-SELECT * FROM ts_stat('SELECT a FROM test_tsvector') ORDER BY ndoc DESC, nentry DESC, word LIMIT 10;
- word | ndoc | nentry
-------+------+--------
- qq | 108 | 108
- qt | 102 | 102
- qe | 100 | 100
- qh | 98 | 98
- qw | 98 | 98
- qa | 97 | 97
- ql | 94 | 94
- qs | 94 | 94
- qi | 92 | 92
- qr | 92 | 92
-(10 rows)
-
-SELECT * FROM ts_stat('SELECT a FROM test_tsvector', 'AB') ORDER BY ndoc DESC, nentry DESC, word;
- word | ndoc | nentry
-------+------+--------
- DFG | 1 | 2
-(1 row)
-
---dictionaries and to_tsvector
-SELECT ts_lexize('english_stem', 'skies');
- ts_lexize
------------
- {sky}
-(1 row)
-
-SELECT ts_lexize('english_stem', 'identity');
- ts_lexize
------------
- {ident}
-(1 row)
-
-SELECT * FROM ts_token_type('default') ORDER BY tokid;
- tokid | alias | description
--------+-----------------+------------------------------------------
- 1 | asciiword | Word, all ASCII
- 2 | word | Word, all letters
- 3 | numword | Word, letters and digits
- 4 | email | Email address
- 5 | url | URL
- 6 | host | Host
- 7 | sfloat | Scientific notation
- 8 | version | Version number
- 9 | hword_numpart | Hyphenated word part, letters and digits
- 10 | hword_part | Hyphenated word part, all letters
- 11 | hword_asciipart | Hyphenated word part, all ASCII
- 12 | blank | Space symbols
- 13 | tag | XML tag
- 14 | protocol | Protocol head
- 15 | numhword | Hyphenated word, letters and digits
- 16 | asciihword | Hyphenated word, all ASCII
- 17 | hword | Hyphenated word, all letters
- 18 | url_path | URL path
- 19 | file | File or path name
- 20 | float | Decimal notation
- 21 | int | Signed integer
- 22 | uint | Unsigned integer
- 23 | entity | XML entity
-(23 rows)
-
-SELECT * FROM ts_parse('default', '345
[email protected] '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005
[email protected] qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
-/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
-<i <b> wow < jqw <> qwerty') ORDER BY tokid,token;
- tokid | token
--------+--------------------------------------
- 1 | ad
- 1 | asdf
- 1 | dw
- 1 | hjwer
- 1 | i
- 1 | jf
- 1 | jqw
- 1 | qwe
- 1 | qwe
- 1 | qwe
- 1 | qwe
- 1 | qwer
- 1 | qwerty
- 1 | qwqwe
- 1 | readline
- 1 | readline
- 1 | readline
- 1 | sdjk
- 1 | we
- 1 | wefjn
- 1 | wow
- 3 | ewr1
- 3 | ewri2
- 5 | 1aew.werc.ewr/?ad=qwe&dw
- 5 | 3aew.werc.ewr/?ad=qwe&dw
- 5 | 5aew.werc.ewr:8100/?
- 5 | 6aew.werc.ewr:8100/?ad=qwe&dw
- 5 | 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32
- 5 | aew.werc.ewr/?ad=qwe&dw
- 6 | 1aew.werc.ewr
- 6 | 2aew.werc.ewr
- 6 | 3aew.werc.ewr
- 6 | 4aew.werc.ewr
- 6 | 5aew.werc.ewr:8100
- 6 | 6aew.werc.ewr:8100
- 6 | 7aew.werc.ewr:8100
- 6 | aew.werc.ewr
- 6 | www.com
- 7 | +4.0e-10
- 11 | qwe
- 11 | wer
- 12 | +
- |
- 12 | +
- |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 |
- 12 | '
- 12 | &
- 12 | ,
- 12 | -
- 12 | .
- 12 | .
- 12 | .
- 12 | /
- 12 | <
- 12 | <
- 12 | <
- 12 | <>
- 12 | =
- 12 | >
- 12 | @
- 13 | <a href="qwe<qwe>">
- 13 | <b>
- 13 | <fr>
- 13 | <werrwe>
- 14 | http://
- 14 | http://
- 14 | http://
- 14 | http://
- 14 | http://
- 16 | qwe-wer
- 18 | /?
- 18 | /?ad=qwe&dw
- 18 | /?ad=qwe&dw
- 18 | /?ad=qwe&dw
- 18 | /?ad=qwe&dw
- 18 | /?ad=qwe&dw=%20%32
- 19 | /awdf/dwqe/4325
- 19 | /usr/local/fff
- 19 | /wqe-324/ewr
- 19 | efd.r
- 19 | gist.c
- 19 | gist.h
- 19 | gist.h.c
- 19 | rewt/ewr
- 20 | -4.2
- 20 | -4.2
- 20 | 234.435
- 20 | 4.2
- 20 | 4.2
- 20 | 4.2
- 20 | 5.005
- 22 | 234
- 22 | 345
- 22 | 455
-(133 rows)
-
-SELECT to_tsvector('english', '345
[email protected] '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005
[email protected] qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
-/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
-<i <b> wow < jqw <> qwerty');
- to_tsvector
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- '+4.0e-10':28 '-4.2':60,62 '/?':18 '/?ad=qwe&dw':7,10,14,24 '/?ad=qwe&dw=%20%32':27 '/awdf/dwqe/4325':48 '/usr/local/fff':47 '/wqe-324/ewr':51 '1aew.werc.ewr':9 '1aew.werc.ewr/?ad=qwe&dw':8 '234':63 '234.435':32 '2aew.werc.ewr':11 '345':1 '3aew.werc.ewr':13 '3aew.werc.ewr/?ad=qwe&dw':12 '4.2':56,57,58 '455':33 '4aew.werc.ewr':15 '5.005':34 '5aew.werc.ewr:8100':17 '5aew.werc.ewr:8100/?':16 '6aew.werc.ewr:8100':23 '6aew.werc.ewr:8100/?ad=qwe&dw':22 '7aew.werc.ewr:8100':26 '7aew.werc.ewr:8100/?ad=qwe&dw=%20%32':25 'ad':19 'aew.werc.ewr':6 'aew.werc.ewr/?ad=qwe&dw':5 'asdf':39 'dw':21 'efd.r':3 'ewr1':45 'ewri2':46 'gist.c':54 'gist.h':52 'gist.h.c':53 'hjwer':44 'jf':41 'jqw':66 'qwe':2,20,29,30,37 'qwe-wer':36 'qwer':40 'qwerti':67 'qwqwe':31 'readlin':55,59,61 'rewt/ewr':49 'sdjk':42 '
[email protected]':35 'wefjn':50 'wer':38 'wow':65 'www.com':4
-(1 row)
-
-SELECT length(to_tsvector('english', '345
[email protected] '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005
[email protected] qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
-/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
-<i <b> wow < jqw <> qwerty'));
- length
---------
- 53
-(1 row)
-
--- ts_debug
-SELECT * from ts_debug('english', '<myns:foo-bar_baz.blurfl>abc&nm1;def©ghiõjkl</myns:foo-bar_baz.blurfl>') ORDER BY alias, description, token;
- alias | description | token | dictionaries | dictionary | lexemes
------------+-----------------+----------------------------+----------------+--------------+---------
- asciiword | Word, all ASCII | abc | {english_stem} | english_stem | {abc}
- asciiword | Word, all ASCII | def | {english_stem} | english_stem | {def}
- asciiword | Word, all ASCII | ghi | {english_stem} | english_stem | {ghi}
- asciiword | Word, all ASCII | jkl | {english_stem} | english_stem | {jkl}
- entity | XML entity | õ | {} | |
- entity | XML entity | © | {} | |
- entity | XML entity | &nm1; | {} | |
- tag | XML tag | </myns:foo-bar_baz.blurfl> | {} | |
- tag | XML tag | <myns:foo-bar_baz.blurfl> | {} | |
-(9 rows)
-
--- check parsing of URLs
-SELECT * from ts_debug('english', 'http://www.harewoodsolutions.co.uk/press.aspx</span>');
- alias | description | token | dictionaries | dictionary | lexemes
-----------+---------------+----------------------------------------+--------------+------------+------------------------------------------
- protocol | Protocol head | http:// | {} | |
- url | URL | www.harewoodsolutions.co.uk/press.aspx | {simple} | simple | {www.harewoodsolutions.co.uk/press.aspx}
- host | Host | www.harewoodsolutions.co.uk | {simple} | simple | {www.harewoodsolutions.co.uk}
- url_path | URL path | /press.aspx | {simple} | simple | {/press.aspx}
- tag | XML tag | </span> | {} | |
-(5 rows)
-
-SELECT * from ts_debug('english', 'http://aew.wer0c.ewr/id?ad=qwe&dw<span>');
- alias | description | token | dictionaries | dictionary | lexemes
-----------+---------------+----------------------------+--------------+------------+------------------------------
- protocol | Protocol head | http:// | {} | |
- url | URL | aew.wer0c.ewr/id?ad=qwe&dw | {simple} | simple | {aew.wer0c.ewr/id?ad=qwe&dw}
- host | Host | aew.wer0c.ewr | {simple} | simple | {aew.wer0c.ewr}
- url_path | URL path | /id?ad=qwe&dw | {simple} | simple | {/id?ad=qwe&dw}
- tag | XML tag | <span> | {} | |
-(5 rows)
-
-SELECT * from ts_debug('english', 'http://5aew.werc.ewr:8100/?');
- alias | description | token | dictionaries | dictionary | lexemes
-----------+---------------+----------------------+--------------+------------+------------------------
- protocol | Protocol head | http:// | {} | |
- url | URL | 5aew.werc.ewr:8100/? | {simple} | simple | {5aew.werc.ewr:8100/?}
- host | Host | 5aew.werc.ewr:8100 | {simple} | simple | {5aew.werc.ewr:8100}
- url_path | URL path | /? | {simple} | simple | {/?}
-(4 rows)
-
-SELECT * from ts_debug('english', '5aew.werc.ewr:8100/?xx');
- alias | description | token | dictionaries | dictionary | lexemes
-----------+-------------+------------------------+--------------+------------+--------------------------
- url | URL | 5aew.werc.ewr:8100/?xx | {simple} | simple | {5aew.werc.ewr:8100/?xx}
- host | Host | 5aew.werc.ewr:8100 | {simple} | simple | {5aew.werc.ewr:8100}
- url_path | URL path | /?xx | {simple} | simple | {/?xx}
-(3 rows)
-
--- to_tsquery
-SELECT to_tsquery('english', 'qwe & sKies ');
- to_tsquery
----------------
- 'qwe' & 'sky'
-(1 row)
-
-SELECT to_tsquery('simple', 'qwe & sKies ');
- to_tsquery
------------------
- 'qwe' & 'skies'
-(1 row)
-
-SELECT to_tsquery('english', '''the wether'':dc & '' sKies '':BC ');
- to_tsquery
-------------------------
- 'wether':CD & 'sky':BC
-(1 row)
-
-SELECT to_tsquery('english', 'asd&(and|fghj)');
- to_tsquery
-----------------
- 'asd' & 'fghj'
-(1 row)
-
-SELECT to_tsquery('english', '(asd&and)|fghj');
- to_tsquery
-----------------
- 'asd' | 'fghj'
-(1 row)
-
-SELECT to_tsquery('english', '(asd&!and)|fghj');
- to_tsquery
-----------------
- 'asd' | 'fghj'
-(1 row)
-
-SELECT to_tsquery('english', '(the|and&(i&1))&fghj');
- to_tsquery
---------------
- '1' & 'fghj'
-(1 row)
-
-SELECT plainto_tsquery('english', 'the and z 1))& fghj');
- plainto_tsquery
---------------------
- 'z' & '1' & 'fghj'
-(1 row)
-
-SELECT plainto_tsquery('english', 'foo bar') && plainto_tsquery('english', 'asd');
- ?column?
------------------------
- 'foo' & 'bar' & 'asd'
-(1 row)
-
-SELECT plainto_tsquery('english', 'foo bar') || plainto_tsquery('english', 'asd fg');
- ?column?
-------------------------------
- 'foo' & 'bar' | 'asd' & 'fg'
-(1 row)
-
-SELECT plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'asd fg');
- ?column?
------------------------------------
- 'foo' & 'bar' | !( 'asd' & 'fg' )
-(1 row)
-
-SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg';
- ?column?
-----------------------------------
- 'foo' & 'bar' & ( 'asd' | 'fg' )
-(1 row)
-
-SELECT ts_rank_cd(to_tsvector('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-'), to_tsquery('english', 'paint&water'));
- ts_rank_cd
-------------
- 0.05
-(1 row)
-
-SELECT ts_rank_cd(to_tsvector('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-'), to_tsquery('english', 'breath&motion&water'));
- ts_rank_cd
-------------
- 0.00833333
-(1 row)
-
-SELECT ts_rank_cd(to_tsvector('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-'), to_tsquery('english', 'ocean'));
- ts_rank_cd
-------------
- 0.1
-(1 row)
-
-SELECT ts_rank_cd(strip(to_tsvector('both stripped')),
- to_tsquery('both & stripped'));
- ts_rank_cd
-------------
- 0
-(1 row)
-
-SELECT ts_rank_cd(to_tsvector('unstripped') || strip(to_tsvector('stripped')),
- to_tsquery('unstripped & stripped'));
- ts_rank_cd
-------------
- 0
-(1 row)
-
---headline tests
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'paint&water'));
- ts_headline
------------------------------------------
- <b>painted</b> Ocean. +
- <b>Water</b>, <b>water</b>, every where+
- And all the boards did shrink; +
- <b>Water</b>, <b>water</b>, every
-(1 row)
-
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'breath&motion&water'));
- ts_headline
-----------------------------------
- <b>breath</b> nor <b>motion</b>,+
- As idle as a painted Ship +
- Upon a painted Ocean. +
- <b>Water</b>, <b>water</b>
-(1 row)
-
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'ocean'));
- ts_headline
-----------------------------------
- <b>Ocean</b>. +
- Water, water, every where +
- And all the boards did shrink;+
- Water, water, every where
-(1 row)
-
-SELECT ts_headline('english', '
-<html>
-<!-- some comment -->
-<body>
-Sea view wow <u>foo bar</u> <i>qq</i>
-<a href="http://www.google.com/foo.bar.html" target="_blank">YES </a>
-ff-bg
-<script>
- document.write(15);
-</script>
-</body>
-</html>',
-to_tsquery('english', 'sea&foo'), 'HighlightAll=true');
- ts_headline
------------------------------------------------------------------------------
- +
- <html> +
- <!-- some comment --> +
- <body> +
- <b>Sea</b> view wow <u><b>foo</b> bar</u> <i>qq</i> +
- <a href="http://www.google.com/foo.bar.html" target="_blank">YES </a>+
- ff-bg +
- <script> +
- document.write(15); +
- </script> +
- </body> +
- </html>
-(1 row)
-
---Check if headline fragments work
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'ocean'), 'MaxFragments=1');
- ts_headline
-------------------------------------
- after day, +
- We stuck, nor breath nor motion,+
- As idle as a painted Ship +
- Upon a painted <b>Ocean</b>. +
- Water, water, every where +
- And all the boards did shrink; +
- Water, water, every where, +
- Nor any drop
-(1 row)
-
---Check if more than one fragments are displayed
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2');
- ts_headline
-----------------------------------------------
- after day, day after day, +
- We <b>stuck</b>, nor breath nor motion, +
- As idle as a painted Ship +
- Upon a painted Ocean. +
- Water, water, every where +
- And all the boards did shrink; +
- Water, water, every where ... drop to drink.+
- S. T. <b>Coleridge</b>
-(1 row)
-
---Fragments when there all query words are not in the document
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'ocean & seahorse'), 'MaxFragments=1');
- ts_headline
-------------------------------------
- +
- Day after day, day after day, +
- We stuck, nor breath nor motion,+
- As idle as
-(1 row)
-
---FragmentDelimiter option
-SELECT ts_headline('english', '
-Day after day, day after day,
- We stuck, nor breath nor motion,
-As idle as a painted Ship
- Upon a painted Ocean.
-Water, water, every where
- And all the boards did shrink;
-Water, water, every where,
- Nor any drop to drink.
-S. T. Coleridge (1772-1834)
-', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2,FragmentDelimiter=***');
- ts_headline
---------------------------------------------
- after day, day after day, +
- We <b>stuck</b>, nor breath nor motion, +
- As idle as a painted Ship +
- Upon a painted Ocean. +
- Water, water, every where +
- And all the boards did shrink; +
- Water, water, every where***drop to drink.+
- S. T. <b>Coleridge</b>
-(1 row)
-
---Rewrite sub system
-CREATE TABLE test_tsquery (txtkeyword TEXT, txtsample TEXT);
-\set ECHO none
-ALTER TABLE test_tsquery ADD COLUMN keyword tsquery;
-UPDATE test_tsquery SET keyword = to_tsquery('english', txtkeyword);
-ALTER TABLE test_tsquery ADD COLUMN sample tsquery;
-UPDATE test_tsquery SET sample = to_tsquery('english', txtsample::text);
-SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new & york';
- count
--------
- 1
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new & york';
- count
--------
- 2
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new & york';
- count
--------
- 1
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new & york';
- count
--------
- 3
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new & york';
- count
--------
- 2
-(1 row)
-
-CREATE UNIQUE INDEX bt_tsq ON test_tsquery (keyword);
-ERROR: Unique index of partitioned table must contain the hash/modulo distribution column.
-SET enable_seqscan=OFF;
-SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new & york';
- count
--------
- 1
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new & york';
- count
--------
- 2
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new & york';
- count
--------
- 1
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new & york';
- count
--------
- 3
-(1 row)
-
-SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new & york';
- count
--------
- 2
-(1 row)
-
-RESET enable_seqscan;
-SELECT ts_rewrite('foo & bar & qq & new & york', 'new & york'::tsquery, 'big & apple | nyc | new & york & city');
- ts_rewrite
-----------------------------------------------------------------------------------
- 'foo' & 'bar' & 'qq' & ( 'city' & 'new' & 'york' | ( 'nyc' | 'big' & 'apple' ) )
-(1 row)
-
-SELECT ts_rewrite('moscow', 'SELECT keyword, sample FROM test_tsquery'::text );
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite('moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'::text );
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite('bar & new & qq & foo & york', 'SELECT keyword, sample FROM test_tsquery'::text );
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-SELECT ts_rewrite( 'moscow', 'SELECT keyword, sample FROM test_tsquery');
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( 'moscow & hotel', 'SELECT keyword, sample FROM test_tsquery');
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( 'bar & new & qq & foo & york', 'SELECT keyword, sample FROM test_tsquery');
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword @> 'new';
- keyword
-----------------
- 'new' & 'york'
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow';
- keyword
-----------
- 'moscow'
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword <@ 'new';
- keyword
----------
-(0 rows)
-
-SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow';
- keyword
-----------
- 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query;
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query;
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-CREATE INDEX qq ON test_tsquery USING gist (keyword tsquery_ops);
-SET enable_seqscan=OFF;
-SELECT keyword FROM test_tsquery WHERE keyword @> 'new';
- keyword
-----------------
- 'new' & 'york'
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow';
- keyword
-----------
- 'moscow'
-(1 row)
-
-SELECT keyword FROM test_tsquery WHERE keyword <@ 'new';
- keyword
----------
-(0 rows)
-
-SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow';
- keyword
-----------
- 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query;
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
- ts_rewrite
----------------------
- 'moskva' | 'moscow'
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query;
- ts_rewrite
------------------------------------
- 'hotel' & ( 'moskva' | 'moscow' )
-(1 row)
-
-SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
- ts_rewrite
--------------------------------------------------------------------------------------
- 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
-(1 row)
-
-RESET enable_seqscan;
---test GUC
-SET default_text_search_config=simple;
-SELECT to_tsvector('SKIES My booKs');
- to_tsvector
-----------------------------
- 'books':3 'my':2 'skies':1
-(1 row)
-
-SELECT plainto_tsquery('SKIES My booKs');
- plainto_tsquery
---------------------------
- 'skies' & 'my' & 'books'
-(1 row)
-
-SELECT to_tsquery('SKIES & My | booKs');
- to_tsquery
---------------------------
- 'skies' & 'my' | 'books'
-(1 row)
-
-SET default_text_search_config=english;
-SELECT to_tsvector('SKIES My booKs');
- to_tsvector
-------------------
- 'book':3 'sky':1
-(1 row)
-
-SELECT plainto_tsquery('SKIES My booKs');
- plainto_tsquery
------------------
- 'sky' & 'book'
-(1 row)
-
-SELECT to_tsquery('SKIES & My | booKs');
- to_tsquery
-----------------
- 'sky' | 'book'
-(1 row)
-
---trigger
-CREATE TRIGGER tsvectorupdate
-BEFORE UPDATE OR INSERT ON test_tsvector
-FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(a, 'pg_catalog.english', t);
-ERROR: Postgres-XL does not support TRIGGER yet
-DETAIL: The feature is not currently supported
-SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
- count
--------
- 0
-(1 row)
-
-INSERT INTO test_tsvector (t) VALUES ('345 qwerty');
-SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
- count
--------
- 0
-(1 row)
-
-UPDATE test_tsvector SET t = null WHERE t = '345 qwerty';
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
- count
--------
- 0
-(1 row)
-
-INSERT INTO test_tsvector (t) VALUES ('345 qwerty');
-SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
- count
--------
- 0
-(1 row)
-
--- test finding items in GIN's pending list
-create table pendtest (ts tsvector);
-create index pendtest_idx on pendtest using gin(ts);
-insert into pendtest values (to_tsvector('Lore ipsam'));
-insert into pendtest values (to_tsvector('Lore ipsum'));
-select * from pendtest where 'ipsu:*'::tsquery @@ ts;
- ts
---------------------
- 'ipsum':2 'lore':1
-(1 row)
-
-select * from pendtest where 'ipsa:*'::tsquery @@ ts;
- ts
---------------------
- 'ipsam':2 'lore':1
-(1 row)
-
-select * from pendtest where 'ips:*'::tsquery @@ ts ORDER BY 1;
- ts
---------------------
- 'ipsam':2 'lore':1
- 'ipsum':2 'lore':1
-(2 rows)
-
-select * from pendtest where 'ipt:*'::tsquery @@ ts;
- ts
-----
-(0 rows)
-
-select * from pendtest where 'ipi:*'::tsquery @@ ts;
- ts
-----
-(0 rows)
-
-drop table pendtest;
+++ /dev/null
-CREATE TABLE ttable1 OF nothing;
-ERROR: type "nothing" does not exist
-CREATE TYPE person_type AS (id int, name text);
-CREATE TABLE persons OF person_type;
-CREATE TABLE IF NOT EXISTS persons OF person_type;
-NOTICE: relation "persons" already exists, skipping
-SELECT * FROM persons;
- id | name
-----+------
-(0 rows)
-
-\d persons
- Table "public.persons"
- Column | Type | Modifiers
---------+---------+-----------
- id | integer |
- name | text |
-Typed table of type: person_type
-
-CREATE FUNCTION get_all_persons() RETURNS SETOF person_type
-LANGUAGE SQL
-AS $$
- SELECT * FROM persons;
-$$;
-SELECT * FROM get_all_persons();
- id | name
-----+------
-(0 rows)
-
--- certain ALTER TABLE operations on typed tables are not allowed
-ALTER TABLE persons ADD COLUMN comment text;
-ERROR: cannot add column to typed table
-ALTER TABLE persons DROP COLUMN name;
-ERROR: cannot drop column from typed table
-ALTER TABLE persons RENAME COLUMN id TO num;
-ERROR: cannot rename column of typed table
-ALTER TABLE persons ALTER COLUMN name TYPE varchar;
-ERROR: cannot alter column type of typed table
-CREATE TABLE stuff (id int);
-ALTER TABLE persons INHERIT stuff;
-ERROR: cannot change inheritance of typed table
-CREATE TABLE personsx OF person_type (myname WITH OPTIONS NOT NULL); -- error
-ERROR: column "myname" does not exist
-CREATE TABLE persons2 OF person_type (
- id WITH OPTIONS PRIMARY KEY,
- UNIQUE (name)
-);
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "persons2_pkey" for table "persons2"
-ERROR: Unique index of partitioned table must contain the hash/modulo distribution column.
-\d persons2
-CREATE TABLE persons3 OF person_type (
- PRIMARY KEY (id),
- name WITH OPTIONS DEFAULT ''
-);
-NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "persons3_pkey" for table "persons3"
-\d persons3
- Table "public.persons3"
- Column | Type | Modifiers
---------+---------+------------------
- id | integer | not null
- name | text | default ''::text
-Indexes:
- "persons3_pkey" PRIMARY KEY, btree (id)
-Typed table of type: person_type
-
-CREATE TABLE persons4 OF person_type (
- name WITH OPTIONS NOT NULL,
- name WITH OPTIONS DEFAULT '' -- error, specified more than once
-);
-ERROR: column "name" specified more than once
-DROP TYPE person_type RESTRICT;
-ERROR: cannot drop type person_type because other objects depend on it
-DETAIL: table persons depends on type person_type
-function get_all_persons() depends on type person_type
-table persons3 depends on type person_type
-HINT: Use DROP ... CASCADE to drop the dependent objects too.
-DROP TYPE person_type CASCADE;
-NOTICE: drop cascades to 3 other objects
-DETAIL: drop cascades to table persons
-drop cascades to function get_all_persons()
-drop cascades to table persons3
-CREATE TABLE persons5 OF stuff; -- only CREATE TYPE AS types may be used
-ERROR: type stuff is not a composite type
-DROP TABLE stuff;
--- implicit casting
-CREATE TYPE person_type AS (id int, name text);
-CREATE TABLE persons OF person_type;
-INSERT INTO persons VALUES (1, 'test');
-CREATE FUNCTION namelen(person_type) RETURNS int LANGUAGE SQL AS $$ SELECT length($1.name) $$;
-SELECT id, namelen(persons) FROM persons;
- id | namelen
-----+---------
- 1 | 4
-(1 row)
-
-DROP TYPE person_type CASCADE;
-NOTICE: drop cascades to 2 other objects
-DETAIL: drop cascades to table persons
-drop cascades to function namelen(person_type)
+++ /dev/null
---
--- UPDATE syntax tests
---
-CREATE TABLE update_test (
- a INT DEFAULT 10,
- b INT,
- c TEXT
-);
-CREATE TABLE upsert_test (
- a INT PRIMARY KEY,
- b TEXT
-);
-INSERT INTO update_test VALUES (5, 10, 'foo');
-INSERT INTO update_test(b, a) VALUES (15, 10);
-SELECT * FROM update_test ORDER BY a, b, c;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 10 | 15 |
-(2 rows)
-
-UPDATE update_test SET a = DEFAULT, b = DEFAULT;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM update_test ORDER BY a, b, c;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 10 | 15 |
-(2 rows)
-
--- aliases for the UPDATE target table
-UPDATE update_test AS t SET b = 10 WHERE t.a = 10;
-SELECT * FROM update_test ORDER BY a, b, c;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 10 | 10 |
-(2 rows)
-
-UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10;
-SELECT * FROM update_test ORDER BY a, b, c;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 10 | 20 |
-(2 rows)
-
---
--- Test VALUES in FROM
---
-UPDATE update_test SET a=v.i FROM (VALUES(100, 20)) AS v(i, j)
- WHERE update_test.b = v.j;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM update_test ORDER BY a, b, c;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 10 | 20 |
-(2 rows)
-
---
--- Test multiple-set-clause syntax
---
-INSERT INTO update_test SELECT a,b+1,c FROM update_test;
-SELECT * FROM update_test;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 5 | 11 | foo
- 10 | 20 |
- 10 | 21 |
-(4 rows)
-
-UPDATE update_test SET (c,b,a) = ('bugle', b+11, DEFAULT) WHERE c = 'foo';
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM update_test ORDER BY a, b, c;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 5 | 11 | foo
- 10 | 20 |
- 10 | 21 |
-(4 rows)
-
-UPDATE update_test SET (c,b) = ('car', a+b), a = a + 1 WHERE a = 10;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM update_test ORDER BY a, b, c;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 5 | 11 | foo
- 10 | 20 |
- 10 | 21 |
-(4 rows)
-
--- fail, multi assignment to same column:
-UPDATE update_test SET (c,b) = ('car', a+b), b = a + 1 WHERE a = 10;
-ERROR: multiple assignments to same column "b"
--- uncorrelated sub-select:
-UPDATE update_test
- SET (b,a) = (select a,b from update_test where b = 41 and c = 'car')
- WHERE a = 100 AND b = 20;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM update_test;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 5 | 11 | foo
- 10 | 20 |
- 10 | 21 |
-(4 rows)
-
--- correlated sub-select:
-UPDATE update_test o
- SET (b,a) = (select a+1,b from update_test i
- where i.a=o.a and i.b=o.b and i.c is not distinct from o.c);
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM update_test;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 5 | 11 | foo
- 10 | 20 |
- 10 | 21 |
-(4 rows)
-
--- fail, multiple rows supplied:
-UPDATE update_test SET (b,a) = (select a+1,b from update_test);
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
--- set to null if no rows supplied:
-UPDATE update_test SET (b,a) = (select a+1,b from update_test where a = 1000)
- WHERE a = 11;
-ERROR: could not plan this distributed update
-DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-SELECT * FROM update_test;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 5 | 11 | foo
- 10 | 20 |
- 10 | 21 |
-(4 rows)
-
--- if an alias for the target table is specified, don't allow references
--- to the original table name
-UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10;
-ERROR: invalid reference to FROM-clause entry for table "update_test"
-LINE 1: UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a...
- ^
-HINT: Perhaps you meant to reference the table alias "t".
--- Make sure that we can update to a TOASTed value.
-UPDATE update_test SET c = repeat('x', 10000) WHERE c = 'car';
-SELECT a, b, char_length(c) FROM update_test ORDER BY a;
- a | b | char_length
-----+----+-------------
- 5 | 10 | 3
- 5 | 11 | 3
- 10 | 20 |
- 10 | 21 |
-(4 rows)
-
--- Test ON CONFLICT DO UPDATE
-INSERT INTO upsert_test VALUES(1, 'Boo');
--- uncorrelated sub-select:
-WITH aaa AS (SELECT 1 AS a, 'Foo' AS b) INSERT INTO upsert_test
- VALUES (1, 'Bar') ON CONFLICT(a)
- DO UPDATE SET (b, a) = (SELECT b, a FROM aaa) RETURNING *;
- a | b
----+-----
- 1 | Foo
-(1 row)
-
--- correlated sub-select:
-INSERT INTO upsert_test VALUES (1, 'Baz') ON CONFLICT(a)
- DO UPDATE SET (b, a) = (SELECT b || ', Correlated', a from upsert_test i WHERE i.a = upsert_test.a)
- RETURNING *;
- a | b
----+-----------------
- 1 | Foo, Correlated
-(1 row)
-
--- correlated sub-select (EXCLUDED.* alias):
-INSERT INTO upsert_test VALUES (1, 'Bat') ON CONFLICT(a)
- DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a)
- RETURNING *;
- a | b
----+---------------------------
- 1 | Foo, Correlated, Excluded
-(1 row)
-
-DROP TABLE update_test;
-DROP TABLE upsert_test;
+++ /dev/null
--- regression test for the uuid datatype
--- creating test tables
-CREATE TABLE guid1
-(
- guid_field UUID,
- text_field TEXT DEFAULT(now())
-);
-CREATE TABLE guid2
-(
- guid_field UUID,
- text_field TEXT DEFAULT(now())
-);
--- inserting invalid data tests
--- too long
-INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111F');
-ERROR: invalid input syntax for uuid: "11111111-1111-1111-1111-111111111111F"
-LINE 1: INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-111...
- ^
--- too short
-INSERT INTO guid1(guid_field) VALUES('{11111111-1111-1111-1111-11111111111}');
-ERROR: invalid input syntax for uuid: "{11111111-1111-1111-1111-11111111111}"
-LINE 1: INSERT INTO guid1(guid_field) VALUES('{11111111-1111-1111-11...
- ^
--- valid data but invalid format
-INSERT INTO guid1(guid_field) VALUES('111-11111-1111-1111-1111-111111111111');
-ERROR: invalid input syntax for uuid: "111-11111-1111-1111-1111-111111111111"
-LINE 1: INSERT INTO guid1(guid_field) VALUES('111-11111-1111-1111-11...
- ^
-INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222 ');
-ERROR: invalid input syntax for uuid: "{22222222-2222-2222-2222-222222222222 "
-LINE 1: INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-22...
- ^
--- invalid data
-INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-G111-111111111111');
-ERROR: invalid input syntax for uuid: "11111111-1111-1111-G111-111111111111"
-LINE 1: INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-G11...
- ^
-INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-1111-111111111111');
-ERROR: invalid input syntax for uuid: "11+11111-1111-1111-1111-111111111111"
-LINE 1: INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-111...
- ^
---inserting three input formats
-INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
-INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
-INSERT INTO guid1(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
--- retrieving the inserted data
-SELECT guid_field FROM guid1 ORDER BY guid_field;
- guid_field
---------------------------------------
- 11111111-1111-1111-1111-111111111111
- 22222222-2222-2222-2222-222222222222
- 3f3e3c3b-3a30-3938-3736-353433a2313e
-(3 rows)
-
--- ordering test
-SELECT guid_field FROM guid1 ORDER BY guid_field ASC;
- guid_field
---------------------------------------
- 11111111-1111-1111-1111-111111111111
- 22222222-2222-2222-2222-222222222222
- 3f3e3c3b-3a30-3938-3736-353433a2313e
-(3 rows)
-
-SELECT guid_field FROM guid1 ORDER BY guid_field DESC;
- guid_field
---------------------------------------
- 3f3e3c3b-3a30-3938-3736-353433a2313e
- 22222222-2222-2222-2222-222222222222
- 11111111-1111-1111-1111-111111111111
-(3 rows)
-
--- = operator test
-SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e';
- count
--------
- 1
-(1 row)
-
--- <> operator test
-SELECT COUNT(*) FROM guid1 WHERE guid_field <> '11111111111111111111111111111111';
- count
--------
- 2
-(1 row)
-
--- < operator test
-SELECT COUNT(*) FROM guid1 WHERE guid_field < '22222222-2222-2222-2222-222222222222';
- count
--------
- 1
-(1 row)
-
--- <= operator test
-SELECT COUNT(*) FROM guid1 WHERE guid_field <= '22222222-2222-2222-2222-222222222222';
- count
--------
- 2
-(1 row)
-
--- > operator test
-SELECT COUNT(*) FROM guid1 WHERE guid_field > '22222222-2222-2222-2222-222222222222';
- count
--------
- 1
-(1 row)
-
--- >= operator test
-SELECT COUNT(*) FROM guid1 WHERE guid_field >= '22222222-2222-2222-2222-222222222222';
- count
--------
- 2
-(1 row)
-
--- btree and hash index creation test
-CREATE INDEX guid1_btree ON guid1 USING BTREE (guid_field);
-CREATE INDEX guid1_hash ON guid1 USING HASH (guid_field);
--- unique index test
-CREATE UNIQUE INDEX guid1_unique_BTREE ON guid1 USING BTREE (guid_field);
-ERROR: Unique index of partitioned table must contain the hash/modulo distribution column.
--- should fail
-INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
--- check to see whether the new indexes are actually there
-SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'guid%';
- count
--------
- 2
-(1 row)
-
--- populating the test tables with additional records
-INSERT INTO guid1(guid_field) VALUES('44444444-4444-4444-4444-444444444444');
-INSERT INTO guid2(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
-INSERT INTO guid2(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
-INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
--- join test
-SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field;
- count
--------
- 4
-(1 row)
-
-SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_field WHERE g2.guid_field IS NULL;
- count
--------
- 1
-(1 row)
-
--- clean up
-DROP TABLE guid1, guid2 CASCADE;
+++ /dev/null
---
--- WITHOUT OID
---
---
--- This test tries to verify that WITHOUT OIDS actually saves space.
--- On machines where MAXALIGN is 8, WITHOUT OIDS may or may not save any
--- space, depending on the size of the tuple header + null bitmap.
--- As of 8.3 we need a null bitmap of 8 or less bits for the difference
--- to appear.
---
-CREATE TABLE wi (i INT,
- n1 int, n2 int, n3 int, n4 int,
- n5 int, n6 int, n7 int) WITH OIDS;
-CREATE TABLE wo (i INT,
- n1 int, n2 int, n3 int, n4 int,
- n5 int, n6 int, n7 int) WITHOUT OIDS;
-INSERT INTO wi VALUES (1); -- 1
-INSERT INTO wo SELECT i FROM wi; -- 1
-INSERT INTO wo SELECT i+1 FROM wi; -- 1+1=2
-INSERT INTO wi SELECT i+1 FROM wo; -- 1+2=3
-INSERT INTO wi SELECT i+3 FROM wi; -- 3+3=6
-INSERT INTO wo SELECT i+2 FROM wi; -- 2+6=8
-INSERT INTO wo SELECT i+8 FROM wo; -- 8+8=16
-INSERT INTO wi SELECT i+6 FROM wo; -- 6+16=22
-INSERT INTO wi SELECT i+22 FROM wi; -- 22+22=44
-INSERT INTO wo SELECT i+16 FROM wi; -- 16+44=60
-INSERT INTO wo SELECT i+60 FROM wo; -- 60+60=120
-INSERT INTO wi SELECT i+44 FROM wo; -- 44+120=164
-INSERT INTO wi SELECT i+164 FROM wi; -- 164+164=328
-INSERT INTO wo SELECT i+120 FROM wi; -- 120+328=448
-INSERT INTO wo SELECT i+448 FROM wo; -- 448+448=896
-INSERT INTO wi SELECT i+328 FROM wo; -- 328+896=1224
-INSERT INTO wi SELECT i+1224 FROM wi; -- 1224+1224=2448
-INSERT INTO wo SELECT i+896 FROM wi; -- 896+2448=3344
-INSERT INTO wo SELECT i+3344 FROM wo; -- 3344+3344=6688
-INSERT INTO wi SELECT i+2448 FROM wo; -- 2448+6688=9136
-INSERT INTO wo SELECT i+6688 FROM wi WHERE i<=2448; -- 6688+2448=9136
-SELECT count(oid) FROM wi;
- count
--------
- 9136
-(1 row)
-
--- should fail
-SELECT count(oid) FROM wo;
-ERROR: column "oid" does not exist
-LINE 1: SELECT count(oid) FROM wo;
- ^
-VACUUM ANALYZE wi;
-VACUUM ANALYZE wo;
-SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples)
- FROM pg_class
- WHERE relname IN ('wi', 'wo');
- ?column? | ?column?
-----------+----------
- f | 0
-(1 row)
-
-DROP TABLE wi;
-DROP TABLE wo;
---
--- WITH / WITHOUT OIDS in CREATE TABLE AS
---
-CREATE TABLE create_table_test (
- a int,
- b int
-);
-COPY create_table_test FROM stdin;
-CREATE TABLE create_table_test2 WITH OIDS AS
- SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
-CREATE TABLE create_table_test3 WITHOUT OIDS AS
- SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
-SELECT count(oid) FROM create_table_test2;
- count
--------
- 2
-(1 row)
-
--- should fail
-SELECT count(oid) FROM create_table_test3;
-ERROR: column "oid" does not exist
-LINE 1: SELECT count(oid) FROM create_table_test3;
- ^
-PREPARE table_source(int) AS
- SELECT a + b AS c1, a - b AS c2, $1 AS c3 FROM create_table_test;
-CREATE TABLE execute_with WITH OIDS AS EXECUTE table_source(1);
-ERROR: CREATE TABLE AS EXECUTE not yet supported
-CREATE TABLE execute_without WITHOUT OIDS AS EXECUTE table_source(2);
-ERROR: CREATE TABLE AS EXECUTE not yet supported
-SELECT count(oid) FROM execute_with;
-ERROR: relation "execute_with" does not exist
-LINE 1: SELECT count(oid) FROM execute_with;
- ^
--- should fail
-SELECT count(oid) FROM execute_without;
-ERROR: relation "execute_without" does not exist
-LINE 1: SELECT count(oid) FROM execute_without;
- ^
-DROP TABLE create_table_test;
-DROP TABLE create_table_test2;
-DROP TABLE create_table_test3;
-DROP TABLE execute_with;
-ERROR: table "execute_with" does not exist
-DROP TABLE execute_without;
-ERROR: table "execute_without" does not exist
+++ /dev/null
---
--- WITHOUT OID
---
---
--- This test tries to verify that WITHOUT OIDS actually saves space.
--- On machines where MAXALIGN is 8, WITHOUT OIDS may or may not save any
--- space, depending on the size of the tuple header + null bitmap.
--- As of 8.3 we need a null bitmap of 8 or less bits for the difference
--- to appear.
---
-CREATE TABLE wi (i INT,
- n1 int, n2 int, n3 int, n4 int,
- n5 int, n6 int, n7 int) WITH OIDS;
-CREATE TABLE wo (i INT,
- n1 int, n2 int, n3 int, n4 int,
- n5 int, n6 int, n7 int) WITHOUT OIDS;
-INSERT INTO wi VALUES (1); -- 1
-INSERT INTO wo SELECT i FROM wi; -- 1
-INSERT INTO wo SELECT i+1 FROM wi; -- 1+1=2
-INSERT INTO wi SELECT i+1 FROM wo; -- 1+2=3
-INSERT INTO wi SELECT i+3 FROM wi; -- 3+3=6
-INSERT INTO wo SELECT i+2 FROM wi; -- 2+6=8
-INSERT INTO wo SELECT i+8 FROM wo; -- 8+8=16
-INSERT INTO wi SELECT i+6 FROM wo; -- 6+16=22
-INSERT INTO wi SELECT i+22 FROM wi; -- 22+22=44
-INSERT INTO wo SELECT i+16 FROM wi; -- 16+44=60
-INSERT INTO wo SELECT i+60 FROM wo; -- 60+60=120
-INSERT INTO wi SELECT i+44 FROM wo; -- 44+120=164
-INSERT INTO wi SELECT i+164 FROM wi; -- 164+164=328
-INSERT INTO wo SELECT i+120 FROM wi; -- 120+328=448
-INSERT INTO wo SELECT i+448 FROM wo; -- 448+448=896
-INSERT INTO wi SELECT i+328 FROM wo; -- 328+896=1224
-INSERT INTO wi SELECT i+1224 FROM wi; -- 1224+1224=2448
-INSERT INTO wo SELECT i+896 FROM wi; -- 896+2448=3344
-INSERT INTO wo SELECT i+3344 FROM wo; -- 3344+3344=6688
-INSERT INTO wi SELECT i+2448 FROM wo; -- 2448+6688=9136
-INSERT INTO wo SELECT i+6688 FROM wi WHERE i<=2448; -- 6688+2448=9136
-SELECT count(oid) FROM wi;
- count
--------
- 9136
-(1 row)
-
--- should fail
-SELECT count(oid) FROM wo;
-ERROR: column "oid" does not exist
-LINE 1: SELECT count(oid) FROM wo;
- ^
-VACUUM ANALYZE wi;
-VACUUM ANALYZE wo;
-SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples)
- FROM pg_class
- WHERE relname IN ('wi', 'wo');
- ?column? | ?column?
-----------+----------
- t | 0
-(1 row)
-
-DROP TABLE wi;
-DROP TABLE wo;
---
--- WITH / WITHOUT OIDS in CREATE TABLE AS
---
-CREATE TABLE create_table_test (
- a int,
- b int
-);
-COPY create_table_test FROM stdin;
-CREATE TABLE create_table_test2 WITH OIDS AS
- SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
-CREATE TABLE create_table_test3 WITHOUT OIDS AS
- SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
-SELECT count(oid) FROM create_table_test2;
- count
--------
- 2
-(1 row)
-
--- should fail
-SELECT count(oid) FROM create_table_test3;
-ERROR: column "oid" does not exist
-LINE 1: SELECT count(oid) FROM create_table_test3;
- ^
-PREPARE table_source(int) AS
- SELECT a + b AS c1, a - b AS c2, $1 AS c3 FROM create_table_test;
-CREATE TABLE execute_with WITH OIDS AS EXECUTE table_source(1);
-ERROR: CREATE TABLE AS EXECUTE not yet supported
-CREATE TABLE execute_without WITHOUT OIDS AS EXECUTE table_source(2);
-ERROR: CREATE TABLE AS EXECUTE not yet supported
-SELECT count(oid) FROM execute_with;
-ERROR: relation "execute_with" does not exist
-LINE 1: SELECT count(oid) FROM execute_with;
- ^
--- should fail
-SELECT count(oid) FROM execute_without;
-ERROR: relation "execute_without" does not exist
-LINE 1: SELECT count(oid) FROM execute_without;
- ^
-DROP TABLE create_table_test;
-DROP TABLE create_table_test2;
-DROP TABLE create_table_test3;
-DROP TABLE execute_with;
-ERROR: table "execute_with" does not exist
-DROP TABLE execute_without;
-ERROR: table "execute_without" does not exist