Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5af4b04

Browse files
committed
Move get_attdisbursion to lsyscache. Clean up get_typdefault.
1 parent e905482 commit 5af4b04

File tree

5 files changed

+187
-131
lines changed

5 files changed

+187
-131
lines changed

src/backend/optimizer/prep/preptlist.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.28 1999/08/09 00:51:26 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.29 1999/08/09 03:13:31 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -297,12 +297,12 @@ new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type)
297297
{
298298
case T_Const: /* INSERT command */
299299
{
300-
struct varlena *typedefault = get_typdefault(atttype);
300+
Datum typedefault = get_typdefault(atttype);
301301
int typlen;
302302
Const *temp_const;
303303
TargetEntry *temp_tle;
304304

305-
if (typedefault == NULL)
305+
if (typedefault == PointerGetDatum(NULL))
306306
typlen = 0;
307307
else
308308
{
@@ -319,9 +319,8 @@ new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type)
319319

320320
temp_const = makeConst(atttype,
321321
typlen,
322-
(Datum) typedefault,
323-
(typedefault == NULL),
324-
/* XXX ? */
322+
typedefault,
323+
(typedefault == PointerGetDatum(NULL)),
325324
false,
326325
false, /* not a set */
327326
false);

src/backend/utils/cache/lsyscache.c

Lines changed: 173 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
/*-------------------------------------------------------------------------
22
*
33
* lsyscache.c
4-
* Routines to access information within system caches
4+
* Convenience routines for common queries in the system catalog cache.
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
*
98
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.31 1999/07/17 20:18:01 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.32 1999/08/09 03:13:30 tgl Exp $
1110
*
1211
* NOTES
1312
* Eventually, the index information should go through here, too.
1413
*-------------------------------------------------------------------------
1514
*/
1615
#include "postgres.h"
1716

18-
1917
#include "catalog/pg_operator.h"
2018
#include "catalog/pg_type.h"
2119
#include "utils/lsyscache.h"
@@ -166,6 +164,77 @@ get_atttypmod(Oid relid, AttrNumber attnum)
166164
return -1;
167165
}
168166

167+
/*
168+
* get_attdisbursion
169+
*
170+
* Retrieve the disbursion statistic for an attribute,
171+
* or produce an estimate if no info is available.
172+
*
173+
* min_estimate is the minimum estimate to return if insufficient data
174+
* is available to produce a reliable value. This value may vary
175+
* depending on context. (For example, when deciding whether it is
176+
* safe to use a hashjoin, we want to be more conservative than when
177+
* estimating the number of tuples produced by an equijoin.)
178+
*/
179+
double
180+
get_attdisbursion(Oid relid, AttrNumber attnum, double min_estimate)
181+
{
182+
HeapTuple atp;
183+
double disbursion;
184+
int32 ntuples;
185+
186+
atp = SearchSysCacheTuple(ATTNUM,
187+
ObjectIdGetDatum(relid),
188+
Int16GetDatum(attnum),
189+
0, 0);
190+
if (!HeapTupleIsValid(atp))
191+
{
192+
/* this should not happen */
193+
elog(ERROR, "get_attdisbursion: no attribute tuple %u %d",
194+
relid, attnum);
195+
return min_estimate;
196+
}
197+
198+
disbursion = ((Form_pg_attribute) GETSTRUCT(atp))->attdisbursion;
199+
if (disbursion > 0.0)
200+
return disbursion; /* we have a specific estimate */
201+
202+
/*
203+
* Disbursion is either 0 (no data available) or -1 (disbursion
204+
* is 1/numtuples). Either way, we need the relation size.
205+
*/
206+
207+
atp = SearchSysCacheTuple(RELOID,
208+
ObjectIdGetDatum(relid),
209+
0, 0, 0);
210+
if (!HeapTupleIsValid(atp))
211+
{
212+
/* this should not happen */
213+
elog(ERROR, "get_attdisbursion: no relation tuple %u", relid);
214+
return min_estimate;
215+
}
216+
217+
ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
218+
219+
if (ntuples == 0)
220+
return min_estimate; /* no data available */
221+
222+
if (disbursion < 0.0) /* VACUUM thinks there are no duplicates */
223+
return 1.0 / (double) ntuples;
224+
225+
/*
226+
* VACUUM ANALYZE has not been run for this table.
227+
* Produce an estimate = 1/numtuples. This may produce
228+
* unreasonably small estimates for large tables, so limit
229+
* the estimate to no less than min_estimate.
230+
*/
231+
disbursion = 1.0 / (double) ntuples;
232+
if (disbursion < min_estimate)
233+
disbursion = min_estimate;
234+
235+
return disbursion;
236+
}
237+
169238
/* ---------- INDEX CACHE ---------- */
170239

171240
/* watch this space...
@@ -504,15 +573,110 @@ get_typalign(Oid typid)
504573
/*
505574
* get_typdefault -
506575
*
507-
* Given the type OID, return the default value of the ADT.
508-
*
576+
* Given a type OID, return the typdefault field associated with that
577+
* type, or Datum(NULL) if there is no typdefault. (This implies
578+
* that pass-by-value types can't have a default value that has
579+
* a representation of zero. Not worth fixing now.)
580+
* The result points to palloc'd storage for non-pass-by-value types.
509581
*/
510-
struct varlena *
582+
Datum
511583
get_typdefault(Oid typid)
512584
{
513-
struct varlena *typdefault = (struct varlena *) TypeDefaultRetrieve(typid);
585+
struct varlena *typDefault;
586+
int32 dataSize;
587+
HeapTuple typeTuple;
588+
Form_pg_type type;
589+
int32 typLen;
590+
bool typByVal;
591+
Datum returnValue;
592+
593+
/*
594+
* First, see if there is a non-null typdefault field (usually there isn't)
595+
*/
596+
typDefault = (struct varlena *)
597+
SearchSysCacheGetAttribute(TYPOID,
598+
Anum_pg_type_typdefault,
599+
ObjectIdGetDatum(typid),
600+
0, 0, 0);
601+
602+
if (typDefault == NULL)
603+
return PointerGetDatum(NULL);
604+
605+
dataSize = VARSIZE(typDefault) - VARHDRSZ;
606+
607+
/*
608+
* Need the type's length and byVal fields.
609+
*
610+
* XXX silly to repeat the syscache search that SearchSysCacheGetAttribute
611+
* just did --- but at present this path isn't taken often enough to
612+
* make it worth fixing.
613+
*/
614+
typeTuple = SearchSysCacheTuple(TYPOID,
615+
ObjectIdGetDatum(typid),
616+
0, 0, 0);
617+
618+
if (!HeapTupleIsValid(typeTuple))
619+
elog(ERROR, "get_typdefault: failed to lookup type %u", typid);
620+
621+
type = (Form_pg_type) GETSTRUCT(typeTuple);
622+
typLen = type->typlen;
623+
typByVal = type->typbyval;
624+
625+
if (typByVal)
626+
{
627+
int8 i8;
628+
int16 i16;
629+
int32 i32 = 0;
630+
631+
if (dataSize == typLen)
632+
{
633+
switch (typLen)
634+
{
635+
case sizeof(int8):
636+
memcpy((char *) &i8, VARDATA(typDefault), sizeof(int8));
637+
i32 = i8;
638+
break;
639+
case sizeof(int16):
640+
memcpy((char *) &i16, VARDATA(typDefault), sizeof(int16));
641+
i32 = i16;
642+
break;
643+
case sizeof(int32):
644+
memcpy((char *) &i32, VARDATA(typDefault), sizeof(int32));
645+
break;
646+
}
647+
returnValue = Int32GetDatum(i32);
648+
}
649+
else
650+
returnValue = PointerGetDatum(NULL);
651+
}
652+
else if (typLen < 0)
653+
{
654+
/* variable-size type */
655+
if (dataSize < 0)
656+
returnValue = PointerGetDatum(NULL);
657+
else
658+
{
659+
returnValue = PointerGetDatum(palloc(VARSIZE(typDefault)));
660+
memcpy((char *) DatumGetPointer(returnValue),
661+
(char *) typDefault,
662+
(int) VARSIZE(typDefault));
663+
}
664+
}
665+
else
666+
{
667+
/* fixed-size pass-by-ref type */
668+
if (dataSize != typLen)
669+
returnValue = PointerGetDatum(NULL);
670+
else
671+
{
672+
returnValue = PointerGetDatum(palloc(dataSize));
673+
memcpy((char *) DatumGetPointer(returnValue),
674+
VARDATA(typDefault),
675+
(int) dataSize);
676+
}
677+
}
514678

515-
return typdefault;
679+
return returnValue;
516680
}
517681

518682
/*

src/backend/utils/cache/syscache.c

Lines changed: 1 addition & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.33 1999/07/20 17:14:06 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.34 1999/08/09 03:13:30 tgl Exp $
1111
*
1212
* NOTES
1313
* These routines allow the parser/planner/executor to perform
@@ -631,112 +631,3 @@ SearchSysCacheGetAttribute(int cacheId,
631631
heap_close(relation);
632632
return returnValue;
633633
}
634-
635-
/*
636-
* TypeDefaultRetrieve
637-
*
638-
* Given a type OID, return the typdefault field associated with that
639-
* type. The result is a Datum, and points to palloc'd storage for
640-
* non-pass-by-value types.
641-
*
642-
* [identical to get_typdefault, expecting a (struct varlena *) as ret val.
643-
* some day, either of the functions should be removed -ay 10/94]
644-
*/
645-
void *
646-
TypeDefaultRetrieve(Oid typId)
647-
{
648-
struct varlena *typDefault;
649-
int32 dataSize;
650-
HeapTuple typeTuple;
651-
Form_pg_type type;
652-
int32 typByVal,
653-
typLen;
654-
void *returnValue;
655-
656-
/*
657-
* First, see if there is a non-null typdefault field (usually there isn't)
658-
*/
659-
typDefault = (struct varlena *)
660-
SearchSysCacheGetAttribute(TYPOID,
661-
Anum_pg_type_typdefault,
662-
ObjectIdGetDatum(typId),
663-
0, 0, 0);
664-
665-
if (typDefault == NULL)
666-
{
667-
#ifdef CACHEDEBUG
668-
elog(DEBUG, "TypeDefaultRetrieve: No extractable typdefault in %s(%d)",
669-
cacheinfo[TYPOID].name, TYPOID);
670-
#endif /* defined(CACHEDEBUG) */
671-
return NULL;
672-
}
673-
674-
dataSize = VARSIZE(typDefault) - VARHDRSZ;
675-
676-
/*
677-
* Need the type's length and byVal fields.
678-
*
679-
* XXX silly to repeat the syscache search that SearchSysCacheGetAttribute
680-
* just did --- but at present this path isn't taken often enough to
681-
* make it worth fixing.
682-
*/
683-
typeTuple = SearchSysCacheTuple(TYPOID,
684-
ObjectIdGetDatum(typId),
685-
0, 0, 0);
686-
687-
if (!HeapTupleIsValid(typeTuple))
688-
{
689-
/* should never get here, really... */
690-
#ifdef CACHEDEBUG
691-
elog(DEBUG, "TypeDefaultRetrieve: Lookup in %s(%d) failed",
692-
cacheinfo[TYPOID].name, TYPOID);
693-
#endif /* defined(CACHEDEBUG) */
694-
return NULL;
695-
}
696-
697-
type = (Form_pg_type) GETSTRUCT(typeTuple);
698-
typLen = type->typlen;
699-
typByVal = type->typbyval;
700-
701-
if (typByVal)
702-
{
703-
int8 i8;
704-
int16 i16;
705-
int32 i32 = 0;
706-
707-
if (dataSize == typLen)
708-
{
709-
switch (typLen)
710-
{
711-
case sizeof(int8):
712-
memcpy((char *) &i8, VARDATA(typDefault), sizeof(int8));
713-
i32 = i8;
714-
break;
715-
case sizeof(int16):
716-
memcpy((char *) &i16, VARDATA(typDefault), sizeof(int16));
717-
i32 = i16;
718-
break;
719-
case sizeof(int32):
720-
memcpy((char *) &i32, VARDATA(typDefault), sizeof(int32));
721-
break;
722-
}
723-
returnValue = (void *) i32;
724-
}
725-
else
726-
returnValue = NULL;
727-
}
728-
else
729-
{
730-
if ((typLen < 0 && dataSize < 0) || dataSize != typLen)
731-
returnValue = NULL;
732-
else
733-
{
734-
returnValue = (void *) palloc(VARSIZE(typDefault));
735-
memcpy((char *) returnValue,
736-
(char *) typDefault,
737-
(int) VARSIZE(typDefault));
738-
}
739-
}
740-
741-
return returnValue;
742-
}

0 commit comments

Comments
 (0)