1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-27 23:21:58 +03:00

The contents of command.c, creatinh.c, define.c, remove.c and rename.c

have been divided according to the type of object manipulated - so ALTER
TABLE code is in tablecmds.c, aggregate commands in aggregatecmds.c and
so on.

A few common support routines remain in define.c (prototypes in
src/include/commands/defrem.h).

No code has been changed except for includes to reflect the new files.
The prototypes for aggregatecmds.c, functioncmds.c, operatorcmds.c,
and typecmds.c remain in src/include/commands/defrem.h.

From John Gray <jgray@azuli.co.uk>
This commit is contained in:
Tom Lane
2002-04-15 05:22:04 +00:00
parent ab1ead6b97
commit 71dc300a37
29 changed files with 3620 additions and 3578 deletions

View File

@ -0,0 +1,247 @@
/*-------------------------------------------------------------------------
*
* operatorcmds.c
*
* Routines for operator manipulation commands
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/operatorcmds.c,v 1.1 2002/04/15 05:22:03 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
* appropriate arguments/flags, passing the results to the
* corresponding "FooDefine" routines (in src/catalog) that do
* the actual catalog-munging. These routines also verify permission
* of the user to execute the command.
*
* NOTES
* These things must be defined and committed in the following order:
* "create function":
* input/output, recv/send procedures
* "create type":
* type
* "create operator":
* operators
*
* Most of the parse-tree manipulation routines are defined in
* commands/manip.c.
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/namespace.h"
#include "catalog/pg_operator.h"
#include "commands/comment.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "parser/parse_type.h"
#include "utils/acl.h"
#include "utils/syscache.h"
/*
* DefineOperator
* this function extracts all the information from the
* parameter list generated by the parser and then has
* OperatorCreate() do all the actual work.
*
* 'parameters' is a list of DefElem
*/
void
DefineOperator(List *names, List *parameters)
{
char *oprName;
Oid oprNamespace;
uint16 precedence = 0; /* operator precedence */
bool canHash = false; /* operator hashes */
bool isLeftAssociative = true; /* operator is left
* associative */
char *functionName = NULL; /* function for operator */
TypeName *typeName1 = NULL; /* first type name */
TypeName *typeName2 = NULL; /* second type name */
Oid typeId1 = InvalidOid; /* types converted to OID */
Oid typeId2 = InvalidOid;
char *commutatorName = NULL; /* optional commutator operator
* name */
char *negatorName = NULL; /* optional negator operator name */
char *restrictionName = NULL; /* optional restrict. sel.
* procedure */
char *joinName = NULL; /* optional join sel. procedure name */
char *sortName1 = NULL; /* optional first sort operator */
char *sortName2 = NULL; /* optional second sort operator */
List *pl;
/* Convert list of names to a name and namespace */
oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
/*
* loop over the definition list and extract the information we need.
*/
foreach(pl, parameters)
{
DefElem *defel = (DefElem *) lfirst(pl);
if (strcasecmp(defel->defname, "leftarg") == 0)
{
typeName1 = defGetTypeName(defel);
if (typeName1->setof)
elog(ERROR, "setof type not implemented for leftarg");
}
else if (strcasecmp(defel->defname, "rightarg") == 0)
{
typeName2 = defGetTypeName(defel);
if (typeName2->setof)
elog(ERROR, "setof type not implemented for rightarg");
}
else if (strcasecmp(defel->defname, "procedure") == 0)
functionName = defGetString(defel);
else if (strcasecmp(defel->defname, "precedence") == 0)
{
/* NOT IMPLEMENTED (never worked in v4.2) */
elog(NOTICE, "CREATE OPERATOR: precedence not implemented");
}
else if (strcasecmp(defel->defname, "associativity") == 0)
{
/* NOT IMPLEMENTED (never worked in v4.2) */
elog(NOTICE, "CREATE OPERATOR: associativity not implemented");
}
else if (strcasecmp(defel->defname, "commutator") == 0)
commutatorName = defGetString(defel);
else if (strcasecmp(defel->defname, "negator") == 0)
negatorName = defGetString(defel);
else if (strcasecmp(defel->defname, "restrict") == 0)
restrictionName = defGetString(defel);
else if (strcasecmp(defel->defname, "join") == 0)
joinName = defGetString(defel);
else if (strcasecmp(defel->defname, "hashes") == 0)
canHash = TRUE;
else if (strcasecmp(defel->defname, "sort1") == 0)
sortName1 = defGetString(defel);
else if (strcasecmp(defel->defname, "sort2") == 0)
sortName2 = defGetString(defel);
else
{
elog(WARNING, "DefineOperator: attribute \"%s\" not recognized",
defel->defname);
}
}
/*
* make sure we have our required definitions
*/
if (functionName == NULL)
elog(ERROR, "Define: \"procedure\" unspecified");
/* Transform type names to type OIDs */
if (typeName1)
typeId1 = typenameTypeId(typeName1);
if (typeName2)
typeId2 = typenameTypeId(typeName2);
/*
* now have OperatorCreate do all the work..
*/
OperatorCreate(oprName, /* operator name */
typeId1, /* left type id */
typeId2, /* right type id */
functionName, /* function for operator */
precedence, /* operator precedence */
isLeftAssociative, /* operator is left associative */
commutatorName, /* optional commutator operator
* name */
negatorName, /* optional negator operator name */
restrictionName, /* optional restrict. sel.
* procedure */
joinName, /* optional join sel. procedure name */
canHash, /* operator hashes */
sortName1, /* optional first sort operator */
sortName2); /* optional second sort operator */
}
/*
* RemoveOperator
* Deletes an operator.
*
* Exceptions:
* BadArg if name is invalid.
* BadArg if type1 is invalid.
* "ERROR" if operator nonexistent.
* ...
*/
void
RemoveOperator(char *operatorName, /* operator name */
TypeName *typeName1, /* left argument type name */
TypeName *typeName2) /* right argument type name */
{
Relation relation;
HeapTuple tup;
Oid typeId1 = InvalidOid;
Oid typeId2 = InvalidOid;
char oprtype;
if (typeName1)
typeId1 = typenameTypeId(typeName1);
if (typeName2)
typeId2 = typenameTypeId(typeName2);
if (OidIsValid(typeId1) && OidIsValid(typeId2))
oprtype = 'b';
else if (OidIsValid(typeId1))
oprtype = 'r';
else
oprtype = 'l';
relation = heap_openr(OperatorRelationName, RowExclusiveLock);
tup = SearchSysCacheCopy(OPERNAME,
PointerGetDatum(operatorName),
ObjectIdGetDatum(typeId1),
ObjectIdGetDatum(typeId2),
CharGetDatum(oprtype));
if (HeapTupleIsValid(tup))
{
if (!pg_oper_ownercheck(tup->t_data->t_oid, GetUserId()))
elog(ERROR, "RemoveOperator: operator '%s': permission denied",
operatorName);
/* Delete any comments associated with this operator */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
simple_heap_delete(relation, &tup->t_self);
}
else
{
if (OidIsValid(typeId1) && OidIsValid(typeId2))
{
elog(ERROR, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
operatorName,
TypeNameToString(typeName1),
TypeNameToString(typeName2));
}
else if (OidIsValid(typeId1))
{
elog(ERROR, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
operatorName,
TypeNameToString(typeName1));
}
else
{
elog(ERROR, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
operatorName,
TypeNameToString(typeName2));
}
}
heap_freetuple(tup);
heap_close(relation, RowExclusiveLock);
}