@@ -263,43 +263,36 @@ impl<S: CostModelStorageLayer> CostModelImpl<S> {
263263 is_eq : bool ,
264264 ) -> CostModelResult < f64 > {
265265 // TODO: The attribute could be a derived attribute
266- todo ! ( )
267- // let ret_sel = if let Some(attribute_stats) =
268- // self.get_attribute_comb_stats(table_id, &[attr_base_index])
269- // {
270- // let eq_freq = if let Some(freq) = attribute_stats.mcvs.freq(&vec![Some(value.clone())]) {
271- // freq
272- // } else {
273- // let non_mcv_freq = 1.0 - attribute_stats.mcvs.total_freq();
274- // // always safe because usize is at least as large as i32
275- // let ndistinct_as_usize = attribute_stats.ndistinct as usize;
276- // let non_mcv_cnt = ndistinct_as_usize - attribute_stats.mcvs.cnt();
277- // if non_mcv_cnt == 0 {
278- // return 0.0;
279- // }
280- // // note that nulls are not included in ndistinct so we don't need to do non_mcv_cnt
281- // // - 1 if null_frac > 0
282- // (non_mcv_freq - attribute_stats.null_frac) / (non_mcv_cnt as f64)
283- // };
284- // if is_eq {
285- // eq_freq
286- // } else {
287- // 1.0 - eq_freq - attribute_stats.null_frac
288- // }
289- // } else {
290- // #[allow(clippy::collapsible_else_if)]
291- // if is_eq {
292- // DEFAULT_EQ_SEL
293- // } else {
294- // 1.0 - DEFAULT_EQ_SEL
295- // }
296- // };
297- // assert!(
298- // (0.0..=1.0).contains(&ret_sel),
299- // "ret_sel ({}) should be in [0, 1]",
300- // ret_sel
301- // );
302- // ret_sel
266+ let ret_sel = {
267+ let attribute_stats = self . get_attribute_comb_stats ( table_id, & [ attr_base_index] ) ?;
268+ let eq_freq = if let Some ( freq) = attribute_stats. mcvs . freq ( & vec ! [ Some ( value. clone( ) ) ] )
269+ {
270+ freq
271+ } else {
272+ let non_mcv_freq = 1.0 - attribute_stats. mcvs . total_freq ( ) ;
273+ // always safe because usize is at least as large as i32
274+ let ndistinct_as_usize = attribute_stats. ndistinct as usize ;
275+ let non_mcv_cnt = ndistinct_as_usize - attribute_stats. mcvs . cnt ( ) ;
276+ if non_mcv_cnt == 0 {
277+ return Ok ( 0.0 ) ;
278+ }
279+ // note that nulls are not included in ndistinct so we don't need to do non_mcv_cnt
280+ // - 1 if null_frac > 0
281+ ( non_mcv_freq - attribute_stats. null_frac ) / ( non_mcv_cnt as f64 )
282+ } ;
283+ if is_eq {
284+ eq_freq
285+ } else {
286+ 1.0 - eq_freq - attribute_stats. null_frac
287+ }
288+ } ;
289+
290+ assert ! (
291+ ( 0.0 ..=1.0 ) . contains( & ret_sel) ,
292+ "ret_sel ({}) should be in [0, 1]" ,
293+ ret_sel
294+ ) ;
295+ Ok ( ret_sel)
303296 }
304297
305298 /// Get the selectivity of an expression of the form "attribute </<=/>=/> value" (or "value
@@ -315,33 +308,33 @@ impl<S: CostModelStorageLayer> CostModelImpl<S> {
315308 end : Bound < & Value > ,
316309 ) -> CostModelResult < f64 > {
317310 // TODO: Consider attribute is a derived attribute
311+ let attribute_stats = self . get_attribute_comb_stats ( table_id, & [ attr_base_index] ) ?;
318312 todo ! ( )
319- // if let Some(attribute_stats) = self.get_attribute_comb_stats(table, &[attr_idx]) {
320- // // Left and right quantile contain both Distribution and MCVs.
321- // let left_quantile = match start {
322- // Bound::Unbounded => 0.0,
323- // Bound::Included(value) => {
324- // self.get_attribute_lt_value_freq(attribute_stats, table, attr_idx, value)
325- // }
326- // Bound::Excluded(value) => Self::get_attribute_leq_value_freq(attribute_stats, value),
327- // };
328- // let right_quantile = match end {
329- // Bound::Unbounded => 1.0,
330- // Bound::Included(value) => Self::get_attribute_leq_value_freq(attribute_stats, value),
331- // Bound::Excluded(value) => {
332- // self.get_attribute_lt_value_freq(attribute_stats, table, attr_idx, value)
333- // }
334- // };
335- // assert!(
336- // left_quantile <= right_quantile,
337- // "left_quantile ({}) should be <= right_quantile ({})",
338- // left_quantile,
339- // right_quantile
340- // );
341- // right_quantile - left_quantile
342- // } else {
343- // DEFAULT_INEQ_SEL
344- // }
313+ // let left_quantile = match start {
314+ // Bound::Unbounded => 0.0,
315+ // Bound::Included(value) => {
316+ // self.get_attribute_lt_value_freq(attribute_stats, table, attr_idx, value)
317+ // }
318+ // Bound::Excluded(value) => {
319+ // Self::get_attribute_leq_value_freq(attribute_stats, value)
320+ // }
321+ // };
322+ // let right_quantile = match end {
323+ // Bound::Unbounded => 1.0,
324+ // Bound::Included(value) => {
325+ // Self::get_attribute_leq_value_freq(attribute_stats, value)
326+ // }
327+ // Bound::Excluded(value) => {
328+ // self.get_attribute_lt_value_freq(attribute_stats, table, attr_idx, value)
329+ // }
330+ // };
331+ // assert!(
332+ // left_quantile <= right_quantile,
333+ // "left_quantile ({}) should be <= right_quantile ({})",
334+ // left_quantile,
335+ // right_quantile
336+ // );
337+ // right_quantile - left_quantile
345338 }
346339
347340 /// Compute the selectivity of a (NOT) LIKE expression.
0 commit comments