~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Jay Pipes
  • Date: 2009-02-11 21:38:28 UTC
  • mto: This revision was merged to the branch mainline in revision 881.
  • Revision ID: jpipes@serialcoder-20090211213828-zpiv58fdoz3ryybs
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
date time numbers are passed through.

This fix illuminated a bug in the optimizer, where the following:

CREATE TABLE t1 (d datetime NOT NULL);
SELECT * FROM t1 WHERE d IS NULL;

was producing an incorrect query plan.  The reason is because the optimizer
was incorrectly reducing an Item_func_isnull to an Item_int with a value of
0.  In MySQL, the optimizer compares datetimes as integers, and *just in the
optimizer*, ignores bad datetimes so that it can do this comparison.  Unfortunately
for MySQL, what this means is that the optimizer cannot optimize away the 
above IS NULL condition because it converts the NULL to a 0000-00-00 00:00:00.

Drizzle's optimizer now shows an impossible WHERE reduction in the explain
output for the above query, which is optimal.

Also fixed an assert that was occurring in mysql_alter_table because that
function called fix_fields() which ignores data truncation errors improperly and
mysql_alter_table ignores the errors as well, which led to an assertion failure
in Diagnostics_area::send_ok_status() because mysql_alter_table() assumes
that all errors would be logged as only warnings from Field::store().

Also contained in this patch is corrections for invalid numeric datetime input
for all test cases affected.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4865
4865
    if (end_active_trans(session))
4866
4866
      error= 1;
4867
4867
  }
4868
 
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
 
4868
  /* We must not ignore bad input! */;
 
4869
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
4869
4870
 
4870
4871
  if (table->s->tmp_table != NO_TMP_TABLE)
4871
4872
  {
5023
5024
  }
5024
5025
 
5025
5026
end_temporary:
5026
 
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5027
 
           (ulong) (copied + deleted), (ulong) deleted,
5028
 
           (ulong) session->cuted_fields);
5029
 
  session->my_ok(copied + deleted, 0L, tmp_name);
5030
 
  session->some_tables_deleted=0;
5031
 
  return(false);
 
5027
  /*
 
5028
   * Field::store() may have called my_error().  If this is 
 
5029
   * the case, we must not send an ok packet, since 
 
5030
   * Diagnostics_area::is_set() will fail an assert.
 
5031
   */
 
5032
  if (! session->is_error())
 
5033
  {
 
5034
    snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
 
5035
            (ulong) (copied + deleted), (ulong) deleted,
 
5036
            (ulong) session->cuted_fields);
 
5037
    session->my_ok(copied + deleted, 0L, tmp_name);
 
5038
    session->some_tables_deleted=0;
 
5039
    return false;
 
5040
  }
 
5041
  else
 
5042
  {
 
5043
    /* my_error() was called.  Return true (which means error...) */
 
5044
    return true;
 
5045
  }
5032
5046
 
5033
5047
err1:
5034
5048
  if (new_table)