]> granicus.if.org Git - postgresql/blobdiff - src/backend/catalog/pg_operator.c
message refinements
[postgresql] / src / backend / catalog / pg_operator.c
index 25ecf12f3b6d7a60a0b8b44162b80436dfc187a2..a72565e9709d284ed723a72a69cabe149ba8276b 100644 (file)
@@ -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,