77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.115 1999/07/19 07:07:20 momjian Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.116 1999/08/01 04:54:24 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -78,7 +78,7 @@ static void vc_vacpage(Page page, VPageDescr vpd);
7878static void vc_vaconeind (VPageList vpl ,Relation indrel ,int num_tuples ,int keep_tuples );
7979static void vc_scanoneind (Relation indrel ,int num_tuples );
8080static void vc_attrstats (Relation onerel ,VRelStats * vacrelstats ,HeapTuple tuple );
81- static void vc_bucketcpy (Form_pg_attribute attr ,Datum value ,Datum * bucket ,int16 * bucket_len );
81+ static void vc_bucketcpy (Form_pg_attribute attr ,Datum value ,Datum * bucket ,int * bucket_len );
8282static void vc_updstats (Oid relid ,int num_pages ,int num_tuples ,bool hasindex ,VRelStats * vacrelstats );
8383static void vc_delhilowstats (Oid relid ,int attcnt ,int * attnums );
8484static VPageDescr vc_tidreapped (ItemPointer itemptr ,VPageList vpl );
@@ -473,9 +473,13 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
473473{
474474pgopform = (Form_pg_operator )GETSTRUCT (func_operator );
475475fmgr_info (pgopform -> oprcode ,& (stats -> f_cmplt ));
476+ stats -> op_cmplt = oprid (func_operator );
476477}
477478else
479+ {
478480stats -> f_cmplt .fn_addr = NULL ;
481+ stats -> op_cmplt = InvalidOid ;
482+ }
479483
480484func_operator = oper (">" ,stats -> attr -> atttypid ,stats -> attr -> atttypid , true);
481485if (func_operator != NULL )
@@ -2200,8 +2204,8 @@ vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple tuple)
22002204{
22012205swapDatum (stats -> guess1 ,stats -> guess2 );
22022206swapInt (stats -> guess1_len ,stats -> guess2_len );
2203- stats -> guess1_cnt = stats -> guess2_hits ;
22042207swapLong (stats -> guess1_hits ,stats -> guess2_hits );
2208+ stats -> guess1_cnt = stats -> guess1_hits ;
22052209}
22062210if (stats -> guess1_cnt > stats -> best_cnt )
22072211{
@@ -2227,7 +2231,7 @@ vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple tuple)
22272231 *
22282232 */
22292233static void
2230- vc_bucketcpy (Form_pg_attribute attr ,Datum value ,Datum * bucket ,int16 * bucket_len )
2234+ vc_bucketcpy (Form_pg_attribute attr ,Datum value ,Datum * bucket ,int * bucket_len )
22312235{
22322236if (attr -> attbyval && attr -> attlen != -1 )
22332237* bucket = value ;
@@ -2340,13 +2344,14 @@ vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *
23402344selratio = 0 ;
23412345else if (VacAttrStatsLtGtValid (stats )&& stats -> min_cnt + stats -> max_cnt == stats -> nonnull_cnt )
23422346{
2347+ /* exact result when there are just 1 or 2 values... */
23432348double min_cnt_d = stats -> min_cnt ,
23442349max_cnt_d = stats -> max_cnt ,
23452350null_cnt_d = stats -> null_cnt ,
2346- nonnullcnt_d = stats -> nonnull_cnt ;/* prevent overflow */
2351+ nonnull_cnt_d = stats -> nonnull_cnt ;/* prevent overflow */
23472352
23482353selratio = (min_cnt_d * min_cnt_d + max_cnt_d * max_cnt_d + null_cnt_d * null_cnt_d ) /
2349- (nonnullcnt_d + null_cnt_d ) / (nonnullcnt_d + null_cnt_d );
2354+ (nonnull_cnt_d + null_cnt_d ) / (nonnull_cnt_d + null_cnt_d );
23502355}
23512356else
23522357{
@@ -2359,7 +2364,9 @@ vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *
23592364 */
23602365selratio = (most * most + 0.20 * most * (total - most )) /total /total ;
23612366}
2362- if (selratio > 1.0 )
2367+ if (selratio < 0.0 )
2368+ selratio = 0.0 ;
2369+ else if (selratio > 1.0 )
23632370selratio = 1.0 ;
23642371attp -> attdisbursion = selratio ;
23652372
@@ -2375,13 +2382,22 @@ vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *
23752382 * doing system relations, especially pg_statistic is a
23762383 * problem
23772384 */
2378- if (VacAttrStatsLtGtValid (stats )&& stats -> initialized /* &&
2379- * !IsSystemRelationName(
2380- *
2381- pgcform->relname.data) */ )
2385+ if (VacAttrStatsLtGtValid (stats )&& stats -> initialized
2386+ /* && !IsSystemRelationName(pgcform->relname.data)
2387+ */ )
23822388{
2389+ float32data nullratio ;
2390+ float32data bestratio ;
23832391FmgrInfo out_function ;
23842392char * out_string ;
2393+ double best_cnt_d = stats -> best_cnt ,
2394+ null_cnt_d = stats -> null_cnt ,
2395+ nonnull_cnt_d = stats -> nonnull_cnt ;/* prevent overflow */
2396+
2397+ nullratio = null_cnt_d / (nonnull_cnt_d + null_cnt_d );
2398+ bestratio = best_cnt_d / (nonnull_cnt_d + null_cnt_d );
2399+
2400+ fmgr_info (stats -> outfunc ,& out_function );
23852401
23862402for (i = 0 ;i < Natts_pg_statistic ;++ i )
23872403nulls [i ]= ' ' ;
@@ -2391,26 +2407,34 @@ vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *
23912407 * ----------------
23922408 */
23932409i = 0 ;
2394- values [i ++ ]= (Datum )relid ;/* 1 */
2395- values [i ++ ]= (Datum )attp -> attnum ;/* 2 */
2396- values [i ++ ]= (Datum )InvalidOid ;/* 3 */
2397- fmgr_info (stats -> outfunc ,& out_function );
2398- out_string = (* fmgr_faddr (& out_function )) (stats -> min ,stats -> attr -> atttypid );
2399- values [i ++ ]= (Datum )fmgr (F_TEXTIN ,out_string );
2410+ values [i ++ ]= (Datum )relid ;/* starelid */
2411+ values [i ++ ]= (Datum )attp -> attnum ;/* staattnum */
2412+ values [i ++ ]= (Datum )stats -> op_cmplt ;/* staop */
2413+ /* hack: this code knows float4 is pass-by-ref */
2414+ values [i ++ ]= PointerGetDatum (& nullratio );/* stanullfrac */
2415+ values [i ++ ]= PointerGetDatum (& bestratio );/* stacommonfrac */
2416+ out_string = (* fmgr_faddr (& out_function )) (stats -> best ,stats -> attr -> atttypid ,stats -> attr -> atttypmod );
2417+ values [i ++ ]= PointerGetDatum (textin (out_string ));/* stacommonval */
24002418pfree (out_string );
2401- out_string = (char * ) (* fmgr_faddr (& out_function )) (stats -> max ,stats -> attr -> atttypid );
2402- values [i ++ ]= (Datum )fmgr (F_TEXTIN ,out_string );
2419+ out_string = (* fmgr_faddr (& out_function )) (stats -> min ,stats -> attr -> atttypid ,stats -> attr -> atttypmod );
2420+ values [i ++ ]= PointerGetDatum (textin (out_string ));/* staloval */
2421+ pfree (out_string );
2422+ out_string = (char * ) (* fmgr_faddr (& out_function )) (stats -> max ,stats -> attr -> atttypid ,stats -> attr -> atttypmod );
2423+ values [i ++ ]= PointerGetDatum (textin (out_string ));/* stahival */
24032424pfree (out_string );
24042425
24052426stup = heap_formtuple (sd -> rd_att ,values ,nulls );
24062427
24072428/* ----------------
2408- *insert the tuple in the relation and get the tuple's oid .
2429+ *insert the tuple in the relation.
24092430 * ----------------
24102431 */
24112432heap_insert (sd ,stup );
2412- pfree (DatumGetPointer (values [3 ]));
2413- pfree (DatumGetPointer (values [4 ]));
2433+
2434+ /* release allocated space */
2435+ pfree (DatumGetPointer (values [Anum_pg_statistic_stacommonval - 1 ]));
2436+ pfree (DatumGetPointer (values [Anum_pg_statistic_staloval - 1 ]));
2437+ pfree (DatumGetPointer (values [Anum_pg_statistic_stahival - 1 ]));
24142438pfree (stup );
24152439}
24162440}