diff options
author | Tomas Vondra | 2017-01-28 15:17:37 +0000 |
---|---|---|
committer | Tomas Vondra | 2017-01-28 16:13:30 +0000 |
commit | 3f7ef9af69a55c9e1c63b89d576616e23aeae4dc (patch) | |
tree | 19cefa4417b9011881fcd2b87b2759d8a1fc2a3a | |
parent | 0465a0f796e1b18f5656b5f9aedadc23a42b15db (diff) |
remove unnecessary expected output for regression tests
There was quite a few unnecessary files in src/test/regress/expected,
not present at upstream, probably due to previous merges. As those
are most likely stale, let's just get rid of them.
37 files changed, 88 insertions, 22288 deletions
diff --git a/src/test/regress/expected/aggregates-float-sunos.out b/src/test/regress/expected/aggregates-float-sunos.out deleted file mode 100644 index 48574baa50..0000000000 --- a/src/test/regress/expected/aggregates-float-sunos.out +++ /dev/null @@ -1,1630 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/aggregates_1.out b/src/test/regress/expected/aggregates_1.out deleted file mode 100644 index 0c9dddc5f9..0000000000 --- a/src/test/regress/expected/aggregates_1.out +++ /dev/null @@ -1,1045 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/box.out b/src/test/regress/expected/box.out index 0e72b217dc..ee7d5b6ec3 100644 --- a/src/test/regress/expected/box.out +++ b/src/test/regress/expected/box.out @@ -15,7 +15,9 @@ -- 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 @@ -219,7 +221,7 @@ SELECT '' AS four, height(f1), width(f1) FROM BOX_TBL ORDER BY (f1[0])[0], (f1[0 -- -- 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; @@ -245,11 +247,13 @@ SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)'; (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 @@ -265,11 +269,13 @@ SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)'; (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 @@ -294,11 +300,13 @@ SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)'; (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 @@ -317,11 +325,13 @@ SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)'; (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 @@ -339,11 +349,13 @@ SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)'; (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 @@ -354,11 +366,13 @@ SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)'; (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 @@ -369,11 +383,13 @@ SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)'; (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 @@ -383,11 +399,13 @@ SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)'; (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 @@ -406,11 +424,13 @@ SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)'; (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 @@ -422,11 +442,13 @@ SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)'; (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 @@ -435,11 +457,13 @@ SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)'; (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 @@ -448,11 +472,13 @@ SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)'; (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; diff --git a/src/test/regress/expected/box_1.out b/src/test/regress/expected/box_1.out deleted file mode 100644 index ee7d5b6ec3..0000000000 --- a/src/test/regress/expected/box_1.out +++ /dev/null @@ -1,484 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/case_1.out b/src/test/regress/expected/case_1.out deleted file mode 100644 index 3a798f7b5b..0000000000 --- a/src/test/regress/expected/case_1.out +++ /dev/null @@ -1,317 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/collate_2.out b/src/test/regress/expected/collate_2.out deleted file mode 100644 index 0924c2b609..0000000000 --- a/src/test/regress/expected/collate_2.out +++ /dev/null @@ -1,596 +0,0 @@ -/* - * 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 diff --git a/src/test/regress/expected/combocid_1.out b/src/test/regress/expected/combocid_1.out deleted file mode 100644 index 71191dd544..0000000000 --- a/src/test/regress/expected/combocid_1.out +++ /dev/null @@ -1,103 +0,0 @@ --- --- 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) - diff --git a/src/test/regress/expected/copy2_1.out b/src/test/regress/expected/copy2_1.out deleted file mode 100644 index 5977563902..0000000000 --- a/src/test/regress/expected/copy2_1.out +++ /dev/null @@ -1,515 +0,0 @@ -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(); diff --git a/src/test/regress/expected/dependency_1.out b/src/test/regress/expected/dependency_1.out deleted file mode 100644 index 4c1fb81032..0000000000 --- a/src/test/regress/expected/dependency_1.out +++ /dev/null @@ -1,125 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/domain_1.out b/src/test/regress/expected/domain_1.out deleted file mode 100644 index f252b184f9..0000000000 --- a/src/test/regress/expected/domain_1.out +++ /dev/null @@ -1,680 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/domain_2.out b/src/test/regress/expected/domain_2.out deleted file mode 100644 index f0ed688968..0000000000 --- a/src/test/regress/expected/domain_2.out +++ /dev/null @@ -1,666 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/float4_1.out b/src/test/regress/expected/float4_1.out deleted file mode 100644 index c9030cf872..0000000000 --- a/src/test/regress/expected/float4_1.out +++ /dev/null @@ -1,260 +0,0 @@ --- --- 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) - diff --git a/src/test/regress/expected/float8_1.out b/src/test/regress/expected/float8_1.out deleted file mode 100644 index 035370658e..0000000000 --- a/src/test/regress/expected/float8_1.out +++ /dev/null @@ -1,448 +0,0 @@ --- --- 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) - diff --git a/src/test/regress/expected/functional_deps_1.out b/src/test/regress/expected/functional_deps_1.out deleted file mode 100644 index 8848e26560..0000000000 --- a/src/test/regress/expected/functional_deps_1.out +++ /dev/null @@ -1,240 +0,0 @@ --- 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 diff --git a/src/test/regress/expected/guc_1.out b/src/test/regress/expected/guc_1.out deleted file mode 100644 index de51c28ac4..0000000000 --- a/src/test/regress/expected/guc_1.out +++ /dev/null @@ -1,649 +0,0 @@ --- 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; diff --git a/src/test/regress/expected/hash_index_1.out b/src/test/regress/expected/hash_index_1.out deleted file mode 100644 index bdf8c3ec9c..0000000000 --- a/src/test/regress/expected/hash_index_1.out +++ /dev/null @@ -1,206 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/inherit_1.out b/src/test/regress/expected/inherit_1.out deleted file mode 100644 index d13c10d6ba..0000000000 --- a/src/test/regress/expected/inherit_1.out +++ /dev/null @@ -1,1781 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/int4_1.out b/src/test/regress/expected/int4_1.out deleted file mode 100644 index 1438e75f21..0000000000 --- a/src/test/regress/expected/int4_1.out +++ /dev/null @@ -1,344 +0,0 @@ --- --- 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) - diff --git a/src/test/regress/expected/namespace_1.out b/src/test/regress/expected/namespace_1.out deleted file mode 100644 index 533028cb01..0000000000 --- a/src/test/regress/expected/namespace_1.out +++ /dev/null @@ -1,52 +0,0 @@ --- --- 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) - diff --git a/src/test/regress/expected/polymorphism_1.out b/src/test/regress/expected/polymorphism_1.out deleted file mode 100644 index e2f208c4ed..0000000000 --- a/src/test/regress/expected/polymorphism_1.out +++ /dev/null @@ -1,1385 +0,0 @@ --- 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); diff --git a/src/test/regress/expected/prepared_xacts_2.out b/src/test/regress/expected/prepared_xacts_2.out deleted file mode 100644 index 31c9501cf3..0000000000 --- a/src/test/regress/expected/prepared_xacts_2.out +++ /dev/null @@ -1,302 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/privileges_1.out b/src/test/regress/expected/privileges_1.out deleted file mode 100644 index f01e3658cf..0000000000 --- a/src/test/regress/expected/privileges_1.out +++ /dev/null @@ -1,1296 +0,0 @@ --- --- 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 diff --git a/src/test/regress/expected/privileges_2.out b/src/test/regress/expected/privileges_2.out deleted file mode 100644 index 80ca5297e2..0000000000 --- a/src/test/regress/expected/privileges_2.out +++ /dev/null @@ -1,1602 +0,0 @@ --- --- 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; diff --git a/src/test/regress/expected/rangefuncs_1.out b/src/test/regress/expected/rangefuncs_1.out deleted file mode 100644 index ed5a812b2f..0000000000 --- a/src/test/regress/expected/rangefuncs_1.out +++ /dev/null @@ -1,918 +0,0 @@ -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 r |