提交 5af4b04f 编写于 作者: T Tom Lane

Move get_attdisbursion to lsyscache. Clean up get_typdefault.

上级 e9054829
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -297,12 +297,12 @@ new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type)
{ {
case T_Const: /* INSERT command */ case T_Const: /* INSERT command */
{ {
struct varlena *typedefault = get_typdefault(atttype); Datum typedefault = get_typdefault(atttype);
int typlen; int typlen;
Const *temp_const; Const *temp_const;
TargetEntry *temp_tle; TargetEntry *temp_tle;
if (typedefault == NULL) if (typedefault == PointerGetDatum(NULL))
typlen = 0; typlen = 0;
else else
{ {
...@@ -319,9 +319,8 @@ new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type) ...@@ -319,9 +319,8 @@ new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type)
temp_const = makeConst(atttype, temp_const = makeConst(atttype,
typlen, typlen,
(Datum) typedefault, typedefault,
(typedefault == NULL), (typedefault == PointerGetDatum(NULL)),
/* XXX ? */
false, false,
false, /* not a set */ false, /* not a set */
false); false);
......
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* lsyscache.c * 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 * Copyright (c) 1994, Regents of the University of California
* *
*
* IDENTIFICATION * 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 * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
...@@ -15,7 +14,6 @@ ...@@ -15,7 +14,6 @@
*/ */
#include "postgres.h" #include "postgres.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
...@@ -166,6 +164,77 @@ get_atttypmod(Oid relid, AttrNumber attnum) ...@@ -166,6 +164,77 @@ get_atttypmod(Oid relid, AttrNumber attnum)
return -1; 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 ---------- */ /* ---------- INDEX CACHE ---------- */
/* watch this space... /* watch this space...
...@@ -504,15 +573,110 @@ get_typalign(Oid typid) ...@@ -504,15 +573,110 @@ get_typalign(Oid typid)
/* /*
* get_typdefault - * 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) 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;
} }
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
...@@ -631,112 +631,3 @@ SearchSysCacheGetAttribute(int cacheId, ...@@ -631,112 +631,3 @@ SearchSysCacheGetAttribute(int cacheId,
heap_close(relation); heap_close(relation);
return returnValue; 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;
}
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* lsyscache.h * lsyscache.h
* * Convenience routines for common queries in the system catalog cache.
*
* *
* Copyright (c) 1994, Regents of the University of California * 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); ...@@ -21,6 +20,8 @@ extern AttrNumber get_attnum(Oid relid, char *attname);
extern Oid get_atttype(Oid relid, AttrNumber attnum); extern Oid get_atttype(Oid relid, AttrNumber attnum);
extern bool get_attisset(Oid relid, char *attname); extern bool get_attisset(Oid relid, char *attname);
extern int32 get_atttypmod(Oid relid, AttrNumber attnum); 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 RegProcedure get_opcode(Oid opid);
extern char *get_opname(Oid opid); extern char *get_opname(Oid opid);
extern bool op_mergejoinable(Oid opid, Oid ltype, Oid rtype, extern bool op_mergejoinable(Oid opid, Oid ltype, Oid rtype,
...@@ -38,6 +39,6 @@ extern Oid get_ruleid(char *rulename); ...@@ -38,6 +39,6 @@ extern Oid get_ruleid(char *rulename);
extern Oid get_eventrelid(Oid ruleid); extern Oid get_eventrelid(Oid ruleid);
extern int16 get_typlen(Oid typid); extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid); extern bool get_typbyval(Oid typid);
extern struct varlena *get_typdefault(Oid typid); extern Datum get_typdefault(Oid typid);
#endif /* LSYSCACHE_H */ #endif /* LSYSCACHE_H */
...@@ -3,10 +3,12 @@ ...@@ -3,10 +3,12 @@
* syscache.h * syscache.h
* System catalog cache definitions. * 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 * 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, ...@@ -87,6 +89,5 @@ extern int32 SearchSysCacheStruct(int cacheId, char *returnStruct,
extern void *SearchSysCacheGetAttribute(int cacheId, extern void *SearchSysCacheGetAttribute(int cacheId,
AttrNumber attributeNumber, AttrNumber attributeNumber,
Datum key1, Datum key2, Datum key3, Datum key4); Datum key1, Datum key2, Datum key3, Datum key4);
extern void *TypeDefaultRetrieve(Oid typId);
#endif /* SYSCACHE_H */ #endif /* SYSCACHE_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册