23
22
* @file This file implements the Field class and API
25
#include "drizzled/server_includes.h"
30
27
#include "drizzled/sql_select.h"
31
28
#include "drizzled/error.h"
32
29
#include "drizzled/field/str.h"
33
30
#include "drizzled/field/num.h"
34
31
#include "drizzled/field/blob.h"
35
#include "drizzled/field/boolean.h"
36
32
#include "drizzled/field/enum.h"
37
33
#include "drizzled/field/null.h"
38
34
#include "drizzled/field/date.h"
39
35
#include "drizzled/field/decimal.h"
40
36
#include "drizzled/field/real.h"
41
37
#include "drizzled/field/double.h"
42
#include "drizzled/field/int32.h"
43
#include "drizzled/field/int64.h"
38
#include "drizzled/field/long.h"
39
#include "drizzled/field/int64_t.h"
44
40
#include "drizzled/field/num.h"
45
#include "drizzled/field/time.h"
46
#include "drizzled/field/epoch.h"
41
#include "drizzled/field/timestamp.h"
47
42
#include "drizzled/field/datetime.h"
48
#include "drizzled/field/microtime.h"
49
43
#include "drizzled/field/varstring.h"
50
#include "drizzled/field/uuid.h"
51
#include "drizzled/time_functions.h"
52
#include "drizzled/internal/m_string.h"
54
#include "drizzled/display.h"
59
45
/*****************************************************************************
60
46
Instansiate templates and static variables
61
47
*****************************************************************************/
49
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
50
template class List<CreateField>;
51
template class List_iterator<CreateField>;
63
54
static enum_field_types
64
field_types_merge_rules [enum_field_types_size][enum_field_types_size]=
55
field_types_merge_rules [DRIZZLE_TYPE_MAX+1][DRIZZLE_TYPE_MAX+1]=
66
57
/* DRIZZLE_TYPE_LONG -> */
602
365
return (str < strend);
605
void *Field::operator new(size_t size)
607
return memory::sql_alloc(size);
610
void *Field::operator new(size_t size, memory::Root *mem_root)
612
return mem_root->alloc_root(static_cast<uint32_t>(size));
615
368
enum_field_types Field::field_type_merge(enum_field_types a,
616
369
enum_field_types b)
618
assert(a < enum_field_types_size);
619
assert(b < enum_field_types_size);
371
assert(a <= DRIZZLE_TYPE_MAX);
372
assert(b <= DRIZZLE_TYPE_MAX);
620
373
return field_types_merge_rules[a][b];
623
376
Item_result Field::result_merge_type(enum_field_types field_type)
625
assert(field_type < enum_field_types_size);
378
assert(field_type <= DRIZZLE_TYPE_MAX);
626
379
return field_types_result_type[field_type];
819
587
void Field::init(Table *table_arg)
821
589
orig_table= table= table_arg;
590
table_name= &table_arg->alias;
593
String *Field::val_int_as_str(String *val_buffer, bool unsigned_val)
595
const CHARSET_INFO * const cs= &my_charset_bin;
597
int64_t value= val_int();
599
if (val_buffer->alloc(MY_INT64_NUM_DECIMAL_DIGITS))
601
length= (uint32_t) (*cs->cset->int64_t10_to_str)(cs, (char*) val_buffer->ptr(),
602
MY_INT64_NUM_DECIMAL_DIGITS,
603
unsigned_val ? 10 : -10,
605
val_buffer->length(length);
824
609
/// This is used as a table name when the table structure is not set up
827
612
unsigned char *null_ptr_arg,
828
613
unsigned char null_bit_arg,
829
614
utype unireg_check_arg,
830
const char *field_name_arg) :
615
const char *field_name_arg)
832
618
null_ptr(null_ptr_arg),
834
620
orig_table(NULL),
835
622
field_name(field_name_arg),
836
comment(NULL_LEX_STRING),
839
625
part_of_key_not_clustered(0),
840
626
part_of_sortkey(0),
841
627
unireg_check(unireg_check_arg),
842
628
field_length(length_arg),
843
flags(null_ptr ? 0: NOT_NULL_FLAG),
845
629
null_bit(null_bit_arg),
846
630
is_created_from_null_item(false)
632
flags= null_ptr ? 0: NOT_NULL_FLAG;
633
comment.str= (char*) "";
850
638
void Field::hash(uint32_t *nr, uint32_t *nr2)
876
int Field::store_and_check(enum_check_fields check_level,
879
const CHARSET_INFO * const cs)
664
int Field::compatible_field_size(uint32_t field_metadata)
666
uint32_t const source_size= pack_length_from_metadata(field_metadata);
667
uint32_t const destination_size= row_pack_length();
668
return (source_size <= destination_size);
671
int Field::store(const char *to,
673
const CHARSET_INFO * const cs,
674
enum_check_fields check_level)
883
677
enum_check_fields old_check_level= table->in_use->count_cuted_fields;
936
730
const unsigned char *Field::unpack(unsigned char* to, const unsigned char *from)
938
const unsigned char *result= unpack(to, from, 0U, table->getShare()->db_low_byte_first);
732
const unsigned char *result= unpack(to, from, 0U, table->s->db_low_byte_first);
942
type::Decimal *Field::val_decimal(type::Decimal *)
736
uint32_t Field::packed_col_length(const unsigned char *, uint32_t length)
741
int Field::pack_cmp(const unsigned char *a, const unsigned char *b,
747
int Field::pack_cmp(const unsigned char *b, uint32_t, bool)
752
my_decimal *Field::val_decimal(my_decimal *)
944
754
/* This never have to be called */
950
760
void Field::make_field(SendField *field)
952
if (orig_table && orig_table->getShare()->getSchemaName() && *orig_table->getShare()->getSchemaName())
762
if (orig_table && orig_table->s->db.str && *orig_table->s->db.str)
954
field->db_name= orig_table->getShare()->getSchemaName();
955
field->org_table_name= orig_table->getShare()->getTableName();
764
field->db_name= orig_table->s->db.str;
765
field->org_table_name= orig_table->s->table_name.str;
958
768
field->org_table_name= field->db_name= "";
961
field->table_name= orig_table->getAlias();
771
field->table_name= orig_table->alias;
962
772
field->org_col_name= field_name;
974
784
field->decimals= 0;
977
int64_t Field::convert_decimal2int64_t(const type::Decimal *val, bool, int *err)
787
int64_t Field::convert_decimal2int64_t(const my_decimal *val, bool, int *err)
980
if (warn_if_overflow(val->val_int32(E_DEC_ERROR &
790
if (warn_if_overflow(my_decimal2int(E_DEC_ERROR &
981
791
~E_DEC_OVERFLOW & ~E_DEC_TRUNCATED,
984
794
i= (val->sign() ? INT64_MIN : INT64_MAX);
1008
818
return copy->length+ store_length;
1011
bool Field::get_date(type::Time <ime, uint32_t fuzzydate)
1013
char buff[type::Time::MAX_STRING_LENGTH];
1014
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1016
assert(getTable() and getTable()->getSession());
1018
if (not (res=val_str_internal(&tmp)) or
1019
str_to_datetime_with_warn(getTable()->getSession(),
1020
res->ptr(), res->length(),
1021
<ime, fuzzydate) <= type::DRIZZLE_TIMESTAMP_ERROR)
1029
bool Field::get_time(type::Time <ime)
1031
char buff[type::Time::MAX_STRING_LENGTH];
1032
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1034
if (not (res= val_str_internal(&tmp)) or
1035
str_to_time_with_warn(getTable()->getSession(), res->ptr(), res->length(), <ime))
1043
int Field::store_time(type::Time <ime, type::timestamp_t)
1049
return store(tmp.ptr(), tmp.length(), &my_charset_bin);
1052
bool Field::optimize_range(uint32_t idx, uint32_t)
1054
return test(table->index_flags(idx) & HA_READ_RANGE);
1057
Field *Field::new_field(memory::Root *root, Table *new_table, bool)
821
bool Field::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
824
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
825
if (!(res=val_str(&tmp)) ||
826
str_to_datetime_with_warn(res->ptr(), res->length(),
827
ltime, fuzzydate) <= DRIZZLE_TIMESTAMP_ERROR)
832
bool Field::get_time(DRIZZLE_TIME *ltime)
835
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
836
if (!(res=val_str(&tmp)) ||
837
str_to_time_with_warn(res->ptr(), res->length(), ltime))
842
int Field::store_time(DRIZZLE_TIME *ltime, enum enum_drizzle_timestamp_type)
844
char buff[MAX_DATE_STRING_REP_LENGTH];
845
uint32_t length= (uint32_t) my_TIME_to_str(ltime, buff);
846
return store(buff, length, &my_charset_bin);
849
bool Field::optimize_range(uint32_t idx, uint32_t part)
851
return test(table->cursor->index_flags(idx, part, 1) & HA_READ_RANGE);
854
Field *Field::new_field(MEM_ROOT *root, Table *new_table, bool)
1060
if (!(tmp= (Field*) root->memdup_root((char*) this,size_of())))
857
if (!(tmp= (Field*) memdup_root(root,(char*) this,size_of())))
1063
860
if (tmp->table->maybe_null)
1067
864
tmp->part_of_key.reset();
1068
865
tmp->part_of_sortkey.reset();
1069
866
tmp->unireg_check= Field::NONE;
1070
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | BINARY_FLAG | ENUM_FLAG);
867
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
1071
868
tmp->reset_fields();
1075
Field *Field::new_key_field(memory::Root *root, Table *new_table,
872
Field *Field::new_key_field(MEM_ROOT *root, Table *new_table,
1076
873
unsigned char *new_ptr,
1077
874
unsigned char *new_null_ptr,
1078
875
uint32_t new_null_bit)
1090
Field *Field::clone(memory::Root *root, Table *new_table)
887
Field *Field::clone(MEM_ROOT *root, Table *new_table)
1093
if ((tmp= (Field*) root->memdup_root((char*) this,size_of())))
890
if ((tmp= (Field*) memdup_root(root,(char*) this,size_of())))
1095
892
tmp->init(new_table);
1096
tmp->move_field_offset((ptrdiff_t) (new_table->getInsertRecord() -
1097
new_table->getDefaultValues()));
893
tmp->move_field_offset((ptrdiff_t) (new_table->record[0] -
894
new_table->s->default_values));
1118
915
if (!Field::eq_def(field))
1121
917
TYPELIB *from_lib=((Field_enum*) field)->typelib;
1123
919
if (typelib->count < from_lib->count)
1126
921
for (uint32_t i=0 ; i < from_lib->count ; i++)
1128
922
if (my_strnncoll(field_charset,
1129
923
(const unsigned char*)typelib->type_names[i],
1130
924
strlen(typelib->type_names[i]),
1131
925
(const unsigned char*)from_lib->type_names[i],
1132
926
strlen(from_lib->type_names[i])))
932
Make a field from the .frm file info
1139
934
uint32_t calc_pack_length(enum_field_types type,uint32_t length)
1142
937
case DRIZZLE_TYPE_VARCHAR: return (length + (length < 256 ? 1: 2));
1143
case DRIZZLE_TYPE_UUID: return field::Uuid::max_string_length();
1144
case DRIZZLE_TYPE_MICROTIME: return field::Microtime::max_string_length();
1145
case DRIZZLE_TYPE_TIMESTAMP: return field::Epoch::max_string_length();
1146
case DRIZZLE_TYPE_BOOLEAN: return field::Boolean::max_string_length();
1147
case DRIZZLE_TYPE_DATE:
1148
case DRIZZLE_TYPE_ENUM:
938
case DRIZZLE_TYPE_DATE: return 3;
939
case DRIZZLE_TYPE_TIMESTAMP:
1149
940
case DRIZZLE_TYPE_LONG: return 4;
1150
941
case DRIZZLE_TYPE_DOUBLE: return sizeof(double);
1151
case DRIZZLE_TYPE_TIME:
1152
942
case DRIZZLE_TYPE_DATETIME:
1153
943
case DRIZZLE_TYPE_LONGLONG: return 8; /* Don't crash if no int64_t */
1154
944
case DRIZZLE_TYPE_NULL: return 0;
1155
945
case DRIZZLE_TYPE_BLOB: return 4 + portable_sizeof_char_ptr;
946
case DRIZZLE_TYPE_ENUM:
1156
947
case DRIZZLE_TYPE_DECIMAL:
1164
954
uint32_t pack_length_to_packflag(uint32_t type)
1167
957
case 1: return 1 << FIELDFLAG_PACK_SHIFT;
1168
958
case 2: assert(1);
1169
959
case 3: assert(1);
1170
case 4: return f_settype(DRIZZLE_TYPE_LONG);
1171
case 8: return f_settype(DRIZZLE_TYPE_LONGLONG);
960
case 4: return f_settype((uint32_t) DRIZZLE_TYPE_LONG);
961
case 8: return f_settype((uint32_t) DRIZZLE_TYPE_LONGLONG);
1173
963
return 0; // This shouldn't happen
966
Field *make_field(TableShare *share,
969
uint32_t field_length,
971
unsigned char *null_pos,
972
unsigned char null_bit,
974
enum_field_types field_type,
975
const CHARSET_INFO * field_charset,
976
Field::utype unireg_check,
978
const char *field_name)
981
root= current_mem_root();
990
null_bit= ((unsigned char) 1) << null_bit;
995
case DRIZZLE_TYPE_DATE:
996
case DRIZZLE_TYPE_DATETIME:
997
case DRIZZLE_TYPE_TIMESTAMP:
998
field_charset= &my_charset_bin;
1002
if (field_type == DRIZZLE_TYPE_VARCHAR ||
1003
field_type == DRIZZLE_TYPE_BLOB ||
1004
field_type == DRIZZLE_TYPE_ENUM)
1006
if (field_type == DRIZZLE_TYPE_VARCHAR)
1007
return new (root) Field_varstring(ptr,field_length,
1008
HA_VARCHAR_PACKLENGTH(field_length),
1014
if (field_type == DRIZZLE_TYPE_BLOB)
1016
return new (root) Field_blob(ptr,
1021
calc_pack_length(DRIZZLE_TYPE_LONG, 0),
1027
return new (root) Field_enum(ptr,
1032
get_enum_pack_length(interval->count),
1040
case DRIZZLE_TYPE_DECIMAL:
1041
return new (root) Field_decimal(ptr,
1049
false /* is_unsigned */);
1050
case DRIZZLE_TYPE_DOUBLE:
1051
return new (root) Field_double(ptr,
1059
false /* is_unsigned */);
1060
case DRIZZLE_TYPE_LONG:
1061
return new (root) Field_long(ptr,
1068
false /* is_unsigned */);
1069
case DRIZZLE_TYPE_LONGLONG:
1070
return new (root) Field_int64_t(ptr,
1077
false /* is_unsigned */);
1078
case DRIZZLE_TYPE_TIMESTAMP:
1079
return new (root) Field_timestamp(ptr,
1087
case DRIZZLE_TYPE_DATE:
1088
return new (root) Field_date(ptr,
1093
case DRIZZLE_TYPE_DATETIME:
1094
return new (root) Field_datetime(ptr,
1099
case DRIZZLE_TYPE_NULL:
1100
return new (root) Field_null(ptr,
1104
default: // Impossible (Wrong version)
1176
1110
/*****************************************************************************
1177
1111
Warning handling
1178
1112
*****************************************************************************/
1180
1114
bool Field::set_warning(DRIZZLE_ERROR::enum_warning_level level,
1181
drizzled::error_t code,
1182
1116
int cuted_increment)
1200
1134
void Field::set_datetime_warning(DRIZZLE_ERROR::enum_warning_level level,
1201
drizzled::error_t code,
1202
1136
const char *str,
1203
1137
uint32_t str_length,
1204
type::timestamp_t ts_type,
1138
enum enum_drizzle_timestamp_type ts_type,
1205
1139
int cuted_increment)
1207
Session *session= (getTable() and getTable()->getSession()) ? getTable()->getSession() : current_session;
1209
if ((session->abortOnWarning() and
1141
Session *session= table ? table->in_use : current_session;
1142
if ((session->really_abort_on_warning() &&
1210
1143
level >= DRIZZLE_ERROR::WARN_LEVEL_WARN) ||
1211
1144
set_warning(level, code, cuted_increment))
1212
1145
make_truncated_value_warning(session, level, str, str_length, ts_type,
1216
1149
void Field::set_datetime_warning(DRIZZLE_ERROR::enum_warning_level level,
1217
drizzled::error_t code,
1219
type::timestamp_t ts_type,
1152
enum enum_drizzle_timestamp_type ts_type,
1220
1153
int cuted_increment)
1222
Session *session= (getTable() and getTable()->getSession()) ? getTable()->getSession() : current_session;
1224
if (session->abortOnWarning() or
1155
Session *session= table ? table->in_use : current_session;
1156
if (session->really_abort_on_warning() ||
1225
1157
set_warning(level, code, cuted_increment))
1227
char str_nr[DECIMAL_LONGLONG_DIGITS];
1228
char *str_end= internal::int64_t10_to_str(nr, str_nr, -10);
1160
char *str_end= int64_t10_to_str(nr, str_nr, -10);
1229
1161
make_truncated_value_warning(session, level, str_nr, (uint32_t) (str_end - str_nr),
1230
1162
ts_type, field_name);
1234
1166
void Field::set_datetime_warning(DRIZZLE_ERROR::enum_warning_level level,
1235
const drizzled::error_t code,
1167
const uint32_t code,
1237
type::timestamp_t ts_type)
1169
enum enum_drizzle_timestamp_type ts_type)
1239
Session *session= (getTable() and getTable()->getSession()) ? getTable()->getSession() : current_session;
1241
if (session->abortOnWarning() or
1171
Session *session= table ? table->in_use : current_session;
1172
if (session->really_abort_on_warning() ||
1242
1173
set_warning(level, code, 1))
1244
1175
/* DBL_DIG is enough to print '-[digits].E+###' */
1245
1176
char str_nr[DBL_DIG + 8];
1246
uint32_t str_len= snprintf(str_nr, sizeof(str_nr), "%g", nr);
1177
uint32_t str_len= sprintf(str_nr, "%g", nr);
1247
1178
make_truncated_value_warning(session, level, str_nr, str_len, ts_type,
1275
1206
table->clearWriteSet(field_index);
1278
void Field::pack_num(uint64_t arg, unsigned char *destination)
1280
if (not destination)
1283
int64_tstore(destination, arg);
1286
void Field::pack_num(uint32_t arg, unsigned char *destination)
1288
if (not destination)
1291
longstore(destination, arg);
1294
uint64_t Field::unpack_num(uint64_t &destination, const unsigned char *arg) const
1299
int64_tget(destination, arg);
1304
uint32_t Field::unpack_num(uint32_t &destination, const unsigned char *arg) const
1309
longget(destination, arg);
1314
std::ostream& operator<<(std::ostream& output, const Field &field)
1316
output << "Field:(";
1317
output << field.field_name;
1319
output << drizzled::display::type(field.real_type());
1322
if (field.flags & NOT_NULL_FLAG)
1323
output << " NOT_NULL";
1325
if (field.flags & PRI_KEY_FLAG)
1326
output << ", PRIMARY KEY";
1328
if (field.flags & UNIQUE_KEY_FLAG)
1329
output << ", UNIQUE KEY";
1331
if (field.flags & MULTIPLE_KEY_FLAG)
1332
output << ", MULTIPLE KEY";
1334
if (field.flags & BLOB_FLAG)
1337
if (field.flags & UNSIGNED_FLAG)
1338
output << ", UNSIGNED";
1340
if (field.flags & BINARY_FLAG)
1341
output << ", BINARY";
1345
return output; // for multiple << operators.
1348
} /* namespace drizzled */