Move get_attdisbursion to lsyscache. Clean up get_typdefault.
This commit is contained in:
parent
e9054829a2
commit
5af4b04f31
@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
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);
|
||||||
|
182
src/backend/utils/cache/lsyscache.c
vendored
182
src/backend/utils/cache/lsyscache.c
vendored
@ -1,13 +1,12 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* 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 @@
|
|||||||
*/
|
*/
|
||||||
#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)
|
|||||||
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)
|
|||||||
/*
|
/*
|
||||||
* 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;
|
||||||
|
|
||||||
return typdefault;
|
/*
|
||||||
|
* 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 returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
111
src/backend/utils/cache/syscache.c
vendored
111
src/backend/utils/cache/syscache.c
vendored
@ -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,
|
|||||||
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;
|
|
||||||
}
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* 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);
|
|||||||
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);
|
|||||||
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 @@
|
|||||||
* 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,
|
|||||||
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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user