postgresql/src/test/regress/expected/create_operator.out

294 lines
8.0 KiB
Plaintext
Raw Normal View History

2000-01-05 18:31:08 +01:00
--
-- CREATE_OPERATOR
--
CREATE OPERATOR ## (
1997-04-06 08:07:13 +02:00
leftarg = path,
rightarg = path,
function = path_inter,
commutator = ##
1997-04-06 08:07:13 +02:00
);
2000-01-05 18:31:08 +01:00
CREATE OPERATOR <% (
1997-04-06 08:07:13 +02:00
leftarg = point,
Major patch from Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov> OK, here are a passel of patches for the geometric data types. These add a "circle" data type, new operators and functions for the existing data types, and change the default formats for some of the existing types to make them consistant with each other. Current formatting conventions (e.g. compatible with v6.0 to allow dump/reload) are supported, but the new conventions should be an improvement and we can eventually drop the old conventions entirely. For example, there are two kinds of paths (connected line segments), open and closed, and the old format was '(1,2,1,2,3,4)' for a closed path with two points (1,2) and (3,4) '(0,2,1,2,3,4)' for an open path with two points (1,2) and (3,4) Pretty arcane, huh? The new format for paths is '((1,2),(3,4))' for a closed path with two points (1,2) and (3,4) '[(1,2),(3,4)]' for an open path with two points (1,2) and (3,4) For polygons, the old convention is '(0,4,2,0,4,3)' for a triangle with points at (0,0),(4,4), and (2,3) and the new convention is '((0,0),(4,4),(2,3))' for a triangle with points at (0,0),(4,4), and (2,3) Other data types which are also represented as lists of points (e.g. boxes, line segments, and polygons) have similar representations (they surround each point with parens). For v6.1, any format which can be interpreted as the old style format is decoded as such; we can remove that backwards compatibility but ugly convention for v7.0. This will allow dump/reloads from v6.0. These include some updates to the regression test files to change the test for creating a data type from "circle" to "widget" to keep the test from trashing the new builtin circle type.
1997-04-22 19:35:09 +02:00
rightarg = widget,
procedure = pt_in_widget,
commutator = >% ,
negator = >=%
1997-04-06 08:07:13 +02:00
);
2000-01-05 18:31:08 +01:00
CREATE OPERATOR @#@ (
rightarg = int8, -- prefix
procedure = factorial
1997-04-06 08:07:13 +02:00
);
CREATE OPERATOR #%# (
leftarg = int8, -- fail, postfix is no longer supported
procedure = factorial
1997-04-06 08:07:13 +02:00
);
ERROR: operator right argument type must be specified
DETAIL: Postfix operators are not supported.
-- Test operator created above
SELECT point '(1,2)' <% widget '(0,0,3)' AS t,
point '(1,2)' <% widget '(0,0,1)' AS f;
t | f
---+---
t | f
(1 row)
-- Test comments
COMMENT ON OPERATOR ###### (NONE, int4) IS 'bad prefix';
ERROR: operator does not exist: ###### integer
COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad postfix';
ERROR: postfix operators are not supported
COMMENT ON OPERATOR ###### (int4, int8) IS 'bad infix';
ERROR: operator does not exist: integer ###### bigint
-- Check that DROP on a nonexistent op behaves sanely, too
DROP OPERATOR ###### (NONE, int4);
ERROR: operator does not exist: ###### integer
DROP OPERATOR ###### (int4, NONE);
ERROR: postfix operators are not supported
DROP OPERATOR ###### (int4, int8);
ERROR: operator does not exist: integer ###### bigint
-- => is disallowed as an operator name now
CREATE OPERATOR => (
rightarg = int8,
procedure = factorial
);
ERROR: syntax error at or near "=>"
LINE 1: CREATE OPERATOR => (
^
-- lexing of <=, >=, <>, != has a number of edge cases
-- (=> is tested elsewhere)
-- this is legal because ! is not allowed in sql ops
CREATE OPERATOR !=- (
rightarg = int8,
procedure = factorial
);
SELECT !=- 10;
?column?
----------
3628800
(1 row)
-- postfix operators don't work anymore
SELECT 10 !=-;
ERROR: syntax error at or near ";"
LINE 1: SELECT 10 !=-;
^
-- make sure lexer returns != as <> even in edge cases
SELECT 2 !=/**/ 1, 2 !=/**/ 2;
?column? | ?column?
----------+----------
t | f
(1 row)
SELECT 2 !=-- comment to be removed by psql
1;
?column?
----------
t
(1 row)
DO $$ -- use DO to protect -- from psql
declare r boolean;
begin
execute $e$ select 2 !=-- comment
1 $e$ into r;
raise info 'r = %', r;
end;
$$;
INFO: r = t
-- check that <= etc. followed by more operator characters are returned
-- as the correct token with correct precedence
SELECT true<>-1 BETWEEN 1 AND 1; -- BETWEEN has prec. above <> but below Op
?column?
----------
t
(1 row)
SELECT false<>/**/1 BETWEEN 1 AND 1;
?column?
----------
t
(1 row)
SELECT false<=-1 BETWEEN 1 AND 1;
?column?
----------
t
(1 row)
SELECT false>=-1 BETWEEN 1 AND 1;
?column?
----------
t
(1 row)
SELECT 2<=/**/3, 3>=/**/2, 2<>/**/3;
?column? | ?column? | ?column?
----------+----------+----------
t | t | t
(1 row)
SELECT 3<=/**/2, 2>=/**/3, 2<>/**/2;
?column? | ?column? | ?column?
----------+----------+----------
f | f | f
(1 row)
-- Should fail. CREATE OPERATOR requires USAGE on SCHEMA
BEGIN TRANSACTION;
CREATE ROLE regress_rol_op1;
CREATE SCHEMA schema_op1;
GRANT USAGE ON SCHEMA schema_op1 TO PUBLIC;
REVOKE USAGE ON SCHEMA schema_op1 FROM regress_rol_op1;
SET ROLE regress_rol_op1;
CREATE OPERATOR schema_op1.#*# (
rightarg = int8,
procedure = factorial
);
ERROR: permission denied for schema schema_op1
ROLLBACK;
-- Should fail. SETOF type functions not allowed as argument (testing leftarg)
BEGIN TRANSACTION;
CREATE OPERATOR #*# (
leftarg = SETOF int8,
procedure = factorial
);
ERROR: SETOF type not allowed for operator argument
ROLLBACK;
-- Should fail. SETOF type functions not allowed as argument (testing rightarg)
BEGIN TRANSACTION;
CREATE OPERATOR #*# (
rightarg = SETOF int8,
procedure = factorial
);
ERROR: SETOF type not allowed for operator argument
ROLLBACK;
-- Should work. Sample text-book case
BEGIN TRANSACTION;
CREATE OR REPLACE FUNCTION fn_op2(boolean, boolean)
RETURNS boolean AS $$
SELECT NULL::BOOLEAN;
$$ LANGUAGE sql IMMUTABLE;
CREATE OPERATOR === (
LEFTARG = boolean,
RIGHTARG = boolean,
PROCEDURE = fn_op2,
COMMUTATOR = ===,
NEGATOR = !==,
RESTRICT = contsel,
JOIN = contjoinsel,
SORT1, SORT2, LTCMP, GTCMP, HASHES, MERGES
);
ROLLBACK;
-- Should fail. Invalid attribute
CREATE OPERATOR #@%# (
rightarg = int8,
procedure = factorial,
invalid_att = int8
);
WARNING: operator attribute "invalid_att" not recognized
-- Should fail. At least rightarg should be mandatorily specified
CREATE OPERATOR #@%# (
procedure = factorial
);
ERROR: operator argument types must be specified
-- Should fail. Procedure should be mandatorily specified
CREATE OPERATOR #@%# (
rightarg = int8
);
ERROR: operator function must be specified
-- Should fail. CREATE OPERATOR requires USAGE on TYPE
BEGIN TRANSACTION;
CREATE ROLE regress_rol_op3;
CREATE TYPE type_op3 AS ENUM ('new', 'open', 'closed');
CREATE FUNCTION fn_op3(type_op3, int8)
RETURNS int8 AS $$
SELECT NULL::int8;
$$ LANGUAGE sql IMMUTABLE;
REVOKE USAGE ON TYPE type_op3 FROM regress_rol_op3;
REVOKE USAGE ON TYPE type_op3 FROM PUBLIC; -- Need to do this so that regress_rol_op3 is not allowed USAGE via PUBLIC
SET ROLE regress_rol_op3;
CREATE OPERATOR #*# (
leftarg = type_op3,
rightarg = int8,
procedure = fn_op3
);
ERROR: permission denied for type type_op3
ROLLBACK;
-- Should fail. CREATE OPERATOR requires USAGE on TYPE (need to check separately for rightarg)
BEGIN TRANSACTION;
CREATE ROLE regress_rol_op4;
CREATE TYPE type_op4 AS ENUM ('new', 'open', 'closed');
CREATE FUNCTION fn_op4(int8, type_op4)
RETURNS int8 AS $$
SELECT NULL::int8;
$$ LANGUAGE sql IMMUTABLE;
REVOKE USAGE ON TYPE type_op4 FROM regress_rol_op4;
REVOKE USAGE ON TYPE type_op4 FROM PUBLIC; -- Need to do this so that regress_rol_op3 is not allowed USAGE via PUBLIC
SET ROLE regress_rol_op4;
CREATE OPERATOR #*# (
leftarg = int8,
rightarg = type_op4,
procedure = fn_op4
);
ERROR: permission denied for type type_op4
ROLLBACK;
-- Should fail. CREATE OPERATOR requires EXECUTE on function
BEGIN TRANSACTION;
CREATE ROLE regress_rol_op5;
CREATE TYPE type_op5 AS ENUM ('new', 'open', 'closed');
CREATE FUNCTION fn_op5(int8, int8)
RETURNS int8 AS $$
SELECT NULL::int8;
$$ LANGUAGE sql IMMUTABLE;
REVOKE EXECUTE ON FUNCTION fn_op5(int8, int8) FROM regress_rol_op5;
REVOKE EXECUTE ON FUNCTION fn_op5(int8, int8) FROM PUBLIC;-- Need to do this so that regress_rol_op3 is not allowed EXECUTE via PUBLIC
SET ROLE regress_rol_op5;
CREATE OPERATOR #*# (
leftarg = int8,
rightarg = int8,
procedure = fn_op5
);
ERROR: permission denied for function fn_op5
ROLLBACK;
-- Should fail. CREATE OPERATOR requires USAGE on return TYPE
BEGIN TRANSACTION;
CREATE ROLE regress_rol_op6;
CREATE TYPE type_op6 AS ENUM ('new', 'open', 'closed');
CREATE FUNCTION fn_op6(int8, int8)
RETURNS type_op6 AS $$
SELECT NULL::type_op6;
$$ LANGUAGE sql IMMUTABLE;
REVOKE USAGE ON TYPE type_op6 FROM regress_rol_op6;
REVOKE USAGE ON TYPE type_op6 FROM PUBLIC; -- Need to do this so that regress_rol_op3 is not allowed USAGE via PUBLIC
SET ROLE regress_rol_op6;
CREATE OPERATOR #*# (
leftarg = int8,
rightarg = int8,
procedure = fn_op6
);
ERROR: permission denied for type type_op6
ROLLBACK;
Avoid unnecessary use of pg_strcasecmp for already-downcased identifiers. We have a lot of code in which option names, which from the user's viewpoint are logically keywords, are passed through the grammar as plain identifiers, and then matched to string literals during command execution. This approach avoids making words into lexer keywords unnecessarily. Some places matched these strings using plain strcmp, some using pg_strcasecmp. But the latter should be unnecessary since identifiers would have been downcased on their way through the parser. Aside from any efficiency concerns (probably not a big factor), the lack of consistency in this area creates a hazard of subtle bugs due to different places coming to different conclusions about whether two option names are the same or different. Hence, standardize on using strcmp() to match any option names that are expected to have been fed through the parser. This does create a user-visible behavioral change, which is that while formerly all of these would work: alter table foo set (fillfactor = 50); alter table foo set (FillFactor = 50); alter table foo set ("fillfactor" = 50); alter table foo set ("FillFactor" = 50); now the last case will fail because that double-quoted identifier is different from the others. However, none of our documentation says that you can use a quoted identifier in such contexts at all, and we should discourage doing so since it would break if we ever decide to parse such constructs as true lexer keywords rather than poor man's substitutes. So this shouldn't create a significant compatibility issue for users. Daniel Gustafsson, reviewed by Michael Paquier, small changes by me Discussion: https://postgr.es/m/29405B24-564E-476B-98C0-677A29805B84@yesql.se
2018-01-27 00:25:02 +01:00
-- invalid: non-lowercase quoted identifiers
CREATE OPERATOR ===
(
"Leftarg" = box,
"Rightarg" = box,
"Procedure" = area_equal_function,
Avoid unnecessary use of pg_strcasecmp for already-downcased identifiers. We have a lot of code in which option names, which from the user's viewpoint are logically keywords, are passed through the grammar as plain identifiers, and then matched to string literals during command execution. This approach avoids making words into lexer keywords unnecessarily. Some places matched these strings using plain strcmp, some using pg_strcasecmp. But the latter should be unnecessary since identifiers would have been downcased on their way through the parser. Aside from any efficiency concerns (probably not a big factor), the lack of consistency in this area creates a hazard of subtle bugs due to different places coming to different conclusions about whether two option names are the same or different. Hence, standardize on using strcmp() to match any option names that are expected to have been fed through the parser. This does create a user-visible behavioral change, which is that while formerly all of these would work: alter table foo set (fillfactor = 50); alter table foo set (FillFactor = 50); alter table foo set ("fillfactor" = 50); alter table foo set ("FillFactor" = 50); now the last case will fail because that double-quoted identifier is different from the others. However, none of our documentation says that you can use a quoted identifier in such contexts at all, and we should discourage doing so since it would break if we ever decide to parse such constructs as true lexer keywords rather than poor man's substitutes. So this shouldn't create a significant compatibility issue for users. Daniel Gustafsson, reviewed by Michael Paquier, small changes by me Discussion: https://postgr.es/m/29405B24-564E-476B-98C0-677A29805B84@yesql.se
2018-01-27 00:25:02 +01:00
"Commutator" = ===,
"Negator" = !==,
"Restrict" = area_restriction_function,
"Join" = area_join_function,
Avoid unnecessary use of pg_strcasecmp for already-downcased identifiers. We have a lot of code in which option names, which from the user's viewpoint are logically keywords, are passed through the grammar as plain identifiers, and then matched to string literals during command execution. This approach avoids making words into lexer keywords unnecessarily. Some places matched these strings using plain strcmp, some using pg_strcasecmp. But the latter should be unnecessary since identifiers would have been downcased on their way through the parser. Aside from any efficiency concerns (probably not a big factor), the lack of consistency in this area creates a hazard of subtle bugs due to different places coming to different conclusions about whether two option names are the same or different. Hence, standardize on using strcmp() to match any option names that are expected to have been fed through the parser. This does create a user-visible behavioral change, which is that while formerly all of these would work: alter table foo set (fillfactor = 50); alter table foo set (FillFactor = 50); alter table foo set ("fillfactor" = 50); alter table foo set ("FillFactor" = 50); now the last case will fail because that double-quoted identifier is different from the others. However, none of our documentation says that you can use a quoted identifier in such contexts at all, and we should discourage doing so since it would break if we ever decide to parse such constructs as true lexer keywords rather than poor man's substitutes. So this shouldn't create a significant compatibility issue for users. Daniel Gustafsson, reviewed by Michael Paquier, small changes by me Discussion: https://postgr.es/m/29405B24-564E-476B-98C0-677A29805B84@yesql.se
2018-01-27 00:25:02 +01:00
"Hashes",
"Merges"
);
WARNING: operator attribute "Leftarg" not recognized
WARNING: operator attribute "Rightarg" not recognized
WARNING: operator attribute "Procedure" not recognized
WARNING: operator attribute "Commutator" not recognized
WARNING: operator attribute "Negator" not recognized
WARNING: operator attribute "Restrict" not recognized
WARNING: operator attribute "Join" not recognized
WARNING: operator attribute "Hashes" not recognized
WARNING: operator attribute "Merges" not recognized
ERROR: operator function must be specified