*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.63 2001/10/25 05:49:23 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.64 2002/03/29 19:06:01 tgl Exp $
*
* NOTES
* these routines moved here from commands/define.c and somewhat cleaned up.
#include "utils/syscache.h"
-static Oid OperatorGetWithOpenRelation(Relation pg_operator_desc,
- const char *operatorName,
- Oid leftObjectId,
- Oid rightObjectId,
- bool *defined);
+static Oid OperatorGet(const char *operatorName,
+ Oid leftObjectId,
+ Oid rightObjectId,
+ bool *defined);
-static Oid OperatorGet(char *operatorName,
- char *leftTypeName,
- char *rightTypeName,
- bool *defined);
+static Oid OperatorShellMake(const char *operatorName,
+ Oid leftTypeId,
+ Oid rightTypeId);
-static Oid OperatorShellMake(char *operatorName,
- char *leftTypeName,
- char *rightTypeName);
-
-static void OperatorDef(char *operatorName,
- char *leftTypeName,
- char *rightTypeName,
- char *procedureName,
+static void OperatorDef(const char *operatorName,
+ Oid leftTypeId,
+ Oid rightTypeId,
+ const char *procedureName,
uint16 precedence,
bool isLeftAssociative,
- char *commutatorName,
- char *negatorName,
- char *restrictionName,
- char *oinName,
+ const char *commutatorName,
+ const char *negatorName,
+ const char *restrictionName,
+ const char *joinName,
bool canHash,
- char *leftSortName,
- char *rightSortName);
+ const char *leftSortName,
+ const char *rightSortName);
static void OperatorUpd(Oid baseId, Oid commId, Oid negId);
/* ----------------------------------------------------------------
- * OperatorGetWithOpenRelation
+ * OperatorGet
*
- * performs a scan on pg_operator for an operator tuple
- * with given name and left/right type oids.
+ * finds the operator associated with the specified name
+ * and left and right type IDs.
*
- * pg_operator_desc -- reldesc for pg_operator
- * operatorName -- name of operator to fetch
- * leftObjectId -- left data type oid of operator to fetch
- * rightObjectId -- right data type oid of operator to fetch
- * defined -- set TRUE if defined (not a shell)
+ * operatorName -- name of operator to fetch
+ * leftObjectId -- left data type oid of operator to fetch
+ * rightObjectId -- right data type oid of operator to fetch
+ * defined -- set TRUE if defined (not a shell)
* ----------------------------------------------------------------
*/
static Oid
-OperatorGetWithOpenRelation(Relation pg_operator_desc,
- const char *operatorName,
- Oid leftObjectId,
- Oid rightObjectId,
- bool *defined)
+OperatorGet(const char *operatorName,
+ Oid leftObjectId,
+ Oid rightObjectId,
+ bool *defined)
{
+ Relation pg_operator_desc;
HeapScanDesc pg_operator_scan;
- Oid operatorObjectId;
HeapTuple tup;
ScanKeyData opKey[3];
+ Oid operatorObjectId;
+
+ if (!(OidIsValid(leftObjectId) || OidIsValid(rightObjectId)))
+ elog(ERROR, "operator %s must have at least one operand type",
+ operatorName);
+
+ /*
+ * open the pg_operator relation
+ */
+ pg_operator_desc = heap_openr(OperatorRelationName, AccessShareLock);
/*
* form scan key
* close the scan and return the oid.
*/
heap_endscan(pg_operator_scan);
-
- return operatorObjectId;
-}
-
-/* ----------------------------------------------------------------
- * OperatorGet
- *
- * finds the operator associated with the specified name
- * and left and right type names.
- * ----------------------------------------------------------------
- */
-static Oid
-OperatorGet(char *operatorName,
- char *leftTypeName,
- char *rightTypeName,
- bool *defined)
-{
- Relation pg_operator_desc;
- Oid operatorObjectId;
- Oid leftObjectId = InvalidOid;
- Oid rightObjectId = InvalidOid;
- bool leftDefined = false;
- bool rightDefined = false;
-
- /*
- * look up the operator data types.
- *
- * Note: types must be defined before operators
- */
- if (leftTypeName)
- {
- leftObjectId = TypeGet(leftTypeName, &leftDefined);
-
- if (!OidIsValid(leftObjectId) || !leftDefined)
- elog(ERROR, "left type \"%s\" of operator %s does not exist",
- leftTypeName, operatorName);
- }
-
- if (rightTypeName)
- {
- rightObjectId = TypeGet(rightTypeName, &rightDefined);
-
- if (!OidIsValid(rightObjectId) || !rightDefined)
- elog(ERROR, "right type \"%s\" of operator %s does not exist",
- rightTypeName, operatorName);
- }
-
- if (!((OidIsValid(leftObjectId) && leftDefined) ||
- (OidIsValid(rightObjectId) && rightDefined)))
- elog(ERROR, "operator %s must have at least one operand type", operatorName);
-
- /*
- * open the pg_operator relation
- */
- pg_operator_desc = heap_openr(OperatorRelationName, AccessShareLock);
-
- /*
- * get the oid for the operator with the appropriate name and
- * left/right types.
- */
- operatorObjectId = OperatorGetWithOpenRelation(pg_operator_desc,
- operatorName,
- leftObjectId,
- rightObjectId,
- defined);
-
- /*
- * close the relation and return the operator oid.
- */
heap_close(pg_operator_desc, AccessShareLock);
return operatorObjectId;
}
-/* ----------------------------------------------------------------
- * OperatorShellMake
- *
- * Specify operator name and left and right type names,
- * fill an operator struct with this info and NULL's,
- * call heap_insert and return the Oid to the caller.
- * ----------------------------------------------------------------
+/*
+ * OperatorShellMake
+ * Make a "shell" entry for a not-yet-existing operator.
*/
static Oid
-OperatorShellMake(char *operatorName,
- char *leftTypeName,
- char *rightTypeName)
+OperatorShellMake(const char *operatorName,
+ Oid leftTypeId,
+ Oid rightTypeId)
{
Relation pg_operator_desc;
Oid operatorObjectId;
- Oid leftObjectId = InvalidOid;
- Oid rightObjectId = InvalidOid;
- bool leftDefined = false;
- bool rightDefined = false;
int i;
HeapTuple tup;
Datum values[Natts_pg_operator];
elog(ERROR, "\"%s\" is not a valid operator name", operatorName);
/*
- * get the left and right type oid's for this operator
- */
- if (leftTypeName)
- leftObjectId = TypeGet(leftTypeName, &leftDefined);
-
- if (rightTypeName)
- rightObjectId = TypeGet(rightTypeName, &rightDefined);
-
- if (!((OidIsValid(leftObjectId) && leftDefined) ||
- (OidIsValid(rightObjectId) && rightDefined)))
- elog(ERROR, "OperatorShellMake: the operand types are not valid");
-
- /*
* open pg_operator
*/
pg_operator_desc = heap_openr(OperatorRelationName, RowExclusiveLock);
values[i++] = CharGetDatum('b'); /* assume it's binary */
values[i++] = BoolGetDatum(false);
values[i++] = BoolGetDatum(false);
- values[i++] = ObjectIdGetDatum(leftObjectId); /* <-- left oid */
- values[i++] = ObjectIdGetDatum(rightObjectId); /* <-- right oid */
+ values[i++] = ObjectIdGetDatum(leftTypeId);
+ values[i++] = ObjectIdGetDatum(rightTypeId);
values[i++] = ObjectIdGetDatum(InvalidOid);
values[i++] = ObjectIdGetDatum(InvalidOid);
values[i++] = ObjectIdGetDatum(InvalidOid);
* --------------------------------
* "X" indicates an optional argument (i.e. one that can be NULL)
* operatorName; -- operator name
- * leftTypeName; -- X left type name
- * rightTypeName; -- X right type name
+ * leftTypeId; -- X left type id
+ * rightTypeId; -- X right type id
* procedureName; -- procedure name for operator code
* precedence; -- operator precedence
* isLeftAssociative; -- operator is left associative?
* rightSortName; -- X right sort operator (for merge join)
*/
static void
-OperatorDef(char *operatorName,
- char *leftTypeName,
- char *rightTypeName,
- char *procedureName,
+OperatorDef(const char *operatorName,
+ Oid leftTypeId,
+ Oid rightTypeId,
+ const char *procedureName,
uint16 precedence,
bool isLeftAssociative,
- char *commutatorName,
- char *negatorName,
- char *restrictionName,
- char *joinName,
+ const char *commutatorName,
+ const char *negatorName,
+ const char *restrictionName,
+ const char *joinName,
bool canHash,
- char *leftSortName,
- char *rightSortName)
+ const char *leftSortName,
+ const char *rightSortName)
{
- int i,
- j;
Relation pg_operator_desc;
HeapScanDesc pg_operator_scan;
HeapTuple tup;
Datum values[Natts_pg_operator];
Oid operatorObjectId;
bool operatorAlreadyDefined;
- Oid leftTypeId = InvalidOid;
- Oid rightTypeId = InvalidOid;
Oid commutatorId = InvalidOid;
Oid negatorId = InvalidOid;
- bool leftDefined = false;
- bool rightDefined = false;
bool selfCommutator = false;
- char *name[4];
+ const char *name[4];
Oid typeId[FUNC_MAX_ARGS];
int nargs;
NameData oname;
TupleDesc tupDesc;
ScanKeyData opKey[3];
+ int i,
+ j;
+
+ /*
+ * validate operator name
+ */
+ if (!validOperatorName(operatorName))
+ elog(ERROR, "\"%s\" is not a valid operator name", operatorName);
+
+ if (!(OidIsValid(leftTypeId) || OidIsValid(rightTypeId)))
+ elog(ERROR, "operator must have at least one operand type");
operatorObjectId = OperatorGet(operatorName,
- leftTypeName,
- rightTypeName,
+ leftTypeId,
+ rightTypeId,
&operatorAlreadyDefined);
if (operatorAlreadyDefined)
* filling in a previously-created shell.
*/
- /*
- * validate operator name
- */
- if (!validOperatorName(operatorName))
- elog(ERROR, "\"%s\" is not a valid operator name", operatorName);
-
- /*
- * look up the operator data types.
- *
- * Note: types must be defined before operators
- */
- if (leftTypeName)
- {
- leftTypeId = TypeGet(leftTypeName, &leftDefined);
-
- if (!OidIsValid(leftTypeId) || !leftDefined)
- elog(ERROR, "left type \"%s\" does not exist",
- leftTypeName);
- }
-
- if (rightTypeName)
- {
- rightTypeId = TypeGet(rightTypeName, &rightDefined);
-
- if (!OidIsValid(rightTypeId) || !rightDefined)
- elog(ERROR, "right type \"%s\" does not exist",
- rightTypeName);
- }
-
- if (!((OidIsValid(leftTypeId) && leftDefined) ||
- (OidIsValid(rightTypeId) && rightDefined)))
- elog(ERROR, "operator must have at least one operand type");
-
for (i = 0; i < Natts_pg_operator; ++i)
{
values[i] = (Datum) NULL;
* created so we don't have to worry about deleting them later.
*/
MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
- if (!leftTypeName)
+ if (!OidIsValid(leftTypeId))
{
typeId[0] = rightTypeId;
nargs = 1;
}
- else if (!rightTypeName)
+ else if (!OidIsValid(rightTypeId))
{
typeId[0] = leftTypeId;
nargs = 1;
values[i++] = NameGetDatum(&oname);
values[i++] = Int32GetDatum(GetUserId());
values[i++] = UInt16GetDatum(precedence);
- values[i++] = CharGetDatum(leftTypeName ? (rightTypeName ? 'b' : 'r') : 'l');
+ values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l');
values[i++] = BoolGetDatum(isLeftAssociative);
values[i++] = BoolGetDatum(canHash);
values[i++] = ObjectIdGetDatum(leftTypeId);
{
if (name[j])
{
- char *otherLeftTypeName = NULL;
- char *otherRightTypeName = NULL;
Oid otherLeftTypeId = InvalidOid;
Oid otherRightTypeId = InvalidOid;
Oid other_oid = InvalidOid;
switch (j)
{
case 0: /* commutator has reversed arg types */
- otherLeftTypeName = rightTypeName;
- otherRightTypeName = leftTypeName;
otherLeftTypeId = rightTypeId;
otherRightTypeId = leftTypeId;
other_oid = OperatorGet(name[j],
- otherLeftTypeName,
- otherRightTypeName,
+ otherLeftTypeId,
+ otherRightTypeId,
&otherDefined);
commutatorId = other_oid;
break;
case 1: /* negator has same arg types */
- otherLeftTypeName = leftTypeName;
- otherRightTypeName = rightTypeName;
otherLeftTypeId = leftTypeId;
otherRightTypeId = rightTypeId;
other_oid = OperatorGet(name[j],
- otherLeftTypeName,
- otherRightTypeName,
+ otherLeftTypeId,
+ otherRightTypeId,
&otherDefined);
negatorId = other_oid;
break;
case 2: /* left sort op takes left-side data type */
- otherLeftTypeName = leftTypeName;
- otherRightTypeName = leftTypeName;
otherLeftTypeId = leftTypeId;
otherRightTypeId = leftTypeId;
other_oid = OperatorGet(name[j],
- otherLeftTypeName,
- otherRightTypeName,
+ otherLeftTypeId,
+ otherRightTypeId,
&otherDefined);
break;
- case 3: /* right sort op takes right-side data
- * type */
- otherLeftTypeName = rightTypeName;
- otherRightTypeName = rightTypeName;
+ case 3: /* right sort op takes right-side data type */
otherLeftTypeId = rightTypeId;
otherRightTypeId = rightTypeId;
other_oid = OperatorGet(name[j],
- otherLeftTypeName,
- otherRightTypeName,
+ otherLeftTypeId,
+ otherRightTypeId,
&otherDefined);
break;
}
{
/* not in catalogs, different from operator */
other_oid = OperatorShellMake(name[j],
- otherLeftTypeName,
- otherRightTypeName);
+ otherLeftTypeId,
+ otherRightTypeId);
if (!OidIsValid(other_oid))
elog(ERROR,
"OperatorDef: can't create operator shell \"%s\"",
*
* This is now just an interface procedure for OperatorDef ...
*
- * "X" indicates an optional argument (i.e. one that can be NULL)
+ * "X" indicates an optional argument (i.e. one that can be NULL or 0)
* operatorName; -- operator name
- * leftTypeName; -- X left type name
- * rightTypeName; -- X right type name
+ * leftTypeId; -- X left type ID
+ * rightTypeId; -- X right type ID
* procedureName; -- procedure for operator
* precedence; -- operator precedence
* isLeftAssociative; -- operator is left associative
* rightSortName; -- X right sort operator (for merge join)
*/
void
-OperatorCreate(char *operatorName,
- char *leftTypeName,
- char *rightTypeName,
- char *procedureName,
+OperatorCreate(const char *operatorName,
+ Oid leftTypeId,
+ Oid rightTypeId,
+ const char *procedureName,
uint16 precedence,
bool isLeftAssociative,
- char *commutatorName,
- char *negatorName,
- char *restrictionName,
- char *joinName,
+ const char *commutatorName,
+ const char *negatorName,
+ const char *restrictionName,
+ const char *joinName,
bool canHash,
- char *leftSortName,
- char *rightSortName)
+ const char *leftSortName,
+ const char *rightSortName)
{
- if (!leftTypeName && !rightTypeName)
+ if (!OidIsValid(leftTypeId) && !OidIsValid(rightTypeId))
elog(ERROR, "at least one of leftarg or rightarg must be specified");
- if (!(leftTypeName && rightTypeName))
+ if (!(OidIsValid(leftTypeId) && OidIsValid(rightTypeId)))
{
/* If it's not a binary op, these things mustn't be set: */
if (commutatorName)
* already exist.
*/
OperatorDef(operatorName,
- leftTypeName,
- rightTypeName,
+ leftTypeId,
+ rightTypeId,
procedureName,
precedence,
isLeftAssociative,