]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Move get_attdisbursion to lsyscache. Clean up get_typdefault.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 9 Aug 1999 03:13:31 +0000 (03:13 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 9 Aug 1999 03:13:31 +0000 (03:13 +0000)
src/backend/optimizer/prep/preptlist.c
src/backend/utils/cache/lsyscache.c
src/backend/utils/cache/syscache.c
src/include/utils/lsyscache.h
src/include/utils/syscache.h

index ac0223879ddfcb572b1881d0efd4952f9a2fe9ba..0cc4780807e85d0b8ac6f5d33e08f1d593058992 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.28 1999/08/09 00:51:26 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.29 1999/08/09 03:13:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -297,12 +297,12 @@ new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type)
                {
                        case T_Const:           /* INSERT command */
                                {
-                                       struct varlena *typedefault = get_typdefault(atttype);
+                                       Datum           typedefault = get_typdefault(atttype);
                                        int                     typlen;
                                        Const      *temp_const;
                                        TargetEntry *temp_tle;
 
-                                       if (typedefault == NULL)
+                                       if (typedefault == PointerGetDatum(NULL))
                                                typlen = 0;
                                        else
                                        {
@@ -319,9 +319,8 @@ new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type)
 
                                        temp_const = makeConst(atttype,
                                                                                   typlen,
-                                                                                  (Datum) typedefault,
-                                                                                  (typedefault == NULL),
-                                                                                  /* XXX ? */
+                                                                                  typedefault,
+                                                                                  (typedefault == PointerGetDatum(NULL)),
                                                                                   false,
                                                                                   false, /* not a set */
                                                                                   false);
index 07583a4b72a3a4069741b2c6b74b4ac35f5f45c2..cd657ca32729b1cb52a3da3ee86da63ff0e585ca 100644 (file)
@@ -1,13 +1,12 @@
 /*-------------------------------------------------------------------------
  *
  * lsyscache.c
- *       Routines to access information within system caches
+ *       Convenience routines for common queries in the system catalog cache.
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.31 1999/07/17 20:18:01 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.32 1999/08/09 03:13:30 tgl Exp $
  *
  * NOTES
  *       Eventually, the index information should go through here, too.
@@ -15,7 +14,6 @@
  */
 #include "postgres.h"
 
-
 #include "catalog/pg_operator.h"
 #include "catalog/pg_type.h"
 #include "utils/lsyscache.h"
@@ -166,6 +164,77 @@ get_atttypmod(Oid relid, AttrNumber attnum)
                return -1;
 }
 
+/*
+ * get_attdisbursion
+ *
+ *       Retrieve the disbursion statistic for an attribute,
+ *       or produce an estimate if no info is available.
+ *
+ * min_estimate is the minimum estimate to return if insufficient data
+ * is available to produce a reliable value.  This value may vary
+ * depending on context.  (For example, when deciding whether it is
+ * safe to use a hashjoin, we want to be more conservative than when
+ * estimating the number of tuples produced by an equijoin.)
+ */
+double
+get_attdisbursion(Oid relid, AttrNumber attnum, double min_estimate)
+{
+       HeapTuple       atp;
+       double          disbursion;
+       int32           ntuples;
+
+       atp = SearchSysCacheTuple(ATTNUM,
+                                                         ObjectIdGetDatum(relid),
+                                                         Int16GetDatum(attnum),
+                                                         0, 0);
+       if (!HeapTupleIsValid(atp))
+       {
+               /* this should not happen */
+               elog(ERROR, "get_attdisbursion: no attribute tuple %u %d",
+                        relid, attnum);
+               return min_estimate;
+       }
+
+       disbursion = ((Form_pg_attribute) GETSTRUCT(atp))->attdisbursion;
+       if (disbursion > 0.0)
+               return disbursion;              /* we have a specific estimate */
+
+       /*
+        * Disbursion is either 0 (no data available) or -1 (disbursion
+        * is 1/numtuples).  Either way, we need the relation size.
+        */
+
+       atp = SearchSysCacheTuple(RELOID,
+                                                         ObjectIdGetDatum(relid),
+                                                         0, 0, 0);
+       if (!HeapTupleIsValid(atp))
+       {
+               /* this should not happen */
+               elog(ERROR, "get_attdisbursion: no relation tuple %u", relid);
+               return min_estimate;
+       }
+
+       ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
+
+       if (ntuples == 0)
+               return min_estimate;    /* no data available */
+
+       if (disbursion < 0.0)           /* VACUUM thinks there are no duplicates */
+               return 1.0 / (double) ntuples;
+
+       /*
+        * VACUUM ANALYZE has not been run for this table.
+        * Produce an estimate = 1/numtuples.  This may produce
+        * unreasonably small estimates for large tables, so limit
+        * the estimate to no less than min_estimate.
+        */
+       disbursion = 1.0 / (double) ntuples;
+       if (disbursion < min_estimate)
+               disbursion = min_estimate;
+
+       return disbursion;
+}
+
 /*                             ---------- INDEX CACHE ----------                                                */
 
 /*             watch this space...
@@ -504,15 +573,110 @@ get_typalign(Oid typid)
 /*
  * get_typdefault -
  *
- *             Given the type OID, return the default value of the ADT.
- *
+ *       Given a type OID, return the typdefault field associated with that
+ *       type, or Datum(NULL) if there is no typdefault.  (This implies
+ *       that pass-by-value types can't have a default value that has
+ *       a representation of zero.  Not worth fixing now.)
+ *       The result points to palloc'd storage for non-pass-by-value types.
  */
-struct varlena *
+Datum
 get_typdefault(Oid typid)
 {
-       struct varlena *typdefault = (struct varlena *) TypeDefaultRetrieve(typid);
+       struct varlena *typDefault;
+       int32           dataSize;
+       HeapTuple       typeTuple;
+       Form_pg_type type;
+       int32           typLen;
+       bool            typByVal;
+       Datum           returnValue;
+
+       /*
+        * First, see if there is a non-null typdefault field (usually there isn't)
+        */
+       typDefault = (struct varlena *)
+               SearchSysCacheGetAttribute(TYPOID,
+                                                                  Anum_pg_type_typdefault,
+                                                                  ObjectIdGetDatum(typid),
+                                                                  0, 0, 0);
+
+       if (typDefault == NULL)
+               return PointerGetDatum(NULL);
+
+       dataSize = VARSIZE(typDefault) - VARHDRSZ;
+
+       /*
+        * Need the type's length and byVal fields.
+        *
+        * XXX silly to repeat the syscache search that SearchSysCacheGetAttribute
+        * just did --- but at present this path isn't taken often enough to
+        * make it worth fixing.
+        */
+       typeTuple = SearchSysCacheTuple(TYPOID,
+                                                                       ObjectIdGetDatum(typid),
+                                                                       0, 0, 0);
+
+       if (!HeapTupleIsValid(typeTuple))
+               elog(ERROR, "get_typdefault: failed to lookup type %u", typid);
+
+       type = (Form_pg_type) GETSTRUCT(typeTuple);
+       typLen = type->typlen;
+       typByVal = type->typbyval;
+
+       if (typByVal)
+       {
+               int8            i8;
+               int16           i16;
+               int32           i32 = 0;
+
+               if (dataSize == typLen)
+               {
+                       switch (typLen)
+                       {
+                               case sizeof(int8):
+                                       memcpy((char *) &i8, VARDATA(typDefault), sizeof(int8));
+                                       i32 = i8;
+                                       break;
+                               case sizeof(int16):
+                                       memcpy((char *) &i16, VARDATA(typDefault), sizeof(int16));
+                                       i32 = i16;
+                                       break;
+                               case sizeof(int32):
+                                       memcpy((char *) &i32, VARDATA(typDefault), sizeof(int32));
+                                       break;
+                       }
+                       returnValue = Int32GetDatum(i32);
+               }
+               else
+                       returnValue = PointerGetDatum(NULL);
+       }
+       else if (typLen < 0)
+       {
+               /* variable-size type */
+               if (dataSize < 0)
+                       returnValue = PointerGetDatum(NULL);
+               else
+               {
+                       returnValue = PointerGetDatum(palloc(VARSIZE(typDefault)));
+                       memcpy((char *) DatumGetPointer(returnValue),
+                                  (char *) typDefault,
+                                  (int) VARSIZE(typDefault));
+               }
+       }
+       else
+       {
+               /* fixed-size pass-by-ref type */
+               if (dataSize != typLen)
+                       returnValue = PointerGetDatum(NULL);
+               else
+               {
+                       returnValue = PointerGetDatum(palloc(dataSize));
+                       memcpy((char *) DatumGetPointer(returnValue),
+                                  VARDATA(typDefault),
+                                  (int) dataSize);
+               }
+       }
 
-       return typdefault;
+       return returnValue;
 }
 
 /*
index 4e4c354e07b2bc6c581f27a6ad8304f51db7b734..470780676c29487ac142b9a50a7e8bef1e5e7952 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.33 1999/07/20 17:14:06 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.34 1999/08/09 03:13:30 tgl Exp $
  *
  * NOTES
  *       These routines allow the parser/planner/executor to perform
@@ -631,112 +631,3 @@ SearchSysCacheGetAttribute(int cacheId,
        heap_close(relation);
        return returnValue;
 }
-
-/*
- * TypeDefaultRetrieve
- *
- *       Given a type OID, return the typdefault field associated with that
- *       type.  The result is a Datum, and points to palloc'd storage for
- *       non-pass-by-value types.
- *
- * [identical to get_typdefault, expecting a (struct varlena *) as ret val.
- *     some day, either of the functions should be removed              -ay 10/94]
- */
-void *
-TypeDefaultRetrieve(Oid typId)
-{
-       struct varlena *typDefault;
-       int32           dataSize;
-       HeapTuple       typeTuple;
-       Form_pg_type type;
-       int32           typByVal,
-                               typLen;
-       void       *returnValue;
-
-       /*
-        * First, see if there is a non-null typdefault field (usually there isn't)
-        */
-       typDefault = (struct varlena *)
-               SearchSysCacheGetAttribute(TYPOID,
-                                                                  Anum_pg_type_typdefault,
-                                                                  ObjectIdGetDatum(typId),
-                                                                  0, 0, 0);
-
-       if (typDefault == NULL)
-       {
-#ifdef CACHEDEBUG
-               elog(DEBUG, "TypeDefaultRetrieve: No extractable typdefault in %s(%d)",
-                        cacheinfo[TYPOID].name, TYPOID);
-#endif  /* defined(CACHEDEBUG) */
-               return NULL;
-       }
-
-       dataSize = VARSIZE(typDefault) - VARHDRSZ;
-
-       /*
-        * Need the type's length and byVal fields.
-        *
-        * XXX silly to repeat the syscache search that SearchSysCacheGetAttribute
-        * just did --- but at present this path isn't taken often enough to
-        * make it worth fixing.
-        */
-       typeTuple = SearchSysCacheTuple(TYPOID,
-                                                                       ObjectIdGetDatum(typId),
-                                                                       0, 0, 0);
-
-       if (!HeapTupleIsValid(typeTuple))
-       {
-               /* should never get here, really... */
-#ifdef CACHEDEBUG
-               elog(DEBUG, "TypeDefaultRetrieve: Lookup in %s(%d) failed",
-                        cacheinfo[TYPOID].name, TYPOID);
-#endif  /* defined(CACHEDEBUG) */
-               return NULL;
-       }
-
-       type = (Form_pg_type) GETSTRUCT(typeTuple);
-       typLen = type->typlen;
-       typByVal = type->typbyval;
-
-       if (typByVal)
-       {
-               int8            i8;
-               int16           i16;
-               int32           i32 = 0;
-
-               if (dataSize == typLen)
-               {
-                       switch (typLen)
-                       {
-                               case sizeof(int8):
-                                       memcpy((char *) &i8, VARDATA(typDefault), sizeof(int8));
-                                       i32 = i8;
-                                       break;
-                               case sizeof(int16):
-                                       memcpy((char *) &i16, VARDATA(typDefault), sizeof(int16));
-                                       i32 = i16;
-                                       break;
-                               case sizeof(int32):
-                                       memcpy((char *) &i32, VARDATA(typDefault), sizeof(int32));
-                                       break;
-                       }
-                       returnValue = (void *) i32;
-               }
-               else
-                       returnValue = NULL;
-       }
-       else
-       {
-               if ((typLen < 0 && dataSize < 0) || dataSize != typLen)
-                       returnValue = NULL;
-               else
-               {
-                       returnValue = (void *) palloc(VARSIZE(typDefault));
-                       memcpy((char *) returnValue,
-                                  (char *) typDefault,
-                                  (int) VARSIZE(typDefault));
-               }
-       }
-
-       return returnValue;
-}
index 39cf80d9ebf8a8f5a23695593772e01723bb69e1..4ca8fddda108359a512ef2077c425c70245dee66 100644 (file)
@@ -1,12 +1,11 @@
 /*-------------------------------------------------------------------------
  *
  * lsyscache.h
- *
- *
+ *       Convenience routines for common queries in the system catalog cache.
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: lsyscache.h,v 1.18 1999/07/15 23:04:23 momjian Exp $
+ * $Id: lsyscache.h,v 1.19 1999/08/09 03:13:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,6 +20,8 @@ extern AttrNumber get_attnum(Oid relid, char *attname);
 extern Oid     get_atttype(Oid relid, AttrNumber attnum);
 extern bool get_attisset(Oid relid, char *attname);
 extern int32 get_atttypmod(Oid relid, AttrNumber attnum);
+extern double get_attdisbursion(Oid relid, AttrNumber attnum,
+                                                               double min_estimate);
 extern RegProcedure get_opcode(Oid opid);
 extern char *get_opname(Oid opid);
 extern bool op_mergejoinable(Oid opid, Oid ltype, Oid rtype,
@@ -38,6 +39,6 @@ extern Oid    get_ruleid(char *rulename);
 extern Oid     get_eventrelid(Oid ruleid);
 extern int16 get_typlen(Oid typid);
 extern bool get_typbyval(Oid typid);
-extern struct varlena *get_typdefault(Oid typid);
+extern Datum get_typdefault(Oid typid);
 
 #endif  /* LSYSCACHE_H */
index 313f543e45e90085b04e362138c97c8b8d10c08b..b2850a8a6b0d71d2f612429f3efcdcb3615d6ec7 100644 (file)
@@ -3,10 +3,12 @@
  * syscache.h
  *       System catalog cache definitions.
  *
+ * See also lsyscache.h, which provides convenience routines for
+ * common cache-lookup operations.
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: syscache.h,v 1.17 1999/07/20 17:14:08 momjian Exp $
+ * $Id: syscache.h,v 1.18 1999/08/09 03:13:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -87,6 +89,5 @@ extern int32 SearchSysCacheStruct(int cacheId, char *returnStruct,
 extern void *SearchSysCacheGetAttribute(int cacheId,
                                                   AttrNumber attributeNumber,
                                                 Datum key1, Datum key2, Datum key3, Datum key4);
-extern void *TypeDefaultRetrieve(Oid typId);
 
 #endif  /* SYSCACHE_H */