* pg_operator.c
* routines to support manipulation of the pg_operator relation
*
- * Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.40 1999/07/16 04:58:37 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.61 2001/08/10 15:49:39 petere Exp $
*
* NOTES
* these routines moved here from commands/define.c and somewhat cleaned up.
#include "access/heapam.h"
#include "catalog/catname.h"
+#include "catalog/indexing.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
#include "utils/syscache.h"
-#ifndef HAVE_MEMMOVE
-#include <regex/utils.h>
-#else
-#include <string.h>
-#endif
static Oid OperatorGetWithOpenRelation(Relation pg_operator_desc,
const char *operatorName,
/* ----------------------------------------------------------------
* OperatorGetWithOpenRelation
*
- * preforms a scan on pg_operator for an operator tuple
+ * performs a scan on pg_operator for an operator tuple
* with given name and left/right type oids.
- * ----------------------------------------------------------------
+ *
* 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)
+ * ----------------------------------------------------------------
*/
static Oid
OperatorGetWithOpenRelation(Relation pg_operator_desc,
HeapScanDesc pg_operator_scan;
Oid operatorObjectId;
HeapTuple tup;
+ ScanKeyData opKey[3];
- static ScanKeyData opKey[3] = {
- {0, Anum_pg_operator_oprname, F_NAMEEQ},
- {0, Anum_pg_operator_oprleft, F_OIDEQ},
- {0, Anum_pg_operator_oprright, F_OIDEQ},
- };
-
- fmgr_info(F_NAMEEQ, &opKey[0].sk_func);
- fmgr_info(F_OIDEQ, &opKey[1].sk_func);
- fmgr_info(F_OIDEQ, &opKey[2].sk_func);
- opKey[0].sk_nargs = opKey[0].sk_func.fn_nargs;
- opKey[1].sk_nargs = opKey[1].sk_func.fn_nargs;
- opKey[2].sk_nargs = opKey[2].sk_func.fn_nargs;
-
- /* ----------------
- * form scan key
- * ----------------
+ /*
+ * form scan key
*/
- opKey[0].sk_argument = PointerGetDatum(operatorName);
- opKey[1].sk_argument = ObjectIdGetDatum(leftObjectId);
- opKey[2].sk_argument = ObjectIdGetDatum(rightObjectId);
+ ScanKeyEntryInitialize(&opKey[0], 0x0,
+ Anum_pg_operator_oprname,
+ F_NAMEEQ,
+ PointerGetDatum(operatorName));
+ ScanKeyEntryInitialize(&opKey[1], 0x0,
+ Anum_pg_operator_oprleft,
+ F_OIDEQ,
+ ObjectIdGetDatum(leftObjectId));
+ ScanKeyEntryInitialize(&opKey[2], 0x0,
+ Anum_pg_operator_oprright,
+ F_OIDEQ,
+ ObjectIdGetDatum(rightObjectId));
- /* ----------------
- * begin the scan
- * ----------------
+ /*
+ * begin the scan
*/
pg_operator_scan = heap_beginscan(pg_operator_desc,
0,
3,
opKey);
- /* ----------------
- * fetch the operator tuple, if it exists, and determine
- * the proper return oid value.
- * ----------------
+ /*
+ * fetch the operator tuple, if it exists, and determine the proper
+ * return oid value.
*/
tup = heap_getnext(pg_operator_scan, 0);
*defined = false;
}
- /* ----------------
- * close the scan and return the oid.
- * ----------------
+ /*
+ * close the scan and return the oid.
*/
heap_endscan(pg_operator_scan);
bool leftDefined = false;
bool rightDefined = false;
- /* ----------------
- * look up the operator data types.
+ /*
+ * look up the operator data types.
*
- * Note: types must be defined before operators
- * ----------------
+ * Note: types must be defined before operators
*/
if (leftTypeName)
{
leftObjectId = TypeGet(leftTypeName, &leftDefined);
if (!OidIsValid(leftObjectId) || !leftDefined)
- elog(ERROR, "OperatorGet: left type '%s' nonexistent",
- leftTypeName);
+ 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, "OperatorGet: right type '%s' nonexistent",
- rightTypeName);
+ elog(ERROR, "right type \"%s\" of operator %s does not exist",
+ rightTypeName, operatorName);
}
if (!((OidIsValid(leftObjectId) && leftDefined) ||
(OidIsValid(rightObjectId) && rightDefined)))
- elog(ERROR, "OperatorGet: must have at least one argument type");
+ elog(ERROR, "operator %s must have at least one operand type", operatorName);
- /* ----------------
- * open the pg_operator relation
- * ----------------
+ /*
+ * open the pg_operator relation
*/
- pg_operator_desc = heap_openr(OperatorRelationName);
+ pg_operator_desc = heap_openr(OperatorRelationName, AccessShareLock);
- /* ----------------
- * get the oid for the operator with the appropriate name
- * and left/right types.
- * ----------------
+ /*
+ * get the oid for the operator with the appropriate name and
+ * left/right types.
*/
operatorObjectId = OperatorGetWithOpenRelation(pg_operator_desc,
operatorName,
rightObjectId,
defined);
- /* ----------------
- * close the relation and return the operator oid.
- * ----------------
+ /*
+ * close the relation and return the operator oid.
*/
- heap_close(pg_operator_desc);
+ heap_close(pg_operator_desc, AccessShareLock);
return operatorObjectId;
}
NameData oname;
TupleDesc tupDesc;
- /* ----------------
- * initialize our *nulls and *values arrays
- * ----------------
+ /*
+ * initialize our *nulls and *values arrays
*/
for (i = 0; i < Natts_pg_operator; ++i)
{
values[i] = (Datum) NULL; /* redundant, but safe */
}
- /* ----------------
- * initialize *values with the operator name and input data types.
- * Note that oprcode is set to InvalidOid, indicating it's a shell.
- * ----------------
+ /*
+ * initialize *values with the operator name and input data types.
+ * Note that oprcode is set to InvalidOid, indicating it's a shell.
*/
i = 0;
namestrcpy(&oname, operatorName);
values[i++] = NameGetDatum(&oname);
values[i++] = Int32GetDatum(GetUserId());
- values[i++] = (Datum) (uint16) 0;
- values[i++] = (Datum) 'b'; /* assume it's binary */
- values[i++] = (Datum) (bool) 0;
- values[i++] = (Datum) (bool) 0;
+ values[i++] = UInt16GetDatum(0);
+ 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(InvalidOid);
values[i++] = ObjectIdGetDatum(InvalidOid);
values[i++] = ObjectIdGetDatum(InvalidOid);
- /* ----------------
- * create a new operator tuple
- * ----------------
+ /*
+ * create a new operator tuple
*/
tupDesc = pg_operator_desc->rd_att;
values,
nulls);
- /* ----------------
- * insert our "shell" operator tuple and
- * close the relation
- * ----------------
+ /*
+ * insert our "shell" operator tuple and close the relation
*/
heap_insert(pg_operator_desc, tup);
operatorObjectId = tup->t_data->t_oid;
- /* ----------------
- * free the tuple and return the operator oid
- * ----------------
+ if (RelationGetForm(pg_operator_desc)->relhasindex)
+ {
+ Relation idescs[Num_pg_operator_indices];
+
+ CatalogOpenIndices(Num_pg_operator_indices, Name_pg_operator_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_operator_indices, pg_operator_desc, tup);
+ CatalogCloseIndices(Num_pg_operator_indices, idescs);
+ }
+
+ /*
+ * free the tuple and return the operator oid
*/
- pfree(tup);
+ heap_freetuple(tup);
return operatorObjectId;
}
bool leftDefined = false;
bool rightDefined = false;
- /* ----------------
- * get the left and right type oid's for this operator
- * ----------------
+ /*
+ * get the left and right type oid's for this operator
*/
if (leftTypeName)
leftObjectId = TypeGet(leftTypeName, &leftDefined);
if (!((OidIsValid(leftObjectId) && leftDefined) ||
(OidIsValid(rightObjectId) && rightDefined)))
- elog(ERROR, "OperatorShellMake: no valid argument types??");
+ elog(ERROR, "OperatorShellMake: the operand types are not valid");
- /* ----------------
- * open pg_operator
- * ----------------
+ /*
+ * open pg_operator
*/
- pg_operator_desc = heap_openr(OperatorRelationName);
+ pg_operator_desc = heap_openr(OperatorRelationName, RowExclusiveLock);
- /* ----------------
- * add a "shell" operator tuple to the operator relation
- * and recover the shell tuple's oid.
- * ----------------
+ /*
+ * add a "shell" operator tuple to the operator relation and recover
+ * the shell tuple's oid.
*/
operatorObjectId = OperatorShellMakeWithOpenRelation(pg_operator_desc,
operatorName,
leftObjectId,
rightObjectId);
- /* ----------------
- * close the operator relation and return the oid.
- * ----------------
+
+ /*
+ * close the operator relation and return the oid.
*/
- heap_close(pg_operator_desc);
+ heap_close(pg_operator_desc, RowExclusiveLock);
return operatorObjectId;
}
* resultType -- defer this, since it must be determined from
* the pg_procedure catalog
* commutatorObjectId -- if this is NULL, enter ObjectId=0
- * else if this already exists, enter it's ObjectId
+ * else if this already exists, enter its ObjectId
* else if this does not yet exist, and is not
* the same as the main operatorName, then create
* a shell and enter the new ObjectId
* rightSortObjectId -- same as for commutatorObjectId
* operatorProcedure -- must access the pg_procedure catalog to get the
* ObjectId of the procedure that actually does the operator
- * actions this is required. Do an amgetattr to find out the
+ * actions this is required. Do a lookup to find out the
* return type of the procedure
* restrictionProcedure -- must access the pg_procedure catalog to get
* the ObjectId but this is optional
int i,
j;
Relation pg_operator_desc;
-
HeapScanDesc pg_operator_scan;
HeapTuple tup;
char nulls[Natts_pg_operator];
bool rightDefined = false;
bool selfCommutator = false;
char *name[4];
- Oid typeId[8];
+ Oid typeId[FUNC_MAX_ARGS];
int nargs;
NameData oname;
TupleDesc tupDesc;
-
- static ScanKeyData opKey[3] = {
- {0, Anum_pg_operator_oprname, F_NAMEEQ},
- {0, Anum_pg_operator_oprleft, F_OIDEQ},
- {0, Anum_pg_operator_oprright, F_OIDEQ},
- };
-
- fmgr_info(F_NAMEEQ, &opKey[0].sk_func);
- fmgr_info(F_OIDEQ, &opKey[1].sk_func);
- fmgr_info(F_OIDEQ, &opKey[2].sk_func);
- opKey[0].sk_nargs = opKey[0].sk_func.fn_nargs;
- opKey[1].sk_nargs = opKey[1].sk_func.fn_nargs;
- opKey[2].sk_nargs = opKey[2].sk_func.fn_nargs;
+ ScanKeyData opKey[3];
operatorObjectId = OperatorGet(operatorName,
leftTypeName,
* filling in a previously-created shell.
*/
- /* ----------------
- * look up the operator data types.
+ /*
+ * look up the operator data types.
*
- * Note: types must be defined before operators
- * ----------------
+ * Note: types must be defined before operators
*/
if (leftTypeName)
{
leftTypeId = TypeGet(leftTypeName, &leftDefined);
if (!OidIsValid(leftTypeId) || !leftDefined)
- elog(ERROR, "OperatorDef: left type '%s' nonexistent",
+ elog(ERROR, "left type \"%s\" does not exist",
leftTypeName);
}
rightTypeId = TypeGet(rightTypeName, &rightDefined);
if (!OidIsValid(rightTypeId) || !rightDefined)
- elog(ERROR, "OperatorDef: right type '%s' nonexistent",
+ elog(ERROR, "right type \"%s\" does not exist",
rightTypeName);
}
if (!((OidIsValid(leftTypeId) && leftDefined) ||
(OidIsValid(rightTypeId) && rightDefined)))
- elog(ERROR, "OperatorDef: must have at least one argument type");
+ elog(ERROR, "operator must have at least one operand type");
for (i = 0; i < Natts_pg_operator; ++i)
{
nulls[i] = ' ';
}
- /* ----------------
- * Look up registered procedures -- find the return type
- * of procedureName to place in "result" field.
- * Do this before shells are created so we don't
- * have to worry about deleting them later.
- * ----------------
+ /*
+ * Look up registered procedures -- find the return type of
+ * procedureName to place in "result" field. Do this before shells are
+ * created so we don't have to worry about deleting them later.
*/
- MemSet(typeId, 0, 8 * sizeof(Oid));
+ MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
if (!leftTypeName)
{
typeId[0] = rightTypeId;
typeId[1] = rightTypeId;
nargs = 2;
}
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(procedureName),
- Int32GetDatum(nargs),
- PointerGetDatum(typeId),
- 0);
-
+ tup = SearchSysCache(PROCNAME,
+ PointerGetDatum(procedureName),
+ Int32GetDatum(nargs),
+ PointerGetDatum(typeId),
+ 0);
if (!HeapTupleIsValid(tup))
func_error("OperatorDef", procedureName, nargs, typeId, NULL);
values[Anum_pg_operator_oprresult - 1] = ObjectIdGetDatum(((Form_pg_proc)
GETSTRUCT(tup))->prorettype);
- /* ----------------
- * find restriction
- * ----------------
+ ReleaseSysCache(tup);
+
+ /*
+ * find restriction estimator
*/
if (restrictionName)
{ /* optional */
- MemSet(typeId, 0, 8 * sizeof(Oid));
- typeId[0] = OIDOID; /* operator OID */
- typeId[1] = OIDOID; /* relation OID */
- typeId[2] = INT2OID; /* attribute number */
- typeId[3] = 0; /* value - can be any type */
- typeId[4] = INT4OID; /* flags - left or right selectivity */
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(restrictionName),
- Int32GetDatum(5),
- PointerGetDatum(typeId),
- 0);
- if (!HeapTupleIsValid(tup))
- func_error("OperatorDef", restrictionName, 5, typeId, NULL);
-
- values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(tup->t_data->t_oid);
+ Oid restOid;
+
+ MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
+ typeId[0] = 0; /* Query (opaque type) */
+ typeId[1] = OIDOID; /* operator OID */
+ typeId[2] = 0; /* args list (opaque type) */
+ typeId[3] = INT4OID; /* varRelid */
+
+ restOid = GetSysCacheOid(PROCNAME,
+ PointerGetDatum(restrictionName),
+ Int32GetDatum(4),
+ PointerGetDatum(typeId),
+ 0);
+ if (!OidIsValid(restOid))
+ func_error("OperatorDef", restrictionName, 4, typeId, NULL);
+
+ values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(restOid);
}
else
values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(InvalidOid);
- /* ----------------
- * find join - only valid for binary operators
- * ----------------
+ /*
+ * find join estimator
*/
if (joinName)
{ /* optional */
- MemSet(typeId, 0, 8 * sizeof(Oid));
- typeId[0] = OIDOID; /* operator OID */
- typeId[1] = OIDOID; /* relation OID 1 */
- typeId[2] = INT2OID; /* attribute number 1 */
- typeId[3] = OIDOID; /* relation OID 2 */
- typeId[4] = INT2OID; /* attribute number 2 */
-
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(joinName),
- Int32GetDatum(5),
- PointerGetDatum(typeId),
- 0);
- if (!HeapTupleIsValid(tup))
- func_error("OperatorDef", joinName, 5, typeId, NULL);
-
- values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(tup->t_data->t_oid);
+ Oid joinOid;
+
+ MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
+ typeId[0] = 0; /* Query (opaque type) */
+ typeId[1] = OIDOID; /* operator OID */
+ typeId[2] = 0; /* args list (opaque type) */
+
+ joinOid = GetSysCacheOid(PROCNAME,
+ PointerGetDatum(joinName),
+ Int32GetDatum(3),
+ PointerGetDatum(typeId),
+ 0);
+ if (!OidIsValid(joinOid))
+ func_error("OperatorDef", joinName, 3, typeId, NULL);
+
+ values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(joinOid);
}
else
values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(InvalidOid);
- /* ----------------
+ /*
* set up values in the operator tuple
- * ----------------
*/
i = 0;
namestrcpy(&oname, operatorName);
values[i++] = NameGetDatum(&oname);
values[i++] = Int32GetDatum(GetUserId());
values[i++] = UInt16GetDatum(precedence);
- values[i++] = leftTypeName ? (rightTypeName ? 'b' : 'r') : 'l';
- values[i++] = Int8GetDatum(isLeftAssociative);
- values[i++] = Int8GetDatum(canHash);
+ values[i++] = CharGetDatum(leftTypeName ? (rightTypeName ? 'b' : 'r') : 'l');
+ values[i++] = BoolGetDatum(isLeftAssociative);
+ values[i++] = BoolGetDatum(canHash);
values[i++] = ObjectIdGetDatum(leftTypeId);
values[i++] = ObjectIdGetDatum(rightTypeId);
otherRightTypeName);
if (!OidIsValid(other_oid))
elog(ERROR,
- "OperatorDef: can't create operator shell '%s'",
+ "OperatorDef: can't create operator shell \"%s\"",
name[j]);
values[i++] = ObjectIdGetDatum(other_oid);
}
*/
if (j != 0)
elog(ERROR,
- "OperatorDef: operator can't be its own negator or sort op");
+ "operator cannot be its own negator or sort operator");
selfCommutator = true;
values[i++] = ObjectIdGetDatum(InvalidOid);
}
/* last three fields were filled in above */
+ pg_operator_desc = heap_openr(OperatorRelationName, RowExclusiveLock);
+
/*
* If we are adding to an operator shell, get its t_self
*/
- pg_operator_desc = heap_openr(OperatorRelationName);
-
if (operatorObjectId)
{
- opKey[0].sk_argument = PointerGetDatum(operatorName);
- opKey[1].sk_argument = ObjectIdGetDatum(leftTypeId);
- opKey[2].sk_argument = ObjectIdGetDatum(rightTypeId);
+ /* Make sure we can see the shell even if it is new in current cmd */
+ CommandCounterIncrement();
+
+ ScanKeyEntryInitialize(&opKey[0], 0x0,
+ Anum_pg_operator_oprname,
+ F_NAMEEQ,
+ PointerGetDatum(operatorName));
+ ScanKeyEntryInitialize(&opKey[1], 0x0,
+ Anum_pg_operator_oprleft,
+ F_OIDEQ,
+ ObjectIdGetDatum(leftTypeId));
+ ScanKeyEntryInitialize(&opKey[2], 0x0,
+ Anum_pg_operator_oprright,
+ F_OIDEQ,
+ ObjectIdGetDatum(rightTypeId));
pg_operator_scan = heap_beginscan(pg_operator_desc,
0,
nulls,
replaces);
- setheapoverride(true);
- heap_replace(pg_operator_desc, &tup->t_self, tup, NULL);
- setheapoverride(false);
+ simple_heap_update(pg_operator_desc, &tup->t_self, tup);
}
else
- elog(ERROR, "OperatorDef: no operator %u", operatorObjectId);
+ elog(ERROR, "OperatorDef: operator %u not found", operatorObjectId);
heap_endscan(pg_operator_scan);
}
operatorObjectId = tup->t_data->t_oid;
}
- heap_close(pg_operator_desc);
+ if (RelationGetForm(pg_operator_desc)->relhasindex)
+ {
+ Relation idescs[Num_pg_operator_indices];
+
+ CatalogOpenIndices(Num_pg_operator_indices, Name_pg_operator_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_operator_indices, pg_operator_desc, tup);
+ CatalogCloseIndices(Num_pg_operator_indices, idescs);
+ }
+
+ heap_close(pg_operator_desc, RowExclusiveLock);
/*
* If a commutator and/or negator link is provided, update the other
char nulls[Natts_pg_operator];
char replaces[Natts_pg_operator];
Datum values[Natts_pg_operator];
-
- static ScanKeyData opKey[1] = {
- {0, ObjectIdAttributeNumber, F_OIDEQ},
- };
-
- fmgr_info(F_OIDEQ, &opKey[0].sk_func);
- opKey[0].sk_nargs = opKey[0].sk_func.fn_nargs;
+ ScanKeyData opKey[1];
for (i = 0; i < Natts_pg_operator; ++i)
{
- values[i] = (Datum) NULL;
+ values[i] = (Datum) 0;
replaces[i] = ' ';
nulls[i] = ' ';
}
- pg_operator_desc = heap_openr(OperatorRelationName);
+ pg_operator_desc = heap_openr(OperatorRelationName, RowExclusiveLock);
- /* check and update the commutator, if necessary */
- opKey[0].sk_argument = ObjectIdGetDatum(commId);
+ /*
+ * check and update the commutator & negator, if necessary
+ *
+ * First make sure we can see them...
+ */
+ CommandCounterIncrement();
+
+ ScanKeyEntryInitialize(&opKey[0], 0x0,
+ ObjectIdAttributeNumber,
+ F_OIDEQ,
+ ObjectIdGetDatum(commId));
pg_operator_scan = heap_beginscan(pg_operator_desc,
0,
nulls,
replaces);
- setheapoverride(true);
- heap_replace(pg_operator_desc, &tup->t_self, tup, NULL);
- setheapoverride(false);
+ simple_heap_update(pg_operator_desc, &tup->t_self, tup);
+
+ if (RelationGetForm(pg_operator_desc)->relhasindex)
+ {
+ Relation idescs[Num_pg_operator_indices];
+ CatalogOpenIndices(Num_pg_operator_indices, Name_pg_operator_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_operator_indices, pg_operator_desc, tup);
+ CatalogCloseIndices(Num_pg_operator_indices, idescs);
+ }
}
}
heap_endscan(pg_operator_scan);
- heap_close(pg_operator_desc);
+ heap_close(pg_operator_desc, RowExclusiveLock);
return;
}
nulls,
replaces);
- setheapoverride(true);
- heap_replace(pg_operator_desc, &tup->t_self, tup, NULL);
- setheapoverride(false);
+ simple_heap_update(pg_operator_desc, &tup->t_self, tup);
+
+ if (RelationGetForm(pg_operator_desc)->relhasindex)
+ {
+ Relation idescs[Num_pg_operator_indices];
+
+ CatalogOpenIndices(Num_pg_operator_indices, Name_pg_operator_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_operator_indices, pg_operator_desc, tup);
+ CatalogCloseIndices(Num_pg_operator_indices, idescs);
+ }
values[Anum_pg_operator_oprcom - 1] = (Datum) NULL;
replaces[Anum_pg_operator_oprcom - 1] = ' ';
nulls,
replaces);
- setheapoverride(true);
- heap_replace(pg_operator_desc, &tup->t_self, tup, NULL);
- setheapoverride(false);
+ simple_heap_update(pg_operator_desc, &tup->t_self, tup);
+
+ if (RelationGetForm(pg_operator_desc)->relhasindex)
+ {
+ Relation idescs[Num_pg_operator_indices];
+
+ CatalogOpenIndices(Num_pg_operator_indices, Name_pg_operator_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_operator_indices, pg_operator_desc, tup);
+ CatalogCloseIndices(Num_pg_operator_indices, idescs);
+ }
}
heap_endscan(pg_operator_scan);
- heap_close(pg_operator_desc);
+ heap_close(pg_operator_desc, RowExclusiveLock);
}
char *rightSortName)
{
if (!leftTypeName && !rightTypeName)
- elog(ERROR, "OperatorCreate: at least one of leftarg or rightarg must be defined");
+ elog(ERROR, "at least one of leftarg or rightarg must be specified");
if (!(leftTypeName && rightTypeName))
{
/* If it's not a binary op, these things mustn't be set: */
if (commutatorName)
- elog(ERROR, "OperatorCreate: only binary operators can have commutators");
- if (negatorName)
- elog(ERROR, "OperatorCreate: only binary operators can have negators");
- if (restrictionName || joinName)
- elog(ERROR, "OperatorCreate: only binary operators can have selectivity");
+ elog(ERROR, "only binary operators can have commutators");
+ if (joinName)
+ elog(ERROR, "only binary operators can have join selectivity");
if (canHash)
- elog(ERROR, "OperatorCreate: only binary operators can hash");
+ elog(ERROR, "only binary operators can hash");
if (leftSortName || rightSortName)
- elog(ERROR, "OperatorCreate: only binary operators can have sort links");
+ elog(ERROR, "only binary operators can have sort links");
}
- /* ----------------
- * Use OperatorDef() to define the specified operator and
- * also create shells for the operator's associated operators
- * if they don't already exist.
- * ----------------
+ /*
+ * Use OperatorDef() to define the specified operator and also create
+ * shells for the operator's associated operators if they don't
+ * already exist.
*/
OperatorDef(operatorName,
leftTypeName,