diff options
author | unknown <cmiller@zippy.(none)> | 2006-07-05 16:16:09 -0400 |
---|---|---|
committer | unknown <cmiller@zippy.(none)> | 2006-07-05 16:16:09 -0400 |
commit | 30de4903ae2b9cd03bd5f853715e7fc7b648c2c7 (patch) | |
tree | a0c67909c6e1a1b67caf4558144a68911d8dfb15 /sql/field.cc | |
parent | f92fd7c98adad9542e7d8d29ee24db504980541f (diff) | |
parent | 2ef57b836248f945657c7bd0fe02fa7fe3660b54 (diff) | |
download | mariadb-git-30de4903ae2b9cd03bd5f853715e7fc7b648c2c7.tar.gz |
Merge zippy.(none):/home/cmiller/work/mysql/merge/mysql-5.1
into zippy.(none):/home/cmiller/work/mysql/merge/mysql-5.1-new-maint
BUILD/compile-dist:
Auto merged
BitKeeper/deleted/.del-partition_innodb.result:
Auto merged
BitKeeper/deleted/.del-partition_innodb.test:
Auto merged
client/mysqltest.c:
Auto merged
mysql-test/r/create.result:
Auto merged
mysql-test/r/create_not_windows.result:
Auto merged
mysql-test/r/func_group.result:
Auto merged
mysql-test/r/innodb_mysql.result:
Auto merged
mysql-test/r/partition.result:
Auto merged
mysql-test/r/sp.result:
Auto merged
mysql-test/t/innodb_mysql.test:
Auto merged
mysql-test/t/partition.test:
Auto merged
mysql-test/t/ps_1general.test:
Auto merged
mysql-test/t/sp.test:
Auto merged
mysql-test/t/wait_timeout.test:
Auto merged
mysys/my_lib.c:
Auto merged
sql/field.cc:
Auto merged
sql/field.h:
Auto merged
sql/unireg.cc:
Auto merged
mysql-test/extra/rpl_tests/rpl_log.test:
manuakl merge
mysql-test/lib/mtr_process.pl:
manuakl merge
mysql-test/mysql-test-run.pl:
manuakl merge
mysql-test/r/type_newdecimal.result:
manuakl merge
mysql-test/t/create.test:
manuakl merge
mysql-test/t/func_group.test:
manuakl merge
mysql-test/t/type_newdecimal.test:
manuakl merge
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 186 |
1 files changed, 111 insertions, 75 deletions
diff --git a/sql/field.cc b/sql/field.cc index 4b5fffaabf9..57279298cbd 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -50,8 +50,8 @@ const char field_separator=','; #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \ ((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1))) -#define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table->read_set || bitmap_is_set(table->read_set, field_index)) -#define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table->write_set || bitmap_is_set(table->write_set, field_index)) +#define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))) +#define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index))) /* Rules for merging different types of fields in UNION @@ -1243,6 +1243,21 @@ uint Field::offset() } +void Field::hash(ulong *nr, ulong *nr2) +{ + if (is_null()) + { + *nr^= (*nr << 1) | 1; + } + else + { + uint len= pack_length(); + CHARSET_INFO *cs= charset(); + cs->coll->hash_sort(cs, (uchar*) ptr, len, nr, nr2); + } +} + + void Field::copy_from_tmp(int row_offset) { memcpy(ptr,ptr+row_offset,pack_length()); @@ -3483,8 +3498,7 @@ int Field_long::store(longlong nr, bool unsigned_val) ASSERT_COLUMN_MARKED_FOR_WRITE; int error= 0; int32 res; - DBUG_ASSERT(table->in_use == current_thd); // General safety - + if (unsigned_flag) { if (nr < 0 && !unsigned_val) @@ -4617,11 +4631,11 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) int error; bool have_smth_to_conv; my_bool in_dst_time_gap; - THD *thd= table->in_use; + THD *thd= table ? table->in_use : current_thd; /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ have_smth_to_conv= (str_to_datetime(from, len, &l_time, - (table->in_use->variables.sql_mode & + (thd->variables.sql_mode & MODE_NO_ZERO_DATE) | MODE_NO_ZERO_IN_DATE, &error) > MYSQL_TIMESTAMP_ERROR); @@ -4653,7 +4667,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) } #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { int4store(ptr,tmp); } @@ -4687,7 +4701,7 @@ int Field_timestamp::store(longlong nr, bool unsigned_val) my_time_t timestamp= 0; int error; my_bool in_dst_time_gap; - THD *thd= table->in_use; + THD *thd= table ? table->in_use : current_thd; /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ longlong tmp= number_to_datetime(nr, &l_time, (thd->variables.sql_mode & @@ -4720,7 +4734,7 @@ int Field_timestamp::store(longlong nr, bool unsigned_val) nr, MYSQL_TIMESTAMP_DATETIME, 1); #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { int4store(ptr,timestamp); } @@ -4743,10 +4757,10 @@ longlong Field_timestamp::val_int(void) ASSERT_COLUMN_MARKED_FOR_READ; uint32 temp; TIME time_tmp; - THD *thd= table->in_use; + THD *thd= table ? table->in_use : current_thd; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) temp=uint4korr(ptr); else #endif @@ -4769,7 +4783,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) ASSERT_COLUMN_MARKED_FOR_READ; uint32 temp, temp2; TIME time_tmp; - THD *thd= table->in_use; + THD *thd= table ? table->in_use : current_thd; char *to; val_buffer->alloc(field_length+1); @@ -4777,7 +4791,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) val_buffer->length(field_length); #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) temp=uint4korr(ptr); else #endif @@ -4840,9 +4854,9 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) bool Field_timestamp::get_date(TIME *ltime, uint fuzzydate) { long temp; - THD *thd= table->in_use; + THD *thd= table ? table->in_use : current_thd; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) temp=uint4korr(ptr); else #endif @@ -4879,7 +4893,7 @@ int Field_timestamp::cmp(const char *a_ptr, const char *b_ptr) { int32 a,b; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { a=sint4korr(a_ptr); b=sint4korr(b_ptr); @@ -4897,7 +4911,7 @@ int Field_timestamp::cmp(const char *a_ptr, const char *b_ptr) void Field_timestamp::sort_string(char *to,uint length __attribute__((unused))) { #ifdef WORDS_BIGENDIAN - if (!table->s->db_low_byte_first) + if (!table || !table->s->db_low_byte_first) { to[0] = ptr[0]; to[1] = ptr[1]; @@ -4923,10 +4937,11 @@ void Field_timestamp::sql_type(String &res) const void Field_timestamp::set_time() { - long tmp= (long) table->in_use->query_start(); + THD *thd= table ? table->in_use : current_thd; + long tmp= (long) thd->query_start(); set_notnull(); #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { int4store(ptr,tmp); } @@ -4990,7 +5005,7 @@ int Field_time::store_time(TIME *ltime, timestamp_type type) (ltime->minute * 100 + ltime->second); if (ltime->neg) tmp= -tmp; - return Field_time::store((longlong) tmp); + return Field_time::store((longlong) tmp, TRUE); } @@ -5002,7 +5017,7 @@ int Field_time::store(double nr) if (nr > 8385959.0) { tmp=8385959L; - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); error= 1; } @@ -5120,12 +5135,13 @@ String *Field_time::val_str(String *val_buffer, bool Field_time::get_date(TIME *ltime, uint fuzzydate) { long tmp; + THD *thd= table ? table->in_use : current_thd; if (!(fuzzydate & TIME_FUZZY_DATE)) { - push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, ER(ER_WARN_DATA_OUT_OF_RANGE), field_name, - table->in_use->row_count); + thd->row_count); return 1; } tmp=(long) sint3korr(ptr); @@ -5223,7 +5239,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) else if (nr > 1900) nr-= 1900; } - *ptr= (char) (unsigned char) nr; + *ptr= (char) (uchar) nr; return error; } @@ -5255,7 +5271,7 @@ int Field_year::store(longlong nr, bool unsigned_val) else if (nr > 1900) nr-= 1900; } - *ptr= (char) (unsigned char) nr; + *ptr= (char) (uchar) nr; return 0; } @@ -5318,9 +5334,10 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) TIME l_time; uint32 tmp; int error; + THD *thd= table ? table->in_use : current_thd; if (str_to_datetime(from, len, &l_time, TIME_FUZZY_DATE | - (table->in_use->variables.sql_mode & + (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)), &error) <= MYSQL_TIMESTAMP_ERROR) @@ -5336,7 +5353,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) from, len, MYSQL_TIMESTAMP_DATE, 1); #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { int4store(ptr,tmp); } @@ -5374,9 +5391,10 @@ int Field_date::store(longlong nr, bool unsigned_val) TIME not_used; int error; longlong initial_nr= nr; + THD *thd= table ? table->in_use : current_thd; nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE | - (table->in_use->variables.sql_mode & + (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error); @@ -5397,7 +5415,7 @@ int Field_date::store(longlong nr, bool unsigned_val) MYSQL_TIMESTAMP_DATETIME, 1); #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { int4store(ptr, nr); } @@ -5424,7 +5442,7 @@ double Field_date::val_real(void) ASSERT_COLUMN_MARKED_FOR_READ; int32 j; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) j=sint4korr(ptr); else #endif @@ -5438,7 +5456,7 @@ longlong Field_date::val_int(void) ASSERT_COLUMN_MARKED_FOR_READ; int32 j; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) j=sint4korr(ptr); else #endif @@ -5455,7 +5473,7 @@ String *Field_date::val_str(String *val_buffer, val_buffer->alloc(field_length); int32 tmp; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) tmp=sint4korr(ptr); else #endif @@ -5473,7 +5491,7 @@ int Field_date::cmp(const char *a_ptr, const char *b_ptr) { int32 a,b; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { a=sint4korr(a_ptr); b=sint4korr(b_ptr); @@ -5491,7 +5509,7 @@ int Field_date::cmp(const char *a_ptr, const char *b_ptr) void Field_date::sort_string(char *to,uint length __attribute__((unused))) { #ifdef WORDS_BIGENDIAN - if (!table->s->db_low_byte_first) + if (!table || !table->s->db_low_byte_first) { to[0] = ptr[0]; to[1] = ptr[1]; @@ -5526,9 +5544,10 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) TIME l_time; long tmp; int error; + THD *thd= table ? table->in_use : current_thd; if (str_to_datetime(from, len, &l_time, (TIME_FUZZY_DATE | - (table->in_use->variables.sql_mode & + (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error) <= MYSQL_TIMESTAMP_ERROR) @@ -5567,9 +5586,10 @@ int Field_newdate::store(longlong nr, bool unsigned_val) TIME l_time; longlong tmp; int error; + THD *thd= table ? table->in_use : current_thd; if (number_to_datetime(nr, &l_time, (TIME_FUZZY_DATE | - (table->in_use->variables.sql_mode & + (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error) == LL(-1)) @@ -5717,10 +5737,11 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) int error; ulonglong tmp= 0; enum enum_mysql_timestamp_type func_res; + THD *thd= table ? table->in_use : current_thd; func_res= str_to_datetime(from, len, &time_tmp, (TIME_FUZZY_DATE | - (table->in_use->variables.sql_mode & + (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error); @@ -5735,7 +5756,7 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) from, len, MYSQL_TIMESTAMP_DATETIME, 1); #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { int8store(ptr,tmp); } @@ -5768,9 +5789,10 @@ int Field_datetime::store(longlong nr, bool unsigned_val) TIME not_used; int error; longlong initial_nr= nr; + THD *thd= table ? table->in_use : current_thd; nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE | - (table->in_use->variables.sql_mode & + (thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error); @@ -5788,7 +5810,7 @@ int Field_datetime::store(longlong nr, bool unsigned_val) MYSQL_TIMESTAMP_DATETIME, 1); #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { int8store(ptr,nr); } @@ -5818,7 +5840,7 @@ int Field_datetime::store_time(TIME *ltime,timestamp_type type) set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); } #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { int8store(ptr,tmp); } @@ -5846,7 +5868,7 @@ longlong Field_datetime::val_int(void) ASSERT_COLUMN_MARKED_FOR_READ; longlong j; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) j=sint8korr(ptr); else #endif @@ -5867,7 +5889,7 @@ String *Field_datetime::val_str(String *val_buffer, int part3; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) tmp=sint8korr(ptr); else #endif @@ -5932,7 +5954,7 @@ int Field_datetime::cmp(const char *a_ptr, const char *b_ptr) { longlong a,b; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) + if (table && table->s->db_low_byte_first) { a=sint8korr(a_ptr); b=sint8korr(b_ptr); @@ -5950,7 +5972,7 @@ int Field_datetime::cmp(const char *a_ptr, const char *b_ptr) void Field_datetime::sort_string(char *to,uint length __attribute__((unused))) { #ifdef WORDS_BIGENDIAN - if (!table->s->db_low_byte_first) + if (!table || !table->s->db_low_byte_first) { to[0] = ptr[0]; to[1] = ptr[1]; @@ -6186,17 +6208,6 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) { uint a_len, b_len; - if (field_charset->strxfrm_multiply > 1) - { - /* - We have to remove end space to be able to compare multi-byte-characters - like in latin_de 'ae' and 0xe4 - */ - return field_charset->coll->strnncollsp(field_charset, - (const uchar*) a_ptr, field_length, - (const uchar*) b_ptr, - field_length, 0); - } if (field_charset->mbmaxlen != 1) { uint char_len= field_length/field_charset->mbmaxlen; @@ -6205,16 +6216,22 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) } else a_len= b_len= field_length; - return my_strnncoll(field_charset,(const uchar*) a_ptr, a_len, - (const uchar*) b_ptr, b_len); + /* + We have to remove end space to be able to compare multi-byte-characters + like in latin_de 'ae' and 0xe4 + */ + return field_charset->coll->strnncollsp(field_charset, + (const uchar*) a_ptr, a_len, + (const uchar*) b_ptr, b_len, + 0); } void Field_string::sort_string(char *to,uint length) { - uint tmp=my_strnxfrm(field_charset, - (unsigned char *) to, length, - (unsigned char *) ptr, field_length); + uint tmp= my_strnxfrm(field_charset, + (uchar*) to, length, + (uchar*) ptr, field_length); DBUG_ASSERT(tmp == length); } @@ -6935,6 +6952,21 @@ uint Field_varstring::is_equal(create_field *new_field) } +void Field_varstring::hash(ulong *nr, ulong *nr2) +{ + if (is_null()) + { + *nr^= (*nr << 1) | 1; + } + else + { + uint len= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); + CHARSET_INFO *cs= charset(); + cs->coll->hash_sort(cs, (uchar*) ptr + length_bytes, len, nr, nr2); + } +} + + /**************************************************************************** ** blob type ** A blob is saved as a length and a pointer. The length is stored in the @@ -7129,7 +7161,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) int Field_blob::store(double nr) { CHARSET_INFO *cs=charset(); - value.set(nr, 2, cs); + value.set_real(nr, 2, cs); return Field_blob::store(value.ptr(),(uint) value.length(), cs); } @@ -7137,10 +7169,7 @@ int Field_blob::store(double nr) int Field_blob::store(longlong nr, bool unsigned_val) { CHARSET_INFO *cs=charset(); - if (unsigned_val) - value.set((ulonglong) nr, cs); - else - value.set(nr, cs); + value.set_int(nr, unsigned_val, cs); return Field_blob::store(value.ptr(), (uint) value.length(), cs); } @@ -8231,7 +8260,7 @@ int Field_bit::store_decimal(const my_decimal *val) { int err= 0; longlong i= convert_decimal2longlong(val, 1, &err); - return test(err | store(i)); + return test(err | store(i, TRUE)); } @@ -9263,7 +9292,11 @@ bool Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code, int cuted_increment) { - THD *thd= table->in_use; + /* + If this field was created only for type conversion purposes it + will have table == NULL. + */ + THD *thd= table ? table->in_use : current_thd; if (thd->count_cuted_fields) { thd->cuted_fields+= cuted_increment; @@ -9298,9 +9331,10 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, const char *str, uint str_length, timestamp_type ts_type, int cuted_increment) { - if (table->in_use->really_abort_on_warning() || + THD *thd= table ? table->in_use : current_thd; + if (thd->really_abort_on_warning() || set_warning(level, code, cuted_increment)) - make_truncated_value_warning(table->in_use, str, str_length, ts_type, + make_truncated_value_warning(thd, str, str_length, ts_type, field_name); } @@ -9327,13 +9361,13 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, longlong nr, timestamp_type ts_type, int cuted_increment) { - if (table->in_use->really_abort_on_warning() || + THD *thd= table ? table->in_use : current_thd; + if (thd->really_abort_on_warning() || set_warning(level, code, cuted_increment)) { char str_nr[22]; char *str_end= longlong10_to_str(nr, str_nr, -10); - make_truncated_value_warning(table->in_use, str_nr, - (uint) (str_end - str_nr), + make_truncated_value_warning(thd, str_nr, (uint) (str_end - str_nr), ts_type, field_name); } } @@ -9359,13 +9393,15 @@ void Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, double nr, timestamp_type ts_type) { - if (table->in_use->really_abort_on_warning() || + THD *thd= table ? table->in_use : current_thd; + if (thd->really_abort_on_warning() || set_warning(level, code, 1)) { /* DBL_DIG is enough to print '-[digits].E+###' */ char str_nr[DBL_DIG + 8]; uint str_len= my_sprintf(str_nr, (str_nr, "%g", nr)); - make_truncated_value_warning(table->in_use, str_nr, str_len, ts_type, + make_truncated_value_warning(thd, str_nr, str_len, ts_type, field_name); } } + |