diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml index 82ea44921d986cd33ac92b5d8ff4a2410e6c37b3..2a4955113f3fc8f467d23f0a714d5d74f00c8d9b 100644 --- a/doc/src/sgml/ref/create_operator.sgml +++ b/doc/src/sgml/ref/create_operator.sgml @@ -1,5 +1,5 @@ @@ -437,6 +437,15 @@ MYBOXES.description === box '((0,0), (1,1))' Refer to DROP OPERATOR to delete user-defined operators from a database. + + + To give a schema-qualified operator name in com_op or the other optional + arguments, use the OPERATOR() syntax, for example + + COMMUTATOR = OPERATOR(myschema.===) , + + diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml index 90f33bfd0ff7dceec512dc36dc6876191693699b..fbbe78db9a8f7e2f2c6562eb874f6d86d6f3939c 100644 --- a/doc/src/sgml/syntax.sgml +++ b/doc/src/sgml/syntax.sgml @@ -1,5 +1,5 @@ @@ -755,7 +755,7 @@ SELECT (5 !) - 6; - LIKE ILIKE + LIKE ILIKE SIMILAR string pattern matching @@ -801,6 +801,17 @@ SELECT (5 !) - 6; the same precedence as the built-in + operator, no matter what yours does. + + + When a schema-qualified operator name is used in the + OPERATOR syntax, as for example in + +SELECT 3 OPERATOR(pg_catalog.+) 4; + + the OPERATOR construct is taken to have the default precedence + shown above for any other operator. This is true no matter + which specific operator name appears inside OPERATOR(). + diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index a1b47d1274dcd00f0922f84b581591b226ffb3bf..02b730944b417cf722ed4526f631c4cfd2114802 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.78 2002/06/20 20:29:27 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.79 2002/08/10 19:01:53 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -35,6 +35,7 @@ #include #include +#include "catalog/namespace.h" #include "commands/defrem.h" #include "parser/parse_type.h" #include "utils/int8.h" @@ -86,6 +87,8 @@ defGetString(DefElem *def) return strVal(def->arg); case T_TypeName: return TypeNameToString((TypeName *) def->arg); + case T_List: + return NameListToString((List *) def->arg); default: elog(ERROR, "Define: cannot interpret argument of \"%s\"", def->defname); @@ -156,6 +159,8 @@ defGetQualifiedName(DefElem *def) { case T_TypeName: return ((TypeName *) def->arg)->names; + case T_List: + return (List *) def->arg; case T_String: /* Allow quoted name for backwards compatibility */ return makeList1(def->arg); @@ -168,6 +173,9 @@ defGetQualifiedName(DefElem *def) /* * Extract a TypeName from a DefElem. + * + * Note: we do not accept a List arg here, because the parser will only + * return a bare List when the name looks like an operator name. */ TypeName * defGetTypeName(DefElem *def) @@ -223,11 +231,14 @@ defGetTypeLength(DefElem *def) "variable") == 0) return -1; /* variable length */ break; + case T_List: + /* must be an operator name */ + break; default: elog(ERROR, "Define: cannot interpret argument of \"%s\"", def->defname); } - elog(ERROR, "Define: invalid argument for \"%s\"", - def->defname); + elog(ERROR, "Define: invalid argument for \"%s\": \"%s\"", + def->defname, defGetString(def)); return 0; /* keep compiler quiet */ } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index f57f461124dc435b614087ff44b548cc87b960b2..98acc050d56ab71d02bad375db2687fa0382087c 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.357 2002/08/06 05:40:45 ishii Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.358 2002/08/10 19:01:53 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -1307,27 +1307,19 @@ copy_opt_list: copy_opt_item: BINARY { - $$ = makeNode(DefElem); - $$->defname = "binary"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("binary", (Node *)makeInteger(TRUE)); } | OIDS { - $$ = makeNode(DefElem); - $$->defname = "oids"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("oids", (Node *)makeInteger(TRUE)); } | DELIMITER opt_as Sconst { - $$ = makeNode(DefElem); - $$->defname = "delimiter"; - $$->arg = (Node *)makeString($3); + $$ = makeDefElem("delimiter", (Node *)makeString($3)); } | NULL_P opt_as Sconst { - $$ = makeNode(DefElem); - $$->defname = "null"; - $$->arg = (Node *)makeString($3); + $$ = makeDefElem("null", (Node *)makeString($3)); } ; @@ -1336,9 +1328,7 @@ copy_opt_item: opt_binary: BINARY { - $$ = makeNode(DefElem); - $$->defname = "binary"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("binary", (Node *)makeInteger(TRUE)); } | /*EMPTY*/ { $$ = NULL; } ; @@ -1346,9 +1336,7 @@ opt_binary: opt_oids: WITH OIDS { - $$ = makeNode(DefElem); - $$->defname = "oids"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("oids", (Node *)makeInteger(TRUE)); } | /*EMPTY*/ { $$ = NULL; } ; @@ -1357,9 +1345,7 @@ copy_delimiter: /* USING DELIMITERS kept for backward compatibility. 2002-06-15 */ opt_using DELIMITERS Sconst { - $$ = makeNode(DefElem); - $$->defname = "delimiter"; - $$->arg = (Node *)makeString($3); + $$ = makeDefElem("delimiter", (Node *)makeString($3)); } | /*EMPTY*/ { $$ = NULL; } ; @@ -2276,7 +2262,7 @@ def_elem: ColLabel '=' def_arg /* Note: any simple identifier will be returned as a type name! */ def_arg: func_return { $$ = (Node *)$1; } - | all_Op { $$ = (Node *)makeString($1); } + | qual_all_Op { $$ = (Node *)$1; } | NumericOnly { $$ = (Node *)$1; } | Sconst { $$ = (Node *)makeString($1); } ; @@ -3568,27 +3554,19 @@ createdb_opt_list: createdb_opt_item: LOCATION opt_equal Sconst { - $$ = makeNode(DefElem); - $$->defname = "location"; - $$->arg = (Node *)makeString($3); + $$ = makeDefElem("location", (Node *)makeString($3)); } | LOCATION opt_equal DEFAULT { - $$ = makeNode(DefElem); - $$->defname = "location"; - $$->arg = NULL; + $$ = makeDefElem("location", NULL); } | TEMPLATE opt_equal name { - $$ = makeNode(DefElem); - $$->defname = "template"; - $$->arg = (Node *)makeString($3); + $$ = makeDefElem("template", (Node *)makeString($3)); } | TEMPLATE opt_equal DEFAULT { - $$ = makeNode(DefElem); - $$->defname = "template"; - $$->arg = NULL; + $$ = makeDefElem("template", NULL); } | ENCODING opt_equal Sconst { @@ -3598,9 +3576,7 @@ createdb_opt_item: elog(ERROR, "%s is not a valid encoding name", $3); encoding = pg_char_to_encoding($3); - $$ = makeNode(DefElem); - $$->defname = "encoding"; - $$->arg = (Node *)makeInteger(encoding); + $$ = makeDefElem("encoding", (Node *)makeInteger(encoding)); } | ENCODING opt_equal Iconst { @@ -3610,27 +3586,19 @@ createdb_opt_item: if (!strcmp(encoding_name,"") || pg_valid_server_encoding(encoding_name) < 0) elog(ERROR, "%d is not a valid encoding code", $3); - $$ = makeNode(DefElem); - $$->defname = "encoding"; - $$->arg = (Node *)makeInteger($3); + $$ = makeDefElem("encoding", (Node *)makeInteger($3)); } | ENCODING opt_equal DEFAULT { - $$ = makeNode(DefElem); - $$->defname = "encoding"; - $$->arg = (Node *)makeInteger(-1); + $$ = makeDefElem("encoding", (Node *)makeInteger(-1)); } | OWNER opt_equal name { - $$ = makeNode(DefElem); - $$->defname = "owner"; - $$->arg = (Node *)makeString($3); + $$ = makeDefElem("owner", (Node *)makeString($3)); } | OWNER opt_equal DEFAULT { - $$ = makeNode(DefElem); - $$->defname = "owner"; - $$->arg = NULL; + $$ = makeDefElem("owner", NULL); } ;