← Back to team overview

maria-developers team mailing list archive

Re: [GSoC] self-tuning optimizer

 

Hi, Anshu!

Please, see the attached patch.
It introduces a macro top_level_cond_is_satisfied() that now marks all
places where a comparison (in the TIME_FOR_COMPARE sense) is done.

So, all you need to do is to convert this macro into an (inline) function
and increment your counter from there.

As for TIME_FOR_COMPARE_ROWID, it's simpler. There's handler::cmp_ref(),
a virtual handler method. Create handler::ha_cmp_ref(), non-virtual
inline public method (make cmp_ref() protected, as usual). And increment your
counter from ha_cmp_ref().

By the way, before you start writing the code to solve our equations,
please write an email, explaining how you're going to solve them, that
is, what method you'll be using. There are lots of them. Some are
faster, some are slower. Some work better with sparse matrices (and ours
will be very much sparse).

Regards,
Sergei

diff --git a/sql/item.h b/sql/item.h
index 29e727b..6c3c820 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -33,6 +33,8 @@ C_MODE_START
 #include <ma_dyncol.h>
 C_MODE_END
 
+#define top_level_cond_is_satisfied(X)    (!(X) || (X)->val_int())
+
 static inline
 bool trace_unsupported_func(const char *where, const char *processor_name)
 {
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 38bb312..a892ee8 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -3769,7 +3769,7 @@ int subselect_uniquesubquery_engine::scan_table()
       }
     }
 
-    if (!cond || cond->val_int())
+    if (top_level_cond_is_satisfied(cond))
     {
       empty_result_set= FALSE;
       break;
@@ -3899,7 +3899,7 @@ int subselect_uniquesubquery_engine::exec()
   {
     error= 0;
     table->null_row= 0;
-    if (!table->status && (!cond || cond->val_int()))
+    if (!table->status && top_level_cond_is_satisfied(cond))
     {
       ((Item_in_subselect *) item)->value= 1;
       empty_result_set= FALSE;
@@ -3942,7 +3942,7 @@ int subselect_uniquesubquery_engine::index_lookup()
   }
 
   table->null_row= 0;
-  if (!error && (!cond || cond->val_int()))
+  if (!error && (top_level_cond_is_satisfied(cond)))
     ((Item_in_subselect *) item)->value= 1;
   else
     ((Item_in_subselect *) item)->value= 0;
@@ -4073,7 +4073,7 @@ int subselect_indexsubquery_engine::exec()
       table->null_row= 0;
       if (!table->status)
       {
-        if ((!cond || cond->val_int()) && (!having || having->val_int()))
+        if (top_level_cond_is_satisfied(cond) && top_level_cond_is_satisfied(having))
         {
           empty_result_set= FALSE;
           if (null_finding)
@@ -6505,7 +6505,7 @@ bool subselect_table_scan_engine::partial_match()
     {
       DBUG_ASSERT(cur_eq->type() == Item::FUNC_ITEM &&
                   ((Item_func*)cur_eq)->functype() == Item_func::EQ_FUNC);
-      if (!cur_eq->val_int() && !cur_eq->null_value)
+      if (!top_level_cond_is_satisfied(cur_eq) && !cur_eq->null_value)
         break;
       ++count_matches;
     }
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 1ca245e..8b14c02 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -1004,7 +1004,7 @@ class SQL_SELECT :public Sql_alloc {
   */   
   inline int skip_record(THD *thd)
   {
-    int rc= MY_TEST(!cond || cond->val_int());
+    int rc= top_level_cond_is_satisfied(cond);
     if (thd->is_error())
       rc= -1;
     return rc;
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index cab9628..a7f45ca 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -1492,7 +1492,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
   { 
     join_tab->found= 0;
     join_tab->not_null_compl= 1;
-    if (!join_tab->on_precond->val_int())
+    if (!top_level_cond_is_satisfied(join_tab->on_precond))
     {
       flags_pos[0]= MATCH_IMPOSSIBLE;     
       last_written_is_null_compl= 1;
@@ -4396,7 +4396,7 @@ bool JOIN_CACHE_BKA::skip_index_tuple(range_id_t range_info)
 {
 DBUG_ENTER("JOIN_CACHE_BKA::skip_index_tuple");
 get_record_by_pos((uchar*)range_info);
-DBUG_RETURN(!join_tab->cache_idx_cond->val_int());
+DBUG_RETURN(!top_level_cond_is_satisfied(join_tab->cache_idx_cond));
 }
 
 
@@ -4661,7 +4661,7 @@ bool JOIN_CACHE_BKAH::skip_index_tuple(range_id_t range_info)
     next_rec_ref_ptr= get_next_rec_ref(next_rec_ref_ptr);
     uchar *rec_ptr= next_rec_ref_ptr + rec_fields_offset;
     get_record_by_pos(rec_ptr);
-    if (join_tab->cache_idx_cond->val_int())
+    if (top_level_cond_is_satisfied(join_tab->cache_idx_cond))
       DBUG_RETURN(FALSE);
   } while(next_rec_ref_ptr != last_rec_ref_ptr);
   DBUG_RETURN(TRUE);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2e4227e..67d2f60 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2444,8 +2444,8 @@ void JOIN::exec_inner()
       DBUG_ASSERT(error == 0);
       if (cond_value != Item::COND_FALSE &&
           having_value != Item::COND_FALSE &&
-          (!conds || conds->val_int()) &&
-          (!having || having->val_int()))
+          top_level_cond_is_satisfied(conds) &&
+          top_level_cond_is_satisfied(having))
       {
 	if (do_send_rows &&
             (procedure ? (procedure->send_row(procedure_fields_list) ||
@@ -2482,8 +2482,8 @@ void JOIN::exec_inner()
     condtions may be arbitrarily costly, and because the optimize phase
     might not have produced a complete executable plan for EXPLAINs.
   */
-  if (exec_const_cond && !(select_options & SELECT_DESCRIBE) &&
-      !exec_const_cond->val_int())
+  if (!(select_options & SELECT_DESCRIBE) &&
+      !top_level_cond_is_satisfied(exec_const_cond))
     zero_result_cause= "Impossible WHERE noticed after reading const tables";
 
   /* 
@@ -9332,7 +9332,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
         DBUG_EXECUTE("where",print_where(join->exec_const_cond,"constants",
 					 QT_ORDINARY););
         if (join->exec_const_cond && !join->exec_const_cond->is_expensive() &&
-            !join->exec_const_cond->val_int())
+            !top_level_cond_is_satisfied(join->exec_const_cond))
         {
           DBUG_PRINT("info",("Found impossible WHERE condition"));
           join->exec_const_cond= NULL;
@@ -12048,7 +12048,7 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
     */
     while ((item= it++))
       item->no_rows_in_result();
-    if (having && having->val_int() == 0)
+    if (!top_level_cond_is_satisfied(having))
       send_row=0;
   }
   if (!(result->send_result_set_metadata(fields,
@@ -17206,7 +17206,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
       sufficient to check only the condition pseudo_bits_cond.
     */
     DBUG_ASSERT(join->outer_ref_cond == NULL);
-    if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int())
+    if (top_level_cond_is_satisfied(join->pseudo_bits_cond))
     {
       error= (*end_select)(join, 0, 0);
       if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT)
@@ -17222,7 +17222,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
     }
     else if (join->send_row_on_empty_set())
     {
-      if (!join->having || join->having->val_int())
+      if (top_level_cond_is_satisfied(join->having))
       {
         List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
                                    fields);
@@ -17248,7 +17248,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
                           dbug_serve_apcs(join->thd, 1);
                    );
 
-    if (join->outer_ref_cond && !join->outer_ref_cond->val_int())
+    if (!top_level_cond_is_satisfied(join->outer_ref_cond))
       error= NESTED_LOOP_NO_MORE_ROWS;
     else
       error= sub_select(join,join_tab,0);
@@ -17572,7 +17572,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
 
     /* Set first_unmatched for the last inner table of this group */
     join_tab->last_inner->first_unmatched= join_tab;
-    if (join_tab->on_precond && !join_tab->on_precond->val_int())
+    if (!top_level_cond_is_satisfied(join_tab->on_precond))
       rc= NESTED_LOOP_NO_MORE_ROWS;
   }
   join->thd->get_stmt_da()->reset_current_row_for_warning();
@@ -17686,7 +17686,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
 
   if (select_cond)
   {
-    select_cond_result= MY_TEST(select_cond->val_int());
+    select_cond_result= top_level_cond_is_satisfied(select_cond);
 
     /* check for errors evaluating the condition */
     if (join->thd->is_error())
@@ -17734,7 +17734,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
         DBUG_ASSERT(!(tab->table->reginfo.not_exists_optimize &&
                      !tab->select_cond));
 
-        if (tab->select_cond && !tab->select_cond->val_int())
+        if (!top_level_cond_is_satisfied(tab->select_cond))
         {
           /* The condition attached to table tab is false */
 
@@ -17875,7 +17875,7 @@ evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
     mark_as_null_row(join_tab->table);       // For group by without error
     select_cond= join_tab->select_cond;
     /* Check all attached conditions for inner table rows. */
-    if (select_cond && !select_cond->val_int())
+    if (!top_level_cond_is_satisfied(select_cond))
       return NESTED_LOOP_OK;
   }
   join_tab--;
@@ -17897,7 +17897,7 @@ evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
     first_unmatched->found= 1;
     for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
     {
-      if (tab->select_cond && !tab->select_cond->val_int())
+      if (!top_level_cond_is_satisfied(tab->select_cond))
       {
         join->return_tab= tab;
         return NESTED_LOOP_OK;
@@ -18071,7 +18071,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
     (*tab->on_expr_ref)->update_used_tables();
     DBUG_ASSERT((*tab->on_expr_ref)->const_item());
 #endif
-    if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_int() == 0)))
+    if ((table->null_row= !top_level_cond_is_satisfied(*tab->on_expr_ref)))
       mark_as_null_row(table);  
   }
   if (!table->null_row)
@@ -18691,7 +18691,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
       /* Copy non-aggregated fields when loose index scan is used. */
       copy_fields(&join->tmp_table_param);
     }
-    if (join->having && join->having->val_int() == 0)
+    if (!top_level_cond_is_satisfied(join->having))
       DBUG_RETURN(NESTED_LOOP_OK);               // Didn't match having
     if (join->procedure)
     {
@@ -18800,7 +18800,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 	int error=0;
 	if (join->procedure)
 	{
-	  if (join->having && join->having->val_int() == 0)
+	  if (!top_level_cond_is_satisfied(join->having))
 	    error= -1;				// Didn't satisfy having
  	  else
 	  {
@@ -18826,7 +18826,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
             while ((item= it++))
               item->no_rows_in_result();
 	  }
-	  if (join->having && join->having->val_int() == 0)
+	  if (!top_level_cond_is_satisfied(join->having))
 	    error= -1;				// Didn't satisfy having
 	  else
 	  {
@@ -18917,7 +18917,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
     if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
       DBUG_RETURN(NESTED_LOOP_ERROR);           /* purecov: inspected */
 
-    if (!join->having || join->having->val_int())
+    if (top_level_cond_is_satisfied(join->having))
     {
       int error;
       join->found_records++;
@@ -19111,7 +19111,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 	}
         copy_sum_funcs(join->sum_funcs,
                        join->sum_funcs_end[send_group_parts]);
-	if (!join->having || join->having->val_int())
+	if (top_level_cond_is_satisfied(join->having))
 	{
           int error= table->file->ha_write_tmp_row(table->record[0]);
           if (error && 
@@ -20755,7 +20755,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
 	break;
       goto err;
     }
-    if (having && !having->val_int())
+    if (!top_level_cond_is_satisfied(having))
     {
       if ((error= file->ha_delete_row(record)))
 	goto err;
@@ -20873,7 +20873,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
 	break;
       goto err;
     }
-    if (having && !having->val_int())
+    if (!top_level_cond_is_satisfied(having))
     {
       if ((error= file->ha_delete_row(record)))
 	goto err;
@@ -22836,7 +22836,7 @@ int JOIN::rollup_send_data(uint idx)
     memcpy((char*) ref_pointer_array,
 	   (char*) rollup.ref_pointer_arrays[i],
 	   ref_pointer_array_size);
-    if ((!having || having->val_int()))
+    if ((top_level_cond_is_satisfied(having)))
     {
       if (send_records < unit->select_limit_cnt && do_send_rows &&
 	  (res= result->send_data(rollup.fields[i])) > 0)
@@ -22879,7 +22879,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
     memcpy((char*) ref_pointer_array,
 	   (char*) rollup.ref_pointer_arrays[i],
 	   ref_pointer_array_size);
-    if ((!having || having->val_int()))
+    if (top_level_cond_is_satisfied(having))
     {
       int write_error;
       Item *item;

Follow ups

References