22
23
* @file This file implements the Field class and API
29
#include "drizzled/sql_select.h"
30
#include "drizzled/error.h"
31
#include "drizzled/field/str.h"
32
#include "drizzled/field/num.h"
33
#include "drizzled/field/blob.h"
34
#include "drizzled/field/enum.h"
35
#include "drizzled/field/null.h"
36
#include "drizzled/field/date.h"
37
#include "drizzled/field/decimal.h"
38
#include "drizzled/field/real.h"
39
#include "drizzled/field/double.h"
40
#include "drizzled/field/int32.h"
41
#include "drizzled/field/int64.h"
42
#include "drizzled/field/num.h"
43
#include "drizzled/field/timestamp.h"
44
#include "drizzled/field/datetime.h"
45
#include "drizzled/field/varstring.h"
46
#include "drizzled/field/uuid.h"
47
#include "drizzled/time_functions.h"
48
#include "drizzled/internal/m_string.h"
50
#include "drizzled/display.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>
564
bool Field::is_null(ptrdiff_t row_offset)
749
bool Field::is_null(ptrdiff_t row_offset) const
566
751
return null_ptr ?
567
752
(null_ptr[row_offset] & null_bit ? true : false) :
571
bool Field::is_real_null(ptrdiff_t row_offset)
756
bool Field::is_real_null(ptrdiff_t row_offset) const
573
758
return null_ptr ? (null_ptr[row_offset] & null_bit ? true : false) : false;
576
bool Field::is_null_in_record(const unsigned char *record)
761
bool Field::is_null_in_record(const unsigned char *record) const
580
765
return test(record[(uint32_t) (null_ptr -table->getInsertRecord())] & null_bit);
583
bool Field::is_null_in_record_with_offset(ptrdiff_t with_offset)
768
bool Field::is_null_in_record_with_offset(ptrdiff_t with_offset) const
646
831
unsigned char *null_ptr_arg,
647
832
unsigned char null_bit_arg,
648
833
utype unireg_check_arg,
649
const char *field_name_arg)
834
const char *field_name_arg) :
652
836
null_ptr(null_ptr_arg),
654
838
orig_table(NULL),
655
839
field_name(field_name_arg),
840
comment(NULL_LEX_STRING),
658
843
part_of_key_not_clustered(0),
659
844
part_of_sortkey(0),
660
845
unireg_check(unireg_check_arg),
661
846
field_length(length_arg),
847
flags(null_ptr ? 0: NOT_NULL_FLAG),
662
849
null_bit(null_bit_arg),
663
850
is_created_from_null_item(false)
665
flags= null_ptr ? 0: NOT_NULL_FLAG;
666
comment.str= (char*) "";
671
void Field::hash(uint32_t *nr, uint32_t *nr2)
854
void Field::hash(uint32_t *nr, uint32_t *nr2) const
795
978
field->decimals= 0;
798
int64_t Field::convert_decimal2int64_t(const my_decimal *val, bool, int *err)
981
int64_t Field::convert_decimal2int64_t(const type::Decimal *val, bool, int *err)
801
if (warn_if_overflow(my_decimal2int(E_DEC_ERROR &
984
if (warn_if_overflow(val->val_int32(E_DEC_ERROR &
802
985
~E_DEC_OVERFLOW & ~E_DEC_TRUNCATED,
805
988
i= (val->sign() ? INT64_MIN : INT64_MAX);
829
1012
return copy->length+ store_length;
832
bool Field::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
835
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
836
if (!(res=val_str_internal(&tmp)) || str_to_datetime_with_warn(res->ptr(), res->length(),
837
ltime, fuzzydate) <= DRIZZLE_TIMESTAMP_ERROR)
845
bool Field::get_time(DRIZZLE_TIME *ltime)
848
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
850
if (!(res=val_str_internal(&tmp)) || str_to_time_with_warn(res->ptr(), res->length(), ltime))
858
int Field::store_time(DRIZZLE_TIME *ltime, enum enum_drizzle_timestamp_type)
860
char buff[MAX_DATE_STRING_REP_LENGTH];
861
uint32_t length= (uint32_t) my_TIME_to_str(ltime, buff);
862
return store(buff, length, &my_charset_bin);
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);
865
1056
bool Field::optimize_range(uint32_t idx, uint32_t)
931
1122
if (!Field::eq_def(field))
933
1125
TYPELIB *from_lib=((Field_enum*) field)->typelib;
935
1127
if (typelib->count < from_lib->count)
937
1130
for (uint32_t i=0 ; i < from_lib->count ; i++)
938
1132
if (my_strnncoll(field_charset,
939
1133
(const unsigned char*)typelib->type_names[i],
940
1134
strlen(typelib->type_names[i]),
941
1135
(const unsigned char*)from_lib->type_names[i],
942
1136
strlen(from_lib->type_names[i])))
950
1146
case DRIZZLE_TYPE_VARCHAR: return (length + (length < 256 ? 1: 2));
951
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();
952
1151
case DRIZZLE_TYPE_DATE:
953
1152
case DRIZZLE_TYPE_ENUM:
954
1153
case DRIZZLE_TYPE_LONG: return 4;
955
1154
case DRIZZLE_TYPE_DOUBLE: return sizeof(double);
1155
case DRIZZLE_TYPE_TIME:
956
1156
case DRIZZLE_TYPE_DATETIME:
957
case DRIZZLE_TYPE_TIMESTAMP:
958
1157
case DRIZZLE_TYPE_LONGLONG: return 8; /* Don't crash if no int64_t */
959
1158
case DRIZZLE_TYPE_NULL: return 0;
960
1159
case DRIZZLE_TYPE_BLOB: return 4 + portable_sizeof_char_ptr;
961
1160
case DRIZZLE_TYPE_DECIMAL:
1006
1204
void Field::set_datetime_warning(DRIZZLE_ERROR::enum_warning_level level,
1205
drizzled::error_t code,
1008
1206
const char *str,
1009
1207
uint32_t str_length,
1010
enum enum_drizzle_timestamp_type ts_type,
1208
type::timestamp_t ts_type,
1011
1209
int cuted_increment)
1013
Session *session= table ? table->in_use : current_session;
1014
if ((session->really_abort_on_warning() &&
1211
Session *session= (getTable() and getTable()->getSession()) ? getTable()->getSession() : current_session;
1213
if ((session->abortOnWarning() and
1015
1214
level >= DRIZZLE_ERROR::WARN_LEVEL_WARN) ||
1016
1215
set_warning(level, code, cuted_increment))
1017
1216
make_truncated_value_warning(session, level, str, str_length, ts_type,
1021
1220
void Field::set_datetime_warning(DRIZZLE_ERROR::enum_warning_level level,
1221
drizzled::error_t code,
1024
enum enum_drizzle_timestamp_type ts_type,
1223
type::timestamp_t ts_type,
1025
1224
int cuted_increment)
1027
Session *session= table ? table->in_use : current_session;
1028
if (session->really_abort_on_warning() ||
1226
Session *session= (getTable() and getTable()->getSession()) ? getTable()->getSession() : current_session;
1228
if (session->abortOnWarning() or
1029
1229
set_warning(level, code, cuted_increment))
1231
char str_nr[DECIMAL_LONGLONG_DIGITS];
1032
1232
char *str_end= internal::int64_t10_to_str(nr, str_nr, -10);
1033
1233
make_truncated_value_warning(session, level, str_nr, (uint32_t) (str_end - str_nr),
1034
1234
ts_type, field_name);
1038
1238
void Field::set_datetime_warning(DRIZZLE_ERROR::enum_warning_level level,
1039
const uint32_t code,
1239
const drizzled::error_t code,
1041
enum enum_drizzle_timestamp_type ts_type)
1241
type::timestamp_t ts_type)
1043
Session *session= table ? table->in_use : current_session;
1044
if (session->really_abort_on_warning() ||
1243
Session *session= (getTable() and getTable()->getSession()) ? getTable()->getSession() : current_session;
1245
if (session->abortOnWarning() or
1045
1246
set_warning(level, code, 1))
1047
1248
/* DBL_DIG is enough to print '-[digits].E+###' */
1078
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);
1081
1318
std::ostream& operator<<(std::ostream& output, const Field &field)
1083
1320
output << "Field:(";
1084
1321
output << field.field_name;
1085
1322
output << ", ";
1086
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";
1089
1349
return output; // for multiple << operators.