X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=src%2Fbackend%2Fcatalog%2Fpg_operator.c;h=a72565e9709d284ed723a72a69cabe149ba8276b;hb=8265769c8270239352aae62a3cb97308b527972a;hp=25ecf12f3b6d7a60a0b8b44162b80436dfc187a2;hpb=9e1552607a9dc6bc23e43d46770a9063ade4f3f0;p=postgresql diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index 25ecf12f3b..a72565e970 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.56 2001/03/22 03:59:20 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. @@ -69,14 +69,15 @@ static void OperatorUpd(Oid baseId, Oid commId, Oid negId); /* ---------------------------------------------------------------- * 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, @@ -88,31 +89,26 @@ 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, @@ -120,10 +116,9 @@ OperatorGetWithOpenRelation(Relation pg_operator_desc, 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); @@ -140,9 +135,8 @@ OperatorGetWithOpenRelation(Relation pg_operator_desc, *defined = false; } - /* ---------------- - * close the scan and return the oid. - * ---------------- + /* + * close the scan and return the oid. */ heap_endscan(pg_operator_scan); @@ -170,19 +164,18 @@ OperatorGet(char *operatorName, 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\" does not exist", - leftTypeName); + elog(ERROR, "left type \"%s\" of operator %s does not exist", + leftTypeName, operatorName); } if (rightTypeName) @@ -190,24 +183,22 @@ OperatorGet(char *operatorName, rightObjectId = TypeGet(rightTypeName, &rightDefined); if (!OidIsValid(rightObjectId) || !rightDefined) - elog(ERROR, "OperatorGet: right type \"%s\" does not exist", - 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, 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, @@ -215,9 +206,8 @@ OperatorGet(char *operatorName, rightObjectId, defined); - /* ---------------- - * close the relation and return the operator oid. - * ---------------- + /* + * close the relation and return the operator oid. */ heap_close(pg_operator_desc, AccessShareLock); @@ -243,9 +233,8 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc, NameData oname; TupleDesc tupDesc; - /* ---------------- - * initialize our *nulls and *values arrays - * ---------------- + /* + * initialize our *nulls and *values arrays */ for (i = 0; i < Natts_pg_operator; ++i) { @@ -253,10 +242,9 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc, 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); @@ -277,9 +265,8 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc, values[i++] = ObjectIdGetDatum(InvalidOid); values[i++] = ObjectIdGetDatum(InvalidOid); - /* ---------------- - * create a new operator tuple - * ---------------- + /* + * create a new operator tuple */ tupDesc = pg_operator_desc->rd_att; @@ -287,10 +274,8 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc, 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; @@ -304,9 +289,8 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc, CatalogCloseIndices(Num_pg_operator_indices, idescs); } - /* ---------------- - * free the tuple and return the operator oid - * ---------------- + /* + * free the tuple and return the operator oid */ heap_freetuple(tup); @@ -335,9 +319,8 @@ OperatorShellMake(char *operatorName, 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); @@ -347,26 +330,24 @@ OperatorShellMake(char *operatorName, 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, 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, RowExclusiveLock); @@ -421,7 +402,7 @@ OperatorShellMake(char *operatorName, * 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 @@ -468,7 +449,6 @@ OperatorDef(char *operatorName, int i, j; Relation pg_operator_desc; - HeapScanDesc pg_operator_scan; HeapTuple tup; char nulls[Natts_pg_operator]; @@ -488,19 +468,7 @@ OperatorDef(char *operatorName, 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, @@ -516,18 +484,17 @@ OperatorDef(char *operatorName, * 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\" does not exist", + elog(ERROR, "left type \"%s\" does not exist", leftTypeName); } @@ -536,13 +503,13 @@ OperatorDef(char *operatorName, rightTypeId = TypeGet(rightTypeName, &rightDefined); if (!OidIsValid(rightTypeId) || !rightDefined) - elog(ERROR, "OperatorDef: right type \"%s\" does not exist", + 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) { @@ -551,12 +518,10 @@ OperatorDef(char *operatorName, 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, FUNC_MAX_ARGS * sizeof(Oid)); if (!leftTypeName) @@ -589,65 +554,59 @@ OperatorDef(char *operatorName, ReleaseSysCache(tup); - /* ---------------- - * find restriction - * ---------------- + /* + * find restriction estimator */ if (restrictionName) { /* optional */ Oid restOid; MemSet(typeId, 0, FUNC_MAX_ARGS * 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 */ + 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(5), + Int32GetDatum(4), PointerGetDatum(typeId), 0); if (!OidIsValid(restOid)) - func_error("OperatorDef", restrictionName, 5, typeId, NULL); + 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 */ Oid joinOid; MemSet(typeId, 0, FUNC_MAX_ARGS * 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 */ + typeId[0] = 0; /* Query (opaque type) */ + typeId[1] = OIDOID; /* operator OID */ + typeId[2] = 0; /* args list (opaque type) */ joinOid = GetSysCacheOid(PROCNAME, PointerGetDatum(joinName), - Int32GetDatum(5), + Int32GetDatum(3), PointerGetDatum(typeId), 0); if (!OidIsValid(joinOid)) - func_error("OperatorDef", joinName, 5, typeId, NULL); + 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); @@ -758,7 +717,7 @@ OperatorDef(char *operatorName, */ 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); } @@ -779,13 +738,22 @@ OperatorDef(char *operatorName, */ 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, SnapshotSelf, /* no cache? */ @@ -804,7 +772,7 @@ OperatorDef(char *operatorName, 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); } @@ -815,7 +783,6 @@ OperatorDef(char *operatorName, heap_insert(pg_operator_desc, tup); operatorObjectId = tup->t_data->t_oid; - } if (RelationGetForm(pg_operator_desc)->relhasindex) @@ -867,17 +834,11 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId) 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] = ' '; } @@ -891,7 +852,10 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId) */ CommandCounterIncrement(); - opKey[0].sk_argument = ObjectIdGetDatum(commId); + ScanKeyEntryInitialize(&opKey[0], 0x0, + ObjectIdAttributeNumber, + F_OIDEQ, + ObjectIdGetDatum(commId)); pg_operator_scan = heap_beginscan(pg_operator_desc, 0, @@ -1019,7 +983,6 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId) heap_endscan(pg_operator_scan); - heap_close(pg_operator_desc, RowExclusiveLock); } @@ -1060,28 +1023,25 @@ OperatorCreate(char *operatorName, 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,