23
22
* @file This file implements the Field class and API
25
#include "drizzled/server_includes.h"
30
#include <drizzled/sql_select.h>
31
#include <drizzled/error.h>
32
#include <drizzled/field/str.h>
33
#include <drizzled/field/num.h>
34
#include <drizzled/field/blob.h>
35
#include <drizzled/field/boolean.h>
36
#include <drizzled/field/enum.h>
37
#include <drizzled/field/null.h>
38
#include <drizzled/field/date.h>
39
#include <drizzled/field/decimal.h>
40
#include <drizzled/field/real.h>
41
#include <drizzled/field/double.h>
42
#include <drizzled/field/int32.h>
43
#include <drizzled/field/int64.h>
44
#include <drizzled/field/num.h>
45
#include <drizzled/field/time.h>
46
#include <drizzled/field/epoch.h>
47
#include <drizzled/field/datetime.h>
48
#include <drizzled/field/microtime.h>
49
#include <drizzled/field/varstring.h>
50
#include <drizzled/field/uuid.h>
51
#include <drizzled/time_functions.h>
52
#include <drizzled/internal/m_string.h>
53
#include <drizzled/table.h>
54
#include <drizzled/util/test.h>
55
#include <drizzled/session.h>
56
#include <drizzled/current_session.h>
57
#include <drizzled/display.h>
58
#include <drizzled/typelib.h>
27
#include "drizzled/sql_select.h"
28
#include "drizzled/error.h"
29
#include "drizzled/field/str.h"
30
#include "drizzled/field/num.h"
31
#include "drizzled/field/blob.h"
32
#include "drizzled/field/enum.h"
33
#include "drizzled/field/null.h"
34
#include "drizzled/field/date.h"
35
#include "drizzled/field/decimal.h"
36
#include "drizzled/field/real.h"
37
#include "drizzled/field/double.h"
38
#include "drizzled/field/long.h"
39
#include "drizzled/field/int64_t.h"
40
#include "drizzled/field/num.h"
41
#include "drizzled/field/timestamp.h"
42
#include "drizzled/field/datetime.h"
43
#include "drizzled/field/varstring.h"
63
45
/*****************************************************************************
64
46
Instansiate templates and static variables
65
47
*****************************************************************************/
49
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
50
template class List<CreateField>;
51
template class List_iterator<CreateField>;
67
54
static enum_field_types
68
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]=
57
/* DRIZZLE_TYPE_TINY -> */
67
//DRIZZLE_TYPE_TIMESTAMP
69
//DRIZZLE_TYPE_LONGLONG
70
DRIZZLE_TYPE_LONGLONG,
71
//DRIZZLE_TYPE_DATETIME
75
//DRIZZLE_TYPE_VARCHAR
77
//DRIZZLE_TYPE_NEWDECIMAL
78
DRIZZLE_TYPE_NEWDECIMAL,
70
84
/* DRIZZLE_TYPE_LONG -> */
72
88
//DRIZZLE_TYPE_LONG
74
90
//DRIZZLE_TYPE_DOUBLE
606
416
return (str < strend);
609
void *Field::operator new(size_t size)
611
return memory::sql_alloc(size);
614
void *Field::operator new(size_t size, memory::Root *mem_root)
616
return mem_root->alloc_root(static_cast<uint32_t>(size));
619
419
enum_field_types Field::field_type_merge(enum_field_types a,
620
420
enum_field_types b)
622
assert(a < enum_field_types_size);
623
assert(b < enum_field_types_size);
422
assert(a <= DRIZZLE_TYPE_MAX);
423
assert(b <= DRIZZLE_TYPE_MAX);
624
424
return field_types_merge_rules[a][b];
627
427
Item_result Field::result_merge_type(enum_field_types field_type)
629
assert(field_type < enum_field_types_size);
429
assert(field_type <= DRIZZLE_TYPE_MAX);
630
430
return field_types_result_type[field_type];
749
bool Field::is_null(ptrdiff_t row_offset) const
564
bool Field::is_null(my_ptrdiff_t row_offset)
751
566
return null_ptr ?
752
567
(null_ptr[row_offset] & null_bit ? true : false) :
756
bool Field::is_real_null(ptrdiff_t row_offset) const
571
bool Field::is_real_null(my_ptrdiff_t row_offset)
758
573
return null_ptr ? (null_ptr[row_offset] & null_bit ? true : false) : false;
761
bool Field::is_null_in_record(const unsigned char *record) const
576
bool Field::is_null_in_record(const unsigned char *record)
765
return test(record[(uint32_t) (null_ptr -table->getInsertRecord())] & null_bit);
580
return test(record[(uint32_t) (null_ptr -table->record[0])] & null_bit);
768
bool Field::is_null_in_record_with_offset(ptrdiff_t with_offset) const
583
bool Field::is_null_in_record_with_offset(my_ptrdiff_t with_offset)
772
587
return test(null_ptr[with_offset] & null_bit);
775
void Field::set_null(ptrdiff_t row_offset)
590
void Field::set_null(my_ptrdiff_t row_offset)
778
593
null_ptr[row_offset]|= null_bit;
781
void Field::set_notnull(ptrdiff_t row_offset)
596
void Field::set_notnull(my_ptrdiff_t row_offset)
784
599
null_ptr[row_offset]&= (unsigned char) ~null_bit;
787
bool Field::maybe_null(void) const
602
bool Field::maybe_null(void)
789
604
return null_ptr != 0 || table->maybe_null;
792
bool Field::real_maybe_null(void) const
607
bool Field::real_maybe_null(void)
794
609
return null_ptr != 0;
831
663
unsigned char *null_ptr_arg,
832
664
unsigned char null_bit_arg,
833
665
utype unireg_check_arg,
834
const char *field_name_arg) :
666
const char *field_name_arg)
836
669
null_ptr(null_ptr_arg),
838
671
orig_table(NULL),
839
673
field_name(field_name_arg),
840
comment(NULL_LEX_STRING),
843
676
part_of_key_not_clustered(0),
844
677
part_of_sortkey(0),
845
678
unireg_check(unireg_check_arg),
846
679
field_length(length_arg),
847
flags(null_ptr ? 0: NOT_NULL_FLAG),
849
680
null_bit(null_bit_arg),
850
681
is_created_from_null_item(false)
683
flags= null_ptr ? 0: NOT_NULL_FLAG;
684
comment.str= (char*) "";
854
void Field::hash(uint32_t *nr, uint32_t *nr2) const
689
void Field::hash(uint32_t *nr, uint32_t *nr2)
940
781
const unsigned char *Field::unpack(unsigned char* to, const unsigned char *from)
942
const unsigned char *result= unpack(to, from, 0U, table->getShare()->db_low_byte_first);
783
const unsigned char *result= unpack(to, from, 0U, table->s->db_low_byte_first);
946
type::Decimal *Field::val_decimal(type::Decimal *) const
787
uint32_t Field::packed_col_length(const unsigned char *, uint32_t length)
792
int Field::pack_cmp(const unsigned char *a, const unsigned char *b,
798
int Field::pack_cmp(const unsigned char *b, uint32_t, bool)
803
my_decimal *Field::val_decimal(my_decimal *)
948
805
/* This never have to be called */
1012
869
return copy->length+ store_length;
1015
bool Field::get_date(type::Time <ime, uint32_t fuzzydate) const
1017
char buff[type::Time::MAX_STRING_LENGTH];
1018
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1020
assert(getTable() and getTable()->getSession());
1022
if (not (res= val_str_internal(&tmp)) or
1023
str_to_datetime_with_warn(getTable()->getSession(),
1024
res->ptr(), res->length(),
1025
<ime, fuzzydate) <= type::DRIZZLE_TIMESTAMP_ERROR)
1033
bool Field::get_time(type::Time <ime) const
1035
char buff[type::Time::MAX_STRING_LENGTH];
1036
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1038
if (not (res= val_str_internal(&tmp)) or
1039
str_to_time_with_warn(getTable()->getSession(), res->ptr(), res->length(), <ime))
1047
int Field::store_time(type::Time <ime, type::timestamp_t)
1053
return store(tmp.ptr(), tmp.length(), &my_charset_bin);
1056
bool Field::optimize_range(uint32_t idx, uint32_t)
1058
return test(table->index_flags(idx) & HA_READ_RANGE);
1061
Field *Field::new_field(memory::Root *root, Table *new_table, bool)
872
bool Field::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
875
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
876
if (!(res=val_str(&tmp)) ||
877
str_to_datetime_with_warn(res->ptr(), res->length(),
878
ltime, fuzzydate) <= DRIZZLE_TIMESTAMP_ERROR)
883
bool Field::get_time(DRIZZLE_TIME *ltime)
886
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
887
if (!(res=val_str(&tmp)) ||
888
str_to_time_with_warn(res->ptr(), res->length(), ltime))
893
int Field::store_time(DRIZZLE_TIME *ltime, enum enum_drizzle_timestamp_type)
895
char buff[MAX_DATE_STRING_REP_LENGTH];
896
uint32_t length= (uint32_t) my_TIME_to_str(ltime, buff);
897
return store(buff, length, &my_charset_bin);
900
bool Field::optimize_range(uint32_t idx, uint32_t part)
902
return test(table->file->index_flags(idx, part, 1) & HA_READ_RANGE);
905
Field *Field::new_field(MEM_ROOT *root, Table *new_table, bool)
1064
if (!(tmp= (Field*) root->memdup_root((char*) this,size_of())))
908
if (!(tmp= (Field*) memdup_root(root,(char*) this,size_of())))
1067
911
if (tmp->table->maybe_null)
1122
966
if (!Field::eq_def(field))
1125
968
TYPELIB *from_lib=((Field_enum*) field)->typelib;
1127
970
if (typelib->count < from_lib->count)
1130
972
for (uint32_t i=0 ; i < from_lib->count ; i++)
1132
973
if (my_strnncoll(field_charset,
1133
974
(const unsigned char*)typelib->type_names[i],
1134
975
strlen(typelib->type_names[i]),
1135
976
(const unsigned char*)from_lib->type_names[i],
1136
977
strlen(from_lib->type_names[i])))
983
Make a field from the .frm file info
1143
985
uint32_t calc_pack_length(enum_field_types type,uint32_t length)
1146
988
case DRIZZLE_TYPE_VARCHAR: return (length + (length < 256 ? 1: 2));
1147
case DRIZZLE_TYPE_UUID: return field::Uuid::max_string_length();
1148
case DRIZZLE_TYPE_MICROTIME: return field::Microtime::max_string_length();
1149
case DRIZZLE_TYPE_TIMESTAMP: return field::Epoch::max_string_length();
1150
case DRIZZLE_TYPE_BOOLEAN: return field::Boolean::max_string_length();
1151
case DRIZZLE_TYPE_DATE:
1152
case DRIZZLE_TYPE_ENUM:
989
case DRIZZLE_TYPE_TINY: return 1;
990
case DRIZZLE_TYPE_DATE: return 3;
991
case DRIZZLE_TYPE_TIMESTAMP:
1153
992
case DRIZZLE_TYPE_LONG: return 4;
1154
993
case DRIZZLE_TYPE_DOUBLE: return sizeof(double);
1155
case DRIZZLE_TYPE_TIME:
1156
994
case DRIZZLE_TYPE_DATETIME:
1157
995
case DRIZZLE_TYPE_LONGLONG: return 8; /* Don't crash if no int64_t */
1158
996
case DRIZZLE_TYPE_NULL: return 0;
1159
997
case DRIZZLE_TYPE_BLOB: return 4 + portable_sizeof_char_ptr;
1160
case DRIZZLE_TYPE_DECIMAL:
998
case DRIZZLE_TYPE_ENUM:
999
case DRIZZLE_TYPE_NEWDECIMAL:
1168
1006
uint32_t pack_length_to_packflag(uint32_t type)
1171
1009
case 1: return 1 << FIELDFLAG_PACK_SHIFT;
1172
1010
case 2: assert(1);
1173
1011
case 3: assert(1);
1174
case 4: return f_settype(DRIZZLE_TYPE_LONG);
1175
case 8: return f_settype(DRIZZLE_TYPE_LONGLONG);
1012
case 4: return f_settype((uint32_t) DRIZZLE_TYPE_LONG);
1013
case 8: return f_settype((uint32_t) DRIZZLE_TYPE_LONGLONG);
1177
1015
return 0; // This shouldn't happen
1018
Field *make_field(TableShare *share,
1021
uint32_t field_length,
1022
unsigned char *null_pos,
1023
unsigned char null_bit,
1025
enum_field_types field_type,
1026
const CHARSET_INFO * field_charset,
1027
Field::utype unireg_check,
1029
const char *field_name)
1032
root= current_mem_root();
1034
if (!f_maybe_null(pack_flag))
1041
null_bit= ((unsigned char) 1) << null_bit;
1044
switch (field_type) {
1045
case DRIZZLE_TYPE_DATE:
1046
case DRIZZLE_TYPE_DATETIME:
1047
case DRIZZLE_TYPE_TIMESTAMP:
1048
field_charset= &my_charset_bin;
1052
if (f_is_alpha(pack_flag))
1054
if (!f_is_packed(pack_flag))
1056
if (field_type == DRIZZLE_TYPE_VARCHAR)
1057
return new (root) Field_varstring(ptr,field_length,
1058
HA_VARCHAR_PACKLENGTH(field_length),
1060
unireg_check, field_name,
1066
uint32_t pack_length=calc_pack_length((enum_field_types)
1067
f_packtype(pack_flag),
1070
if (f_is_blob(pack_flag))
1071
return new (root) Field_blob(ptr,null_pos,null_bit,
1072
unireg_check, field_name, share,
1073
pack_length, field_charset);
1076
if (f_is_enum(pack_flag))
1078
return new (root) Field_enum(ptr,field_length,null_pos,null_bit,
1079
unireg_check, field_name,
1080
get_enum_pack_length(interval->count),
1081
interval, field_charset);
1086
switch (field_type) {
1087
case DRIZZLE_TYPE_NEWDECIMAL:
1088
return new (root) Field_new_decimal(ptr,field_length,null_pos,null_bit,
1089
unireg_check, field_name,
1090
f_decimals(pack_flag),
1091
f_is_decimal_precision(pack_flag) != 0,
1092
f_is_dec(pack_flag) == 0);
1093
case DRIZZLE_TYPE_DOUBLE:
1094
return new (root) Field_double(ptr,field_length,null_pos,null_bit,
1095
unireg_check, field_name,
1096
f_decimals(pack_flag),
1098
f_is_dec(pack_flag)== 0);
1099
case DRIZZLE_TYPE_TINY:
1101
case DRIZZLE_TYPE_LONG:
1102
return new (root) Field_long(ptr,field_length,null_pos,null_bit,
1103
unireg_check, field_name,
1105
f_is_dec(pack_flag) == 0);
1106
case DRIZZLE_TYPE_LONGLONG:
1107
return new (root) Field_int64_t(ptr,field_length,null_pos,null_bit,
1108
unireg_check, field_name,
1110
f_is_dec(pack_flag) == 0);
1111
case DRIZZLE_TYPE_TIMESTAMP:
1112
return new (root) Field_timestamp(ptr,field_length, null_pos, null_bit,
1113
unireg_check, field_name, share,
1115
case DRIZZLE_TYPE_DATE:
1116
return new (root) Field_date(ptr,null_pos,null_bit,
1117
unireg_check, field_name, field_charset);
1118
case DRIZZLE_TYPE_DATETIME:
1119
return new (root) Field_datetime(ptr,null_pos,null_bit,
1120
unireg_check, field_name, field_charset);
1121
case DRIZZLE_TYPE_NULL:
1122
return new (root) Field_null(ptr, field_length, unireg_check, field_name,
1124
default: // Impossible (Wrong version)
1180
1130
/*****************************************************************************
1181
1131
Warning handling
1182
1132
*****************************************************************************/
1184
1134
bool Field::set_warning(DRIZZLE_ERROR::enum_warning_level level,
1185
drizzled::error_t code,
1186
1136
int cuted_increment)
1220
1169
void Field::set_datetime_warning(DRIZZLE_ERROR::enum_warning_level level,
1221
drizzled::error_t code,
1223
type::timestamp_t ts_type,
1172
enum enum_drizzle_timestamp_type ts_type,
1224
1173
int cuted_increment)
1226
Session *session= (getTable() and getTable()->getSession()) ? getTable()->getSession() : current_session;
1228
if (session->abortOnWarning() or
1175
Session *session= table ? table->in_use : current_session;
1176
if (session->really_abort_on_warning() ||
1229
1177
set_warning(level, code, cuted_increment))
1231
char str_nr[DECIMAL_LONGLONG_DIGITS];
1232
char *str_end= internal::int64_t10_to_str(nr, str_nr, -10);
1180
char *str_end= int64_t10_to_str(nr, str_nr, -10);
1233
1181
make_truncated_value_warning(session, level, str_nr, (uint32_t) (str_end - str_nr),
1234
1182
ts_type, field_name);
1238
1186
void Field::set_datetime_warning(DRIZZLE_ERROR::enum_warning_level level,
1239
const drizzled::error_t code,
1187
const uint32_t code,
1241
type::timestamp_t ts_type)
1189
enum enum_drizzle_timestamp_type ts_type)
1243
Session *session= (getTable() and getTable()->getSession()) ? getTable()->getSession() : current_session;
1245
if (session->abortOnWarning() or
1191
Session *session= table ? table->in_use : current_session;
1192
if (session->really_abort_on_warning() ||
1246
1193
set_warning(level, code, 1))
1248
1195
/* DBL_DIG is enough to print '-[digits].E+###' */
1249
1196
char str_nr[DBL_DIG + 8];
1250
uint32_t str_len= snprintf(str_nr, sizeof(str_nr), "%g", nr);
1197
uint32_t str_len= sprintf(str_nr, "%g", nr);
1251
1198
make_truncated_value_warning(session, level, str_nr, str_len, ts_type,
1256
bool Field::isReadSet() const
1203
bool Field::isReadSet()
1258
1205
return table->isReadSet(field_index);
1277
1224
table->setWriteSet(field_index);
1279
table->clearWriteSet(field_index);
1282
void Field::pack_num(uint64_t arg, unsigned char *destination)
1284
if (not destination)
1287
int64_tstore(destination, arg);
1290
void Field::pack_num(uint32_t arg, unsigned char *destination)
1292
if (not destination)
1295
longstore(destination, arg);
1298
uint64_t Field::unpack_num(uint64_t &destination, const unsigned char *arg) const
1303
int64_tget(destination, arg);
1308
uint32_t Field::unpack_num(uint32_t &destination, const unsigned char *arg) const
1313
longget(destination, arg);
1318
std::ostream& operator<<(std::ostream& output, const Field &field)
1320
output << "Field:(";
1321
output << field.field_name;
1323
output << drizzled::display::type(field.real_type());
1326
if (field.flags & NOT_NULL_FLAG)
1327
output << " NOT_NULL";
1329
if (field.flags & PRI_KEY_FLAG)
1330
output << ", PRIMARY KEY";
1332
if (field.flags & UNIQUE_KEY_FLAG)
1333
output << ", UNIQUE KEY";
1335
if (field.flags & MULTIPLE_KEY_FLAG)
1336
output << ", MULTIPLE KEY";
1338
if (field.flags & BLOB_FLAG)
1341
if (field.flags & UNSIGNED_FLAG)
1342
output << ", UNSIGNED";
1344
if (field.flags & BINARY_FLAG)
1345
output << ", BINARY";
1349
return output; // for multiple << operators.
1352
} /* namespace drizzled */
1226
assert(0); // Not completed