00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <config.h>
00029
00030 #include <pthread.h>
00031 #include <float.h>
00032
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <fcntl.h>
00036
00037
00038 #include <cassert>
00039
00040 #include <drizzled/error.h>
00041 #include <drizzled/gettext.h>
00042 #include <drizzled/sql_base.h>
00043 #include <drizzled/pthread_globals.h>
00044 #include <drizzled/internal/my_pthread.h>
00045
00046 #include <drizzled/table.h>
00047 #include <drizzled/table/shell.h>
00048
00049 #include <drizzled/session.h>
00050
00051 #include <drizzled/charset.h>
00052 #include <drizzled/internal/m_string.h>
00053 #include <drizzled/internal/my_sys.h>
00054
00055 #include <drizzled/item/string.h>
00056 #include <drizzled/item/int.h>
00057 #include <drizzled/item/decimal.h>
00058 #include <drizzled/item/float.h>
00059 #include <drizzled/item/null.h>
00060 #include <drizzled/temporal.h>
00061
00062 #include <drizzled/field.h>
00063 #include <drizzled/field/str.h>
00064 #include <drizzled/field/num.h>
00065 #include <drizzled/field/blob.h>
00066 #include <drizzled/field/boolean.h>
00067 #include <drizzled/field/enum.h>
00068 #include <drizzled/field/null.h>
00069 #include <drizzled/field/date.h>
00070 #include <drizzled/field/decimal.h>
00071 #include <drizzled/field/real.h>
00072 #include <drizzled/field/double.h>
00073 #include <drizzled/field/int32.h>
00074 #include <drizzled/field/int64.h>
00075 #include <drizzled/field/size.h>
00076 #include <drizzled/field/num.h>
00077 #include <drizzled/field/time.h>
00078 #include <drizzled/field/epoch.h>
00079 #include <drizzled/field/datetime.h>
00080 #include <drizzled/field/microtime.h>
00081 #include <drizzled/field/varstring.h>
00082 #include <drizzled/field/uuid.h>
00083 #include <drizzled/field/ipv6.h>
00084 #include <drizzled/plugin/storage_engine.h>
00085 #include <drizzled/definition/cache.h>
00086 #include <drizzled/typelib.h>
00087 #include <drizzled/key.h>
00088 #include <drizzled/open_tables_state.h>
00089
00090 using namespace std;
00091
00092 namespace drizzled {
00093
00094 extern size_t table_def_size;
00095
00096 static enum_field_types proto_field_type_to_drizzle_type(const message::Table::Field &field)
00097 {
00098 switch(field.type())
00099 {
00100 case message::Table::Field::INTEGER:
00101 return DRIZZLE_TYPE_LONG;
00102
00103 case message::Table::Field::DOUBLE:
00104 return DRIZZLE_TYPE_DOUBLE;
00105
00106 case message::Table::Field::EPOCH:
00107 if (field.has_time_options() and field.time_options().microseconds())
00108 return DRIZZLE_TYPE_MICROTIME;
00109
00110 return DRIZZLE_TYPE_TIMESTAMP;
00111
00112 case message::Table::Field::BIGINT:
00113 return DRIZZLE_TYPE_LONGLONG;
00114
00115 case message::Table::Field::DATETIME:
00116 return DRIZZLE_TYPE_DATETIME;
00117
00118 case message::Table::Field::DATE:
00119 return DRIZZLE_TYPE_DATE;
00120
00121 case message::Table::Field::VARCHAR:
00122 return DRIZZLE_TYPE_VARCHAR;
00123
00124 case message::Table::Field::DECIMAL:
00125 return DRIZZLE_TYPE_DECIMAL;
00126
00127 case message::Table::Field::ENUM:
00128 return DRIZZLE_TYPE_ENUM;
00129
00130 case message::Table::Field::BLOB:
00131 return DRIZZLE_TYPE_BLOB;
00132
00133 case message::Table::Field::UUID:
00134 return DRIZZLE_TYPE_UUID;
00135
00136 case message::Table::Field::IPV6:
00137 return DRIZZLE_TYPE_IPV6;
00138
00139 case message::Table::Field::BOOLEAN:
00140 return DRIZZLE_TYPE_BOOLEAN;
00141
00142 case message::Table::Field::TIME:
00143 return DRIZZLE_TYPE_TIME;
00144 }
00145
00146 abort();
00147 }
00148
00149 static Item* default_value_item(enum_field_types field_type, const charset_info_st& charset, bool default_null,
00150 const string& default_value, const string& default_bin_value)
00151 {
00152 if (default_null)
00153 return new Item_null();
00154
00155 switch (field_type)
00156 {
00157 case DRIZZLE_TYPE_LONG:
00158 case DRIZZLE_TYPE_LONGLONG:
00159 {
00160 int error= 0;
00161 Item* default_item= new Item_int(default_value.c_str(), (int64_t) internal::my_strtoll10(default_value.c_str(), NULL, &error), default_value.length());
00162
00163 if (error && error != -1)
00164 {
00165 delete default_item;
00166 return NULL;
00167 }
00168 return default_item;
00169 }
00170 case DRIZZLE_TYPE_DOUBLE:
00171 return new Item_float(default_value.c_str(), default_value.length());
00172 case DRIZZLE_TYPE_NULL:
00173 assert(false);
00174 abort();
00175 case DRIZZLE_TYPE_TIMESTAMP:
00176 case DRIZZLE_TYPE_DATETIME:
00177 case DRIZZLE_TYPE_TIME:
00178 case DRIZZLE_TYPE_DATE:
00179 case DRIZZLE_TYPE_ENUM:
00180 case DRIZZLE_TYPE_UUID:
00181 case DRIZZLE_TYPE_IPV6:
00182 case DRIZZLE_TYPE_MICROTIME:
00183 case DRIZZLE_TYPE_BOOLEAN:
00184
00185 return new Item_string(default_value.data(), default_value.size(), system_charset_info);
00186 case DRIZZLE_TYPE_VARCHAR:
00187 case DRIZZLE_TYPE_BLOB:
00188 return &charset== &my_charset_bin
00189 ? new Item_string(default_bin_value, &my_charset_bin)
00190 : new Item_string(default_value, system_charset_info);
00191 case DRIZZLE_TYPE_DECIMAL:
00192 return new Item_decimal(default_value.c_str(), default_value.length(), system_charset_info);
00193 }
00194 return NULL;
00195 }
00196
00197
00198
00204 bool TableShare::fieldInPrimaryKey(Field *in_field) const
00205 {
00206 assert(getTableMessage());
00207
00208 size_t num_indexes= getTableMessage()->indexes_size();
00209
00210 for (size_t x= 0; x < num_indexes; ++x)
00211 {
00212 const message::Table::Index &index= getTableMessage()->indexes(x);
00213 if (index.is_primary())
00214 {
00215 size_t num_parts= index.index_part_size();
00216 for (size_t y= 0; y < num_parts; ++y)
00217 {
00218 if (index.index_part(y).fieldnr() == in_field->position())
00219 return true;
00220 }
00221 }
00222 }
00223 return false;
00224 }
00225
00226 TableShare::TableShare(const identifier::Table::Type type_arg) :
00227 table_category(TABLE_UNKNOWN_CATEGORY),
00228 found_next_number_field(NULL),
00229 timestamp_field(NULL),
00230 key_info(NULL),
00231 mem_root(TABLE_ALLOC_BLOCK_SIZE),
00232 all_set(),
00233 block_size(0),
00234 version(0),
00235 timestamp_offset(0),
00236 reclength(0),
00237 stored_rec_length(0),
00238 max_rows(0),
00239 _table_message(NULL),
00240 storage_engine(NULL),
00241 tmp_table(type_arg),
00242 _ref_count(0),
00243 null_bytes(0),
00244 last_null_bit_pos(0),
00245 _field_size(0),
00246 rec_buff_length(0),
00247 keys(0),
00248 key_parts(0),
00249 max_key_length(0),
00250 max_unique_length(0),
00251 total_key_length(0),
00252 uniques(0),
00253 null_fields(0),
00254 blob_fields(0),
00255 has_variable_width(false),
00256 db_create_options(0),
00257 db_options_in_use(0),
00258 db_record_offset(0),
00259 rowid_field_offset(0),
00260 primary_key(MAX_KEY),
00261 next_number_index(0),
00262 next_number_key_offset(0),
00263 next_number_keypart(0),
00264 error(0),
00265 open_errno(0),
00266 errarg(0),
00267 blob_ptr_size(portable_sizeof_char_ptr),
00268 db_low_byte_first(false),
00269 keys_in_use(0),
00270 keys_for_keyread(0)
00271 {
00272 if (type_arg == message::Table::INTERNAL)
00273 {
00274 string s= identifier::Table::build_tmptable_filename();
00275 private_key_for_cache.vectorPtr().assign(s.c_str(), s.c_str() + s.size() + 1);
00276 init(private_key_for_cache.vector(), private_key_for_cache.vector());
00277 }
00278 else
00279 {
00280 init("", "");
00281 }
00282 }
00283
00284 TableShare::TableShare(const identifier::Table &identifier, const identifier::Table::Key &key) :
00285 table_category(TABLE_UNKNOWN_CATEGORY),
00286 found_next_number_field(NULL),
00287 timestamp_field(NULL),
00288 key_info(NULL),
00289 mem_root(TABLE_ALLOC_BLOCK_SIZE),
00290 table_charset(0),
00291 all_set(),
00292 block_size(0),
00293 version(0),
00294 timestamp_offset(0),
00295 reclength(0),
00296 stored_rec_length(0),
00297 max_rows(0),
00298 _table_message(NULL),
00299 storage_engine(NULL),
00300 tmp_table(message::Table::INTERNAL),
00301 _ref_count(0),
00302 null_bytes(0),
00303 last_null_bit_pos(0),
00304 _field_size(0),
00305 rec_buff_length(0),
00306 keys(0),
00307 key_parts(0),
00308 max_key_length(0),
00309 max_unique_length(0),
00310 total_key_length(0),
00311 uniques(0),
00312 null_fields(0),
00313 blob_fields(0),
00314 has_variable_width(false),
00315 db_create_options(0),
00316 db_options_in_use(0),
00317 db_record_offset(0),
00318 rowid_field_offset(0),
00319 primary_key(MAX_KEY),
00320 next_number_index(0),
00321 next_number_key_offset(0),
00322 next_number_keypart(0),
00323 error(0),
00324 open_errno(0),
00325 errarg(0),
00326 blob_ptr_size(portable_sizeof_char_ptr),
00327 db_low_byte_first(false),
00328 keys_in_use(0),
00329 keys_for_keyread(0)
00330 {
00331 assert(identifier.getKey() == key);
00332
00333 private_key_for_cache= key;
00334
00335 table_category= TABLE_CATEGORY_TEMPORARY;
00336 tmp_table= message::Table::INTERNAL;
00337
00338 db= str_ref(private_key_for_cache.vector() + strlen(private_key_for_cache.vector()) + 1);
00339
00340 table_name= str_ref(db.data() + strlen(db.data()) + 1);
00341 path= str_ref("");
00342 normalized_path= str_ref("");
00343
00344 std::string tb_name(identifier.getTableName());
00345 boost::to_lower(tb_name);
00346 assert(strcmp(tb_name.c_str(), table_name.data()) == 0);
00347 assert(strcmp(identifier.getSchemaName().c_str(), db.data()) == 0);
00348 }
00349
00350 TableShare::TableShare(const identifier::Table &identifier) :
00351 table_category(TABLE_UNKNOWN_CATEGORY),
00352 found_next_number_field(NULL),
00353 timestamp_field(NULL),
00354 key_info(NULL),
00355 mem_root(TABLE_ALLOC_BLOCK_SIZE),
00356 table_charset(0),
00357 all_set(),
00358 block_size(0),
00359 version(0),
00360 timestamp_offset(0),
00361 reclength(0),
00362 stored_rec_length(0),
00363 max_rows(0),
00364 _table_message(NULL),
00365 storage_engine(NULL),
00366 tmp_table(identifier.getType()),
00367 _ref_count(0),
00368 null_bytes(0),
00369 last_null_bit_pos(0),
00370 _field_size(0),
00371 rec_buff_length(0),
00372 keys(0),
00373 key_parts(0),
00374 max_key_length(0),
00375 max_unique_length(0),
00376 total_key_length(0),
00377 uniques(0),
00378 null_fields(0),
00379 blob_fields(0),
00380 has_variable_width(false),
00381 db_create_options(0),
00382 db_options_in_use(0),
00383 db_record_offset(0),
00384 rowid_field_offset(0),
00385 primary_key(MAX_KEY),
00386 next_number_index(0),
00387 next_number_key_offset(0),
00388 next_number_keypart(0),
00389 error(0),
00390 open_errno(0),
00391 errarg(0),
00392 blob_ptr_size(portable_sizeof_char_ptr),
00393 db_low_byte_first(false),
00394 keys_in_use(0),
00395 keys_for_keyread(0)
00396 {
00397 private_key_for_cache= identifier.getKey();
00398 assert(identifier.getPath().size());
00399 private_normalized_path.resize(identifier.getPath().size() + 1);
00400 memcpy(&private_normalized_path[0], identifier.getPath().c_str(), identifier.getPath().size());
00401
00402 {
00403 table_category= TABLE_CATEGORY_TEMPORARY;
00404 tmp_table= message::Table::INTERNAL;
00405 db= str_ref(private_key_for_cache.vector());
00406 table_name= str_ref(db.data() + 1);
00407 path= private_normalized_path;
00408 normalized_path= path;
00409 }
00410 }
00411
00412
00413
00414
00415
00416 TableShare::TableShare(const identifier::Table::Type type_arg,
00417 const identifier::Table &identifier,
00418 const char *path_arg,
00419 uint32_t path_length_arg) :
00420 table_category(TABLE_UNKNOWN_CATEGORY),
00421 found_next_number_field(NULL),
00422 timestamp_field(NULL),
00423 key_info(NULL),
00424 mem_root(TABLE_ALLOC_BLOCK_SIZE),
00425 table_charset(0),
00426 all_set(),
00427 block_size(0),
00428 version(0),
00429 timestamp_offset(0),
00430 reclength(0),
00431 stored_rec_length(0),
00432 max_rows(0),
00433 _table_message(NULL),
00434 storage_engine(NULL),
00435 tmp_table(type_arg),
00436 _ref_count(0),
00437 null_bytes(0),
00438 last_null_bit_pos(0),
00439 _field_size(0),
00440 rec_buff_length(0),
00441 keys(0),
00442 key_parts(0),
00443 max_key_length(0),
00444 max_unique_length(0),
00445 total_key_length(0),
00446 uniques(0),
00447 null_fields(0),
00448 blob_fields(0),
00449 has_variable_width(false),
00450 db_create_options(0),
00451 db_options_in_use(0),
00452 db_record_offset(0),
00453 rowid_field_offset(0),
00454 primary_key(MAX_KEY),
00455 next_number_index(0),
00456 next_number_key_offset(0),
00457 next_number_keypart(0),
00458 error(0),
00459 open_errno(0),
00460 errarg(0),
00461 blob_ptr_size(portable_sizeof_char_ptr),
00462 db_low_byte_first(false),
00463 keys_in_use(0),
00464 keys_for_keyread(0)
00465 {
00466
00467 private_key_for_cache= identifier.getKey();
00468
00469
00470
00471
00472 db= str_ref(private_key_for_cache.vector() + strlen(private_key_for_cache.vector()) + 1);
00473 table_name= str_ref(db.data() + db.size() + 1);
00474
00475 std::string _path;
00476 if (path_arg)
00477 {
00478 _path.assign(path_arg, path_length_arg);
00479 }
00480 else
00481 {
00482 _path= identifier::Table::build_table_filename(db.data(), table_name.data(), false);
00483 }
00484
00485 char* path_buff= mem_root.strdup(_path);
00486 path= str_ref(path_buff, _path.length());
00487 normalized_path= str_ref(path_buff, _path.length());
00488
00489 version= g_refresh_version;
00490 }
00491
00492 void TableShare::init(const char *new_table_name, const char *new_path)
00493 {
00494 table_category= TABLE_CATEGORY_TEMPORARY;
00495 tmp_table= message::Table::INTERNAL;
00496 db= str_ref("");
00497 table_name= str_ref(new_table_name);
00498 path= str_ref(new_path);
00499 normalized_path= str_ref(new_path);
00500 }
00501
00502 TableShare::~TableShare()
00503 {
00504 storage_engine= NULL;
00505
00506 mem_root.free_root(MYF(0));
00507 }
00508
00509 void TableShare::setIdentifier(const identifier::Table &identifier_arg)
00510 {
00511 private_key_for_cache= identifier_arg.getKey();
00512
00513
00514
00515
00516
00517 db= str_ref(private_key_for_cache.vector() + strlen(private_key_for_cache.vector()) + 1);
00518 table_name= str_ref(db.data() + db.size() + 1);
00519
00520 getTableMessage()->set_name(identifier_arg.getTableName());
00521 getTableMessage()->set_schema(identifier_arg.getSchemaName());
00522 }
00523
00524 bool TableShare::parse_table_proto(Session& session, const message::Table &table)
00525 {
00526 drizzled::error_t local_error= EE_OK;
00527
00528 if (! table.IsInitialized())
00529 {
00530 my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
00531 table.name().empty() ? " " : table.name().c_str(),
00532 table.InitializationErrorString().c_str());
00533
00534 return ER_CORRUPT_TABLE_DEFINITION;
00535 }
00536
00537 setTableMessage(table);
00538
00539 storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
00540 assert(storage_engine);
00541
00542 message::Table::TableOptions table_options;
00543
00544 if (table.has_options())
00545 table_options= table.options();
00546
00547 uint32_t local_db_create_options= 0;
00548
00549 if (table_options.pack_record())
00550 local_db_create_options|= HA_OPTION_PACK_RECORD;
00551
00552
00553
00554
00555 db_create_options= (local_db_create_options & 0x0000FFFF);
00556 db_options_in_use= db_create_options;
00557
00558 block_size= table_options.has_block_size() ? table_options.block_size() : 0;
00559
00560 table_charset= get_charset(table_options.collation_id());
00561
00562 if (not table_charset)
00563 {
00564 my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN_COLLATION, MYF(0),
00565 table_options.collation().c_str(),
00566 table.name().c_str());
00567
00568 return ER_CORRUPT_TABLE_DEFINITION;
00569 }
00570
00571 db_record_offset= 1;
00572
00573 keys= table.indexes_size();
00574
00575 key_parts= 0;
00576 for (int indx= 0; indx < table.indexes_size(); indx++)
00577 key_parts+= table.indexes(indx).index_part_size();
00578
00579 key_info= (KeyInfo*) mem().alloc(table.indexes_size() * sizeof(KeyInfo) +key_parts*sizeof(KeyPartInfo));
00580
00581 KeyPartInfo *key_part;
00582
00583 key_part= reinterpret_cast<KeyPartInfo*>
00584 (key_info+table.indexes_size());
00585
00586
00587 ulong *rec_per_key= (ulong*) mem().alloc(sizeof(ulong*)*key_parts);
00588
00589 KeyInfo* keyinfo= key_info;
00590 for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
00591 {
00592 message::Table::Index indx= table.indexes(keynr);
00593
00594 keyinfo->table= 0;
00595 keyinfo->flags= 0;
00596
00597 if (indx.is_unique())
00598 keyinfo->flags|= HA_NOSAME;
00599
00600 if (indx.has_options())
00601 {
00602 message::Table::Index::Options indx_options= indx.options();
00603 if (indx_options.pack_key())
00604 keyinfo->flags|= HA_PACK_KEY;
00605
00606 if (indx_options.var_length_key())
00607 keyinfo->flags|= HA_VAR_LENGTH_PART;
00608
00609 if (indx_options.null_part_key())
00610 keyinfo->flags|= HA_NULL_PART_KEY;
00611
00612 if (indx_options.binary_pack_key())
00613 keyinfo->flags|= HA_BINARY_PACK_KEY;
00614
00615 if (indx_options.has_partial_segments())
00616 keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
00617
00618 if (indx_options.auto_generated_key())
00619 keyinfo->flags|= HA_GENERATED_KEY;
00620
00621 if (indx_options.has_key_block_size())
00622 {
00623 keyinfo->flags|= HA_USES_BLOCK_SIZE;
00624 keyinfo->block_size= indx_options.key_block_size();
00625 }
00626 else
00627 {
00628 keyinfo->block_size= 0;
00629 }
00630 }
00631
00632 switch (indx.type())
00633 {
00634 case message::Table::Index::UNKNOWN_INDEX:
00635 keyinfo->algorithm= HA_KEY_ALG_UNDEF;
00636 break;
00637 case message::Table::Index::BTREE:
00638 keyinfo->algorithm= HA_KEY_ALG_BTREE;
00639 break;
00640 case message::Table::Index::HASH:
00641 keyinfo->algorithm= HA_KEY_ALG_HASH;
00642 break;
00643
00644 default:
00645
00646 keyinfo->algorithm= HA_KEY_ALG_UNDEF;
00647 break;
00648 }
00649
00650 keyinfo->key_length= indx.key_length();
00651
00652 keyinfo->key_parts= indx.index_part_size();
00653
00654 keyinfo->key_part= key_part;
00655 keyinfo->rec_per_key= rec_per_key;
00656
00657 for (unsigned int partnr= 0;
00658 partnr < keyinfo->key_parts;
00659 partnr++, key_part++)
00660 {
00661 message::Table::Index::IndexPart part;
00662 part= indx.index_part(partnr);
00663
00664 *rec_per_key++= 0;
00665
00666 key_part->field= NULL;
00667 key_part->fieldnr= part.fieldnr() + 1;
00668 key_part->null_bit= 0;
00669
00670
00671
00672 key_part->key_part_flag= 0;
00673 if (part.has_in_reverse_order())
00674 key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
00675
00676 key_part->length= part.compare_length();
00677
00678 int mbmaxlen= 1;
00679
00680 if (table.field(part.fieldnr()).type() == message::Table::Field::VARCHAR
00681 || table.field(part.fieldnr()).type() == message::Table::Field::BLOB)
00682 {
00683 uint32_t collation_id;
00684
00685 if (table.field(part.fieldnr()).string_options().has_collation_id())
00686 collation_id= table.field(part.fieldnr()).string_options().collation_id();
00687 else
00688 collation_id= table.options().collation_id();
00689
00690 const charset_info_st *cs= get_charset(collation_id);
00691
00692 mbmaxlen= cs->mbmaxlen;
00693 }
00694 key_part->length*= mbmaxlen;
00695
00696 key_part->store_length= key_part->length;
00697
00698
00699 key_part->key_type= 0;
00700 }
00701
00702 if (not indx.has_comment())
00703 {
00704 keyinfo->comment.clear();
00705 }
00706 else
00707 {
00708 keyinfo->flags|= HA_USES_COMMENT;
00709 keyinfo->comment.assign(mem().strdup(indx.comment()), indx.comment().length());
00710 }
00711
00712 keyinfo->name= mem().strdup(indx.name());
00713
00714 addKeyName(string(keyinfo->name, indx.name().length()));
00715 }
00716
00717 keys_for_keyread.reset();
00718 set_prefix(keys_in_use, keys);
00719
00720 _field_size= table.field_size();
00721
00722 setFields(_field_size + 1);
00723 _fields[_field_size]= NULL;
00724
00725 uint32_t local_null_fields= 0;
00726 reclength= 0;
00727
00728 std::vector<uint32_t> field_offsets;
00729 std::vector<uint32_t> field_pack_length;
00730
00731 field_offsets.resize(_field_size);
00732 field_pack_length.resize(_field_size);
00733
00734 uint32_t interval_count= 0;
00735 uint32_t interval_parts= 0;
00736
00737 uint32_t stored_columns_reclength= 0;
00738
00739 for (unsigned int fieldnr= 0; fieldnr < _field_size; fieldnr++)
00740 {
00741 message::Table::Field pfield= table.field(fieldnr);
00742 if (pfield.constraints().is_nullable())
00743 {
00744 local_null_fields++;
00745 }
00746 else if (not pfield.constraints().is_notnull())
00747 {
00748 local_null_fields++;
00749 }
00750
00751 enum_field_types drizzle_field_type= proto_field_type_to_drizzle_type(pfield);
00752
00753 field_offsets[fieldnr]= stored_columns_reclength;
00754
00755
00756
00757
00758
00759 switch(drizzle_field_type)
00760 {
00761 case DRIZZLE_TYPE_BLOB:
00762 case DRIZZLE_TYPE_VARCHAR:
00763 {
00764 message::Table::Field::StringFieldOptions field_options= pfield.string_options();
00765
00766 const charset_info_st *cs= get_charset(field_options.has_collation_id() ?
00767 field_options.collation_id() : 0);
00768
00769 if (! cs)
00770 cs= default_charset_info;
00771
00772 field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
00773 field_options.length() * cs->mbmaxlen);
00774 }
00775 break;
00776 case DRIZZLE_TYPE_ENUM:
00777 {
00778 message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
00779
00780 field_pack_length[fieldnr]= 4;
00781
00782 interval_count++;
00783 interval_parts+= field_options.field_value_size();
00784 }
00785 break;
00786 case DRIZZLE_TYPE_DECIMAL:
00787 {
00788 message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
00789
00790 field_pack_length[fieldnr]= class_decimal_get_binary_size(fo.precision(), fo.scale());
00791 }
00792 break;
00793 default:
00794
00795 field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
00796 }
00797
00798 reclength+= field_pack_length[fieldnr];
00799 stored_columns_reclength+= field_pack_length[fieldnr];
00800 }
00801
00802
00803 stored_rec_length= stored_columns_reclength;
00804
00805 null_fields= local_null_fields;
00806
00807 ulong null_bits= local_null_fields;
00808 if (! table_options.pack_record())
00809 null_bits++;
00810 ulong data_offset= (null_bits + 7)/8;
00811
00812
00813 reclength+= data_offset;
00814 stored_rec_length+= data_offset;
00815
00816 ulong local_rec_buff_length;
00817
00818 local_rec_buff_length= ALIGN_SIZE(reclength + 1);
00819 rec_buff_length= local_rec_buff_length;
00820
00821 resizeDefaultValues(local_rec_buff_length);
00822 unsigned char* record= getDefaultValues();
00823 int null_count= 0;
00824
00825 if (! table_options.pack_record())
00826 {
00827 null_count++;
00828 *record|= 1;
00829 }
00830
00831
00832 intervals.resize(interval_count);
00833
00834
00835
00836
00837
00838 uint32_t interval_nr= 0;
00839
00840 for (unsigned int fieldnr= 0; fieldnr < _field_size; fieldnr++)
00841 {
00842 message::Table::Field pfield= table.field(fieldnr);
00843
00844
00845 if (pfield.type() != message::Table::Field::ENUM)
00846 continue;
00847
00848 message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
00849
00850 if (field_options.field_value_size() > Field_enum::max_supported_elements)
00851 {
00852 my_error(ER_CORRUPT_TABLE_DEFINITION_ENUM, MYF(0), table.name().c_str());
00853
00854 return ER_CORRUPT_TABLE_DEFINITION_ENUM;
00855 }
00856
00857
00858 const charset_info_st *charset= get_charset(field_options.has_collation_id() ?
00859 field_options.collation_id() : 0);
00860
00861 if (! charset)
00862 charset= default_charset_info;
00863
00864 TYPELIB *t= (&intervals[interval_nr]);
00865
00866 t->type_names= (const char**)mem().alloc((field_options.field_value_size() + 1) * sizeof(char*));
00867 t->type_lengths= (unsigned int*)mem().alloc((field_options.field_value_size() + 1) * sizeof(unsigned int));
00868
00869 t->type_names[field_options.field_value_size()]= NULL;
00870 t->type_lengths[field_options.field_value_size()]= 0;
00871
00872 t->count= field_options.field_value_size();
00873 t->name= NULL;
00874
00875 for (int n= 0; n < field_options.field_value_size(); n++)
00876 {
00877 t->type_names[n]= mem().strdup(field_options.field_value(n));
00878
00879
00880
00881
00882
00883 t->type_lengths[n]= charset->cset->lengthsp(charset, t->type_names[n], field_options.field_value(n).length());
00884 }
00885 interval_nr++;
00886 }
00887
00888
00889
00890 interval_nr= 0;
00891
00892 bool use_hash= _field_size >= MAX_FIELDS_BEFORE_HASH;
00893
00894 unsigned char* null_pos= getDefaultValues();
00895 int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
00896
00897 for (unsigned int fieldnr= 0; fieldnr < _field_size; fieldnr++)
00898 {
00899 message::Table::Field pfield= table.field(fieldnr);
00900
00901 Field::utype unireg_type= Field::NONE;
00902
00903 if (pfield.has_numeric_options() &&
00904 pfield.numeric_options().is_autoincrement())
00905 {
00906 unireg_type= Field::NEXT_NUMBER;
00907 }
00908
00909 if (pfield.has_options() &&
00910 pfield.options().has_default_expression() &&
00911 pfield.options().default_expression().compare("CURRENT_TIMESTAMP") == 0)
00912 {
00913 if (pfield.options().has_update_expression() &&
00914 pfield.options().update_expression().compare("CURRENT_TIMESTAMP") == 0)
00915 {
00916 unireg_type= Field::TIMESTAMP_DNUN_FIELD;
00917 }
00918 else if (! pfield.options().has_update_expression())
00919 {
00920 unireg_type= Field::TIMESTAMP_DN_FIELD;
00921 }
00922 else
00923 {
00924 assert(0);
00925 abort();
00926 }
00927 }
00928 else if (pfield.has_options() &&
00929 pfield.options().has_update_expression() &&
00930 pfield.options().update_expression().compare("CURRENT_TIMESTAMP") == 0)
00931 {
00932 unireg_type= Field::TIMESTAMP_UN_FIELD;
00933 }
00934
00935 str_ref comment;
00936 if (pfield.has_comment())
00937 {
00938 comment.assign(mem().strdup(pfield.comment()), pfield.comment().size());
00939 }
00940
00941 enum_field_types field_type;
00942
00943 field_type= proto_field_type_to_drizzle_type(pfield);
00944
00945 const charset_info_st *charset= &my_charset_bin;
00946
00947 if (field_type == DRIZZLE_TYPE_BLOB || field_type == DRIZZLE_TYPE_VARCHAR)
00948 {
00949 message::Table::Field::StringFieldOptions field_options= pfield.string_options();
00950
00951 charset= get_charset(field_options.has_collation_id() ? field_options.collation_id() : 0);
00952
00953 if (not charset)
00954 charset= default_charset_info;
00955 }
00956
00957 if (field_type == DRIZZLE_TYPE_ENUM)
00958 {
00959 message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
00960
00961 charset= get_charset(field_options.has_collation_id() ? field_options.collation_id() : 0);
00962
00963 if (not charset)
00964 charset= default_charset_info;
00965 }
00966
00967 uint8_t decimals= 0;
00968 if (field_type == DRIZZLE_TYPE_DECIMAL || field_type == DRIZZLE_TYPE_DOUBLE)
00969 {
00970 message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
00971
00972 if (not pfield.has_numeric_options() || ! fo.has_scale())
00973 {
00974
00975
00976
00977
00978 decimals= NOT_FIXED_DEC;
00979 }
00980 else
00981 {
00982 if (fo.scale() > DECIMAL_MAX_SCALE)
00983 {
00984 local_error= ER_NOT_FORM_FILE;
00985
00986 return true;
00987 }
00988 decimals= static_cast<uint8_t>(fo.scale());
00989 }
00990 }
00991
00992 Item *default_value= NULL;
00993
00994 if (pfield.options().has_default_value() ||
00995 pfield.options().default_null() ||
00996 pfield.options().has_default_bin_value())
00997 {
00998 default_value= default_value_item(field_type, *charset, pfield.options().default_null(), pfield.options().default_value(), pfield.options().default_bin_value());
00999 if (default_value == NULL)
01000 {
01001 my_error(ER_INVALID_DEFAULT, MYF(0), pfield.name().c_str());
01002 return true;
01003 }
01004 }
01005
01006
01007 uint32_t field_length= 0;
01008
01009
01010 switch (field_type)
01011 {
01012 case DRIZZLE_TYPE_BLOB:
01013 case DRIZZLE_TYPE_VARCHAR:
01014 {
01015 message::Table::Field::StringFieldOptions field_options= pfield.string_options();
01016
01017 charset= get_charset(field_options.has_collation_id() ?
01018 field_options.collation_id() : 0);
01019
01020 if (! charset)
01021 charset= default_charset_info;
01022
01023 field_length= field_options.length() * charset->mbmaxlen;
01024 }
01025 break;
01026 case DRIZZLE_TYPE_DOUBLE:
01027 {
01028 message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
01029 if (!fo.has_precision() && !fo.has_scale())
01030 {
01031 field_length= DBL_DIG+7;
01032 }
01033 else
01034 {
01035 field_length= fo.precision();
01036 }
01037 if (field_length < decimals &&
01038 decimals != NOT_FIXED_DEC)
01039 {
01040 my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
01041 local_error= ER_M_BIGGER_THAN_D;
01042 return true;
01043 }
01044 break;
01045 }
01046 case DRIZZLE_TYPE_DECIMAL:
01047 {
01048 message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
01049
01050 field_length= class_decimal_precision_to_length(fo.precision(), fo.scale(),
01051 false);
01052 break;
01053 }
01054 case DRIZZLE_TYPE_DATETIME:
01055 field_length= DateTime::MAX_STRING_LENGTH;
01056 break;
01057 case DRIZZLE_TYPE_DATE:
01058 field_length= Date::MAX_STRING_LENGTH;
01059 break;
01060 case DRIZZLE_TYPE_ENUM:
01061 {
01062 field_length= 0;
01063
01064 message::Table::Field::EnumerationValues fo= pfield.enumeration_values();
01065
01066 for (int valnr= 0; valnr < fo.field_value_size(); valnr++)
01067 {
01068 if (fo.field_value(valnr).length() > field_length)
01069 {
01070 field_length= charset->cset->numchars(charset,
01071 fo.field_value(valnr).c_str(),
01072 fo.field_value(valnr).c_str()
01073 + fo.field_value(valnr).length())
01074 * charset->mbmaxlen;
01075 }
01076 }
01077 }
01078 break;
01079 case DRIZZLE_TYPE_LONG:
01080 {
01081 uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
01082 field_length= MAX_INT_WIDTH+sign_len;
01083 }
01084 break;
01085 case DRIZZLE_TYPE_LONGLONG:
01086 {
01087 uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
01088 field_length= MAX_BIGINT_WIDTH+sign_len;
01089 }
01090 break;
01091 case DRIZZLE_TYPE_UUID:
01092 field_length= field::Uuid::max_string_length();
01093 break;
01094 case DRIZZLE_TYPE_IPV6:
01095 field_length= field::IPv6::max_string_length();
01096 break;
01097 case DRIZZLE_TYPE_BOOLEAN:
01098 field_length= field::Boolean::max_string_length();
01099 break;
01100 case DRIZZLE_TYPE_MICROTIME:
01101 field_length= field::Microtime::max_string_length();
01102 break;
01103 case DRIZZLE_TYPE_TIMESTAMP:
01104 field_length= field::Epoch::max_string_length();
01105 break;
01106 case DRIZZLE_TYPE_TIME:
01107 field_length= field::Time::max_string_length();
01108 break;
01109 case DRIZZLE_TYPE_NULL:
01110 abort();
01111 }
01112
01113 bool is_not_null= false;
01114
01115 if (not pfield.constraints().is_nullable())
01116 {
01117 is_not_null= true;
01118 }
01119 else if (pfield.constraints().is_notnull())
01120 {
01121 is_not_null= true;
01122 }
01123
01124 Field* f= make_field(pfield,
01125 record + field_offsets[fieldnr] + data_offset,
01126 field_length,
01127 not is_not_null,
01128 null_pos,
01129 null_bit_pos,
01130 decimals,
01131 field_type,
01132 charset,
01133 MTYP_TYPENR(unireg_type),
01134 ((field_type == DRIZZLE_TYPE_ENUM) ? &intervals[interval_nr++] : (TYPELIB*) 0),
01135 getTableMessage()->field(fieldnr).name().c_str());
01136
01137 _fields[fieldnr]= f;
01138
01139
01140 switch (field_type)
01141 {
01142 case DRIZZLE_TYPE_BLOB:
01143 case DRIZZLE_TYPE_VARCHAR:
01144 case DRIZZLE_TYPE_DOUBLE:
01145 case DRIZZLE_TYPE_DECIMAL:
01146 case DRIZZLE_TYPE_TIMESTAMP:
01147 case DRIZZLE_TYPE_TIME:
01148 case DRIZZLE_TYPE_DATETIME:
01149 case DRIZZLE_TYPE_MICROTIME:
01150 case DRIZZLE_TYPE_DATE:
01151 case DRIZZLE_TYPE_ENUM:
01152 case DRIZZLE_TYPE_LONG:
01153 case DRIZZLE_TYPE_LONGLONG:
01154 case DRIZZLE_TYPE_NULL:
01155 case DRIZZLE_TYPE_UUID:
01156 case DRIZZLE_TYPE_IPV6:
01157 case DRIZZLE_TYPE_BOOLEAN:
01158 break;
01159 }
01160
01161
01162
01163 table::Shell temp_table(*this);
01164 temp_table.in_use= &session;
01165
01166 f->init(&temp_table);
01167
01168 if (! (f->flags & NOT_NULL_FLAG))
01169 {
01170 *f->null_ptr|= f->null_bit;
01171 if (! (null_bit_pos= (null_bit_pos + 1) & 7))
01172 null_pos++;
01173 null_count++;
01174 }
01175
01176 if (default_value)
01177 {
01178 enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
01179 session.count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
01180 int res= default_value->save_in_field(f, 1);
01181 session.count_cuted_fields= old_count_cuted_fields;
01182 if (res != 0 && res != 3)
01183 {
01184 my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
01185 local_error= ER_INVALID_DEFAULT;
01186
01187 return true;
01188 }
01189 }
01190 else if (f->real_type() == DRIZZLE_TYPE_ENUM && (f->flags & NOT_NULL_FLAG))
01191 {
01192 f->set_notnull();
01193 f->store((int64_t) 1, true);
01194 }
01195 else
01196 {
01197 f->reset();
01198 }
01199
01200
01201 f->setTable(NULL);
01202 f->orig_table= NULL;
01203
01204 f->setPosition(fieldnr);
01205 f->comment= comment;
01206 if (not default_value &&
01207 not (f->unireg_check==Field::NEXT_NUMBER) &&
01208 (f->flags & NOT_NULL_FLAG) &&
01209 (not f->is_timestamp()))
01210 {
01211 f->flags|= NO_DEFAULT_VALUE_FLAG;
01212 }
01213
01214 if (f->unireg_check == Field::NEXT_NUMBER)
01215 found_next_number_field= &(_fields[fieldnr]);
01216
01217 if (use_hash)
01218 {
01219 const char *local_field_name= _fields[fieldnr]->field_name;
01220 name_hash.insert(make_pair(local_field_name, &(_fields[fieldnr])));
01221 }
01222 }
01223
01224 keyinfo= key_info;
01225 for (unsigned int keynr= 0; keynr < keys; keynr++, keyinfo++)
01226 {
01227 key_part= keyinfo->key_part;
01228
01229 for (unsigned int partnr= 0;
01230 partnr < keyinfo->key_parts;
01231 partnr++, key_part++)
01232 {
01233
01234
01235
01236
01237
01238 key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
01239 }
01240 }
01241
01242
01243
01244
01245
01246 if (null_count & 7)
01247 *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
01248
01249 null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
01250
01251 last_null_bit_pos= null_bit_pos;
01252
01253
01254 if (key_parts)
01255 {
01256 uint32_t local_primary_key= doesKeyNameExist("PRIMARY");
01257 keyinfo= key_info;
01258 key_part= keyinfo->key_part;
01259
01260 for (uint32_t key= 0; key < keys; key++,keyinfo++)
01261 {
01262 uint32_t usable_parts= 0;
01263
01264 if (local_primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
01265 {
01266
01267
01268
01269
01270 local_primary_key=key;
01271 for (uint32_t i= 0; i < keyinfo->key_parts; i++)
01272 {
01273 uint32_t fieldnr= key_part[i].fieldnr;
01274 if (not fieldnr ||
01275 _fields[fieldnr-1]->null_ptr ||
01276 _fields[fieldnr-1]->key_length() != key_part[i].length)
01277 {
01278 local_primary_key= MAX_KEY;
01279 break;
01280 }
01281 }
01282 }
01283
01284 for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
01285 {
01286 Field *local_field;
01287 if (! key_part->fieldnr)
01288 {
01289 return ENOMEM;
01290 }
01291 local_field= key_part->field= _fields[key_part->fieldnr-1];
01292 key_part->type= local_field->key_type();
01293 if (local_field->null_ptr)
01294 {
01295 key_part->null_offset=(uint32_t) ((unsigned char*) local_field->null_ptr - getDefaultValues());
01296 key_part->null_bit= local_field->null_bit;
01297 key_part->store_length+=HA_KEY_NULL_LENGTH;
01298 keyinfo->flags|=HA_NULL_PART_KEY;
01299 keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
01300 keyinfo->key_length+= HA_KEY_NULL_LENGTH;
01301 }
01302 if (local_field->type() == DRIZZLE_TYPE_BLOB ||
01303 local_field->real_type() == DRIZZLE_TYPE_VARCHAR)
01304 {
01305 if (local_field->type() == DRIZZLE_TYPE_BLOB)
01306 key_part->key_part_flag|= HA_BLOB_PART;
01307 else
01308 key_part->key_part_flag|= HA_VAR_LENGTH_PART;
01309 keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
01310 key_part->store_length+=HA_KEY_BLOB_LENGTH;
01311 keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
01312 }
01313 if (i == 0 && key != local_primary_key)
01314 local_field->flags |= (((keyinfo->flags & HA_NOSAME) &&
01315 (keyinfo->key_parts == 1)) ?
01316 UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
01317 if (i == 0)
01318 local_field->key_start.set(key);
01319 if (local_field->key_length() == key_part->length &&
01320 !(local_field->flags & BLOB_FLAG))
01321 {
01322 enum ha_key_alg algo= key_info[key].algorithm;
01323 if (db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
01324 {
01325 keys_for_keyread.set(key);
01326 local_field->part_of_key.set(key);
01327 local_field->part_of_key_not_clustered.set(key);
01328 }
01329 if (db_type()->index_flags(algo) & HA_READ_ORDER)
01330 local_field->part_of_sortkey.set(key);
01331 }
01332 if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
01333 usable_parts == i)
01334 usable_parts++;
01335 local_field->flags|= PART_KEY_FLAG;
01336 if (key == local_primary_key)
01337 {
01338 local_field->flags|= PRI_KEY_FLAG;
01339
01340
01341
01342
01343 if (storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
01344 {
01345 local_field->part_of_key= keys_in_use;
01346 if (local_field->part_of_sortkey.test(key))
01347 local_field->part_of_sortkey= keys_in_use;
01348 }
01349 }
01350 if (local_field->key_length() != key_part->length)
01351 {
01352 key_part->key_part_flag|= HA_PART_KEY_SEG;
01353 }
01354 }
01355 keyinfo->usable_key_parts= usable_parts;
01356
01357 set_if_bigger(max_key_length,keyinfo->key_length+
01358 keyinfo->key_parts);
01359 total_key_length+= keyinfo->key_length;
01360
01361 if (keyinfo->flags & HA_NOSAME)
01362 {
01363 set_if_bigger(max_unique_length,keyinfo->key_length);
01364 }
01365 }
01366 if (local_primary_key < MAX_KEY &&
01367 (keys_in_use.test(local_primary_key)))
01368 {
01369 primary_key= local_primary_key;
01370
01371
01372
01373
01374 if (key_info[local_primary_key].key_parts == 1)
01375 {
01376 Field *local_field= key_info[local_primary_key].key_part[0].field;
01377 if (local_field && local_field->result_type() == INT_RESULT)
01378 {
01379
01380 rowid_field_offset= (key_info[local_primary_key].key_part[0].
01381 fieldnr);
01382 }
01383 }
01384 }
01385 }
01386
01387 if (found_next_number_field)
01388 {
01389 Field *reg_field= *found_next_number_field;
01390 if ((int) (next_number_index= (uint32_t)
01391 find_ref_key(key_info, keys,
01392 getDefaultValues(), reg_field,
01393 &next_number_key_offset,
01394 &next_number_keypart)) < 0)
01395 {
01396
01397 local_error= ER_NOT_FORM_FILE;
01398
01399 return true;
01400 }
01401 else
01402 {
01403 reg_field->flags |= AUTO_INCREMENT_FLAG;
01404 }
01405 }
01406
01407 if (blob_fields)
01408 {
01409
01410 blob_field.resize(blob_fields);
01411 uint32_t *save= &blob_field[0];
01412 uint32_t k= 0;
01413 for (Fields::iterator iter= _fields.begin(); iter != _fields.end()-1; iter++, k++)
01414 {
01415 if ((*iter)->flags & BLOB_FLAG)
01416 (*save++)= k;
01417 }
01418 }
01419
01420 all_set.clear();
01421 all_set.resize(_field_size);
01422 all_set.set();
01423
01424 return local_error != EE_OK;
01425 }
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451 int TableShare::open_table_def(Session& session, const identifier::Table &identifier)
01452 {
01453 drizzled::error_t local_error= EE_OK;
01454
01455 message::table::shared_ptr table= plugin::StorageEngine::getTableMessage(session, identifier, local_error);
01456
01457 if (table and table->IsInitialized())
01458 {
01459 if (parse_table_proto(session, *table))
01460 {
01461 local_error= ER_CORRUPT_TABLE_DEFINITION_UNKNOWN;
01462 my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
01463 }
01464 else
01465 {
01466 setTableCategory(TABLE_CATEGORY_USER);
01467 local_error= EE_OK;
01468 }
01469 }
01470 else if (table and not table->IsInitialized())
01471 {
01472 local_error= ER_CORRUPT_TABLE_DEFINITION_UNKNOWN;
01473 my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
01474 }
01475 else
01476 {
01477 local_error= ER_TABLE_UNKNOWN;
01478 my_error(ER_TABLE_UNKNOWN, identifier);
01479 }
01480
01481 return static_cast<int>(local_error);
01482 }
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508 int TableShare::open_table_from_share(Session *session,
01509 const identifier::Table &identifier,
01510 const char *alias,
01511 uint32_t db_stat, uint32_t ha_open_flags,
01512 Table &outparam)
01513 {
01514 bool error_reported= false;
01515 int ret= open_table_from_share_inner(session, alias, db_stat, outparam);
01516
01517 if (not ret)
01518 ret= open_table_cursor_inner(identifier, db_stat, ha_open_flags, outparam, error_reported);
01519
01520 if (not ret)
01521 return ret;
01522
01523 if (not error_reported)
01524 open_table_error(ret, errno, 0);
01525
01526 boost::checked_delete(outparam.cursor);
01527 outparam.cursor= 0;
01528 outparam.db_stat= 0;
01529 outparam.mem().free_root(MYF(0));
01530 outparam.clearAlias();
01531
01532 return ret;
01533 }
01534
01535 int TableShare::open_table_from_share_inner(Session *session, const char *alias, uint32_t db_stat, Table &outparam)
01536 {
01537 int local_error= 1;
01538 outparam.resetTable(session, this, db_stat);
01539
01540 outparam.setAlias(alias);
01541
01542
01543 if (not (outparam.cursor= db_type()->getCursor(outparam)))
01544 return local_error;
01545
01546 local_error= 4;
01547 uint32_t records= 0;
01548 if (db_stat & HA_OPEN_KEYFILE)
01549 records=1;
01550
01551 records++;
01552
01553 unsigned char* record= outparam.alloc(rec_buff_length * records);
01554
01555 if (records == 0)
01556 {
01557
01558 outparam.record[0]= outparam.record[1]= getDefaultValues();
01559 }
01560 else
01561 {
01562 outparam.record[0]= record;
01563 if (records > 1)
01564 outparam.record[1]= record+ rec_buff_length;
01565 else
01566 outparam.record[1]= outparam.getInsertRecord();
01567 }
01568
01569 #ifdef HAVE_VALGRIND
01570
01571
01572
01573
01574 if (records > 1)
01575 {
01576 memcpy(outparam.getInsertRecord(), getDefaultValues(), rec_buff_length);
01577 memcpy(outparam.getUpdateRecord(), getDefaultValues(), null_bytes);
01578 if (records > 2)
01579 memcpy(outparam.getUpdateRecord(), getDefaultValues(), rec_buff_length);
01580 }
01581 #endif
01582 if (records > 1)
01583 {
01584 memcpy(outparam.getUpdateRecord(), getDefaultValues(), null_bytes);
01585 }
01586
01587 Field** field_ptr = new (outparam.mem()) Field*[_field_size + 1];
01588
01589 outparam.setFields(field_ptr);
01590
01591 record= outparam.getInsertRecord()-1;
01592
01593 outparam.null_flags= (unsigned char*) record+1;
01594
01595
01596 for (uint32_t i= 0 ; i < _field_size; i++, field_ptr++)
01597 {
01598 if (!((*field_ptr)= _fields[i]->clone(&outparam.mem(), &outparam)))
01599 return local_error;
01600 }
01601 *field_ptr= 0;
01602
01603 if (found_next_number_field)
01604 outparam.found_next_number_field=
01605 outparam.getField(positionFields(found_next_number_field));
01606 if (timestamp_field)
01607 outparam.timestamp_field= (field::Epoch*) outparam.getField(timestamp_field->position());
01608
01609
01610 if (key_parts)
01611 {
01612 uint32_t n_length= keys * sizeof(KeyInfo) + key_parts * sizeof(KeyPartInfo);
01613 KeyInfo* local_key_info= (KeyInfo*) outparam.alloc(n_length);
01614 outparam.key_info= local_key_info;
01615 KeyPartInfo* key_part= reinterpret_cast<KeyPartInfo*>(local_key_info+keys);
01616
01617 memcpy(local_key_info, key_info, sizeof(*local_key_info)*keys);
01618 memcpy(key_part, key_info[0].key_part, sizeof(*key_part) * key_parts);
01619
01620 for (KeyInfo* key_info_end= local_key_info + keys; local_key_info < key_info_end; local_key_info++)
01621 {
01622 local_key_info->table= &outparam;
01623 local_key_info->key_part= key_part;
01624
01625 for (KeyPartInfo* key_part_end= key_part+ local_key_info->key_parts; key_part < key_part_end; key_part++)
01626 {
01627 Field *local_field= key_part->field= outparam.getField(key_part->fieldnr-1);
01628
01629 if (local_field->key_length() != key_part->length && not (local_field->flags & BLOB_FLAG))
01630 {
01631
01632
01633
01634
01635 local_field= key_part->field= local_field->new_field(&outparam.mem(), &outparam, 0);
01636 local_field->field_length= key_part->length;
01637 }
01638 }
01639 }
01640 }
01641
01642
01643
01644 outparam.def_read_set.resize(_field_size);
01645 outparam.def_write_set.resize(_field_size);
01646 outparam.tmp_set.resize(_field_size);
01647 outparam.default_column_bitmaps();
01648
01649 return 0;
01650 }
01651
01652 int TableShare::open_table_cursor_inner(const identifier::Table &identifier,
01653 uint32_t db_stat, uint32_t ha_open_flags,
01654 Table &outparam,
01655 bool &error_reported)
01656 {
01657
01658 int local_error= 2;
01659 if (db_stat)
01660 {
01661 assert(!(db_stat & HA_WAIT_IF_LOCKED));
01662 int ha_err;
01663
01664 if ((ha_err= (outparam.cursor->ha_open(identifier,
01665 (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
01666 (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
01667 {
01668 switch (ha_err)
01669 {
01670 case HA_ERR_NO_SUCH_TABLE:
01671
01672
01673
01674
01675 local_error= 1;
01676 errno= ENOENT;
01677 break;
01678 case EMFILE:
01679
01680
01681
01682
01683 local_error= 1;
01684 errno= EMFILE;
01685 break;
01686 default:
01687 outparam.print_error(ha_err, MYF(0));
01688 error_reported= true;
01689 if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
01690 local_error= 7;
01691 break;
01692 }
01693 return local_error;
01694 }
01695 }
01696
01697 return 0;
01698 }
01699
01700
01701 void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
01702 {
01703 char buff[FN_REFLEN];
01704 myf errortype= ME_ERROR+ME_WAITTANG;
01705
01706 switch (pass_error) {
01707 case 7:
01708 case 1:
01709 if (db_errno == ENOENT)
01710 {
01711 identifier::Table identifier(db.data(), table_name.data());
01712 my_error(ER_TABLE_UNKNOWN, identifier);
01713 }
01714 else
01715 {
01716 snprintf(buff, sizeof(buff), "%s",normalized_path.data());
01717 my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND, errortype, buff, db_errno);
01718 }
01719 break;
01720 case 2:
01721 {
01722 drizzled::error_t err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ? ER_FILE_USED : ER_CANT_OPEN_FILE;
01723 my_error(err_no, errortype, normalized_path.data(), db_errno);
01724 break;
01725 }
01726 case 5:
01727 {
01728 const char *csname= get_charset_name((uint32_t) pass_errarg);
01729 char tmp[10];
01730 if (!csname || csname[0] =='?')
01731 {
01732 snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
01733 csname= tmp;
01734 }
01735 my_printf_error(ER_UNKNOWN_COLLATION, _("Unknown collation '%s' in table '%-.64s' definition"), MYF(0), csname, table_name.data());
01736 break;
01737 }
01738 case 6:
01739 snprintf(buff, sizeof(buff), "%s", normalized_path.data());
01740 my_printf_error(ER_NOT_FORM_FILE, _("Table '%-.64s' was created with a different version of Drizzle and cannot be read"), MYF(0), buff);
01741 break;
01742 case 8:
01743 break;
01744 default:
01745 case 4:
01746 snprintf(buff, sizeof(buff), "%s", normalized_path.data());
01747 my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
01748 break;
01749 }
01750 return;
01751 }
01752
01753 Field *TableShare::make_field(const message::Table::Field &pfield,
01754 unsigned char *ptr,
01755 uint32_t field_length,
01756 bool is_nullable,
01757 unsigned char *null_pos,
01758 unsigned char null_bit,
01759 uint8_t decimals,
01760 enum_field_types field_type,
01761 const charset_info_st * field_charset,
01762 Field::utype unireg_check,
01763 TYPELIB *interval,
01764 const char *field_name)
01765 {
01766 return make_field(pfield,
01767 ptr,
01768 field_length,
01769 is_nullable,
01770 null_pos,
01771 null_bit,
01772 decimals,
01773 field_type,
01774 field_charset,
01775 unireg_check,
01776 interval,
01777 field_name,
01778 pfield.constraints().is_unsigned());
01779 }
01780
01781 Field *TableShare::make_field(const message::Table::Field &,
01782 unsigned char *ptr,
01783 uint32_t field_length,
01784 bool is_nullable,
01785 unsigned char *null_pos,
01786 unsigned char null_bit,
01787 uint8_t decimals,
01788 enum_field_types field_type,
01789 const charset_info_st * field_charset,
01790 Field::utype unireg_check,
01791 TYPELIB *interval,
01792 const char *field_name,
01793 bool is_unsigned)
01794 {
01795 if (! is_nullable)
01796 {
01797 null_pos=0;
01798 null_bit=0;
01799 }
01800 else
01801 {
01802 null_bit= ((unsigned char) 1) << null_bit;
01803 }
01804
01805 switch (field_type)
01806 {
01807 case DRIZZLE_TYPE_ENUM:
01808 return new (&mem_root) Field_enum(ptr,
01809 field_length,
01810 null_pos,
01811 null_bit,
01812 field_name,
01813 interval,
01814 field_charset);
01815 case DRIZZLE_TYPE_VARCHAR:
01816 setVariableWidth();
01817 return new (&mem_root) Field_varstring(ptr,field_length,
01818 ha_varchar_packlength(field_length),
01819 null_pos,null_bit,
01820 field_name,
01821 field_charset);
01822 case DRIZZLE_TYPE_BLOB:
01823 return new (&mem_root) Field_blob(ptr,
01824 null_pos,
01825 null_bit,
01826 field_name,
01827 this,
01828 field_charset);
01829 case DRIZZLE_TYPE_DECIMAL:
01830 return new (&mem_root) Field_decimal(ptr,
01831 field_length,
01832 null_pos,
01833 null_bit,
01834 unireg_check,
01835 field_name,
01836 decimals);
01837 case DRIZZLE_TYPE_DOUBLE:
01838 return new (&mem_root) Field_double(ptr,
01839 field_length,
01840 null_pos,
01841 null_bit,
01842 unireg_check,
01843 field_name,
01844 decimals,
01845 false,
01846 false );
01847 case DRIZZLE_TYPE_UUID:
01848 return new (&mem_root) field::Uuid(ptr,
01849 field_length,
01850 null_pos,
01851 null_bit,
01852 field_name);
01853 case DRIZZLE_TYPE_IPV6:
01854 return new (&mem_root) field::IPv6(ptr,
01855 field_length,
01856 null_pos,
01857 null_bit,
01858 field_name);
01859 case DRIZZLE_TYPE_BOOLEAN:
01860 return new (&mem_root) field::Boolean(ptr,
01861 field_length,
01862 null_pos,
01863 null_bit,
01864 field_name,
01865 is_unsigned);
01866 case DRIZZLE_TYPE_LONG:
01867 return new (&mem_root) field::Int32(ptr,
01868 field_length,
01869 null_pos,
01870 null_bit,
01871 unireg_check,
01872 field_name);
01873 case DRIZZLE_TYPE_LONGLONG:
01874 {
01875 if (is_unsigned)
01876 {
01877 return new (&mem_root) field::Size(ptr,
01878 field_length,
01879 null_pos,
01880 null_bit,
01881 unireg_check,
01882 field_name);
01883 }
01884
01885 return new (&mem_root) field::Int64(ptr,
01886 field_length,
01887 null_pos,
01888 null_bit,
01889 unireg_check,
01890 field_name);
01891 }
01892 case DRIZZLE_TYPE_MICROTIME:
01893 return new (&mem_root) field::Microtime(ptr,
01894 null_pos,
01895 null_bit,
01896 unireg_check,
01897 field_name,
01898 this);
01899 case DRIZZLE_TYPE_TIMESTAMP:
01900 return new (&mem_root) field::Epoch(ptr,
01901 null_pos,
01902 null_bit,
01903 unireg_check,
01904 field_name,
01905 this);
01906 case DRIZZLE_TYPE_TIME:
01907 return new (&mem_root) field::Time(ptr, field_length, null_pos, null_bit, field_name);
01908 case DRIZZLE_TYPE_DATE:
01909 return new (&mem_root) Field_date(ptr, null_pos, null_bit, field_name);
01910 case DRIZZLE_TYPE_DATETIME:
01911 return new (&mem_root) Field_datetime(ptr, null_pos, null_bit, field_name);
01912 case DRIZZLE_TYPE_NULL:
01913 return new (&mem_root) Field_null(ptr, field_length, field_name);
01914 }
01915 assert(false);
01916 abort();
01917 }
01918
01919 void TableShare::refreshVersion()
01920 {
01921 version= g_refresh_version;
01922 }
01923
01924
01925 }