00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <fcntl.h>
00026
00027 #include <drizzled/session.h>
00028 #include <plugin/myisam/myisam.h>
00029 #include <drizzled/plugin/transactional_storage_engine.h>
00030
00031 #include <drizzled/table.h>
00032
00033 namespace drizzled
00034 {
00035
00036 namespace table
00037 {
00038
00039 Singular::Singular(Session *session, List<CreateField> &field_list) :
00040 _share(message::Table::INTERNAL),
00041 _has_variable_width(false)
00042 {
00043 uint32_t field_count= field_list.size();
00044 uint32_t blob_count= 0;
00045 Field **field_arg;
00046 CreateField *cdef;
00047 uint32_t record_length= 0;
00048 uint32_t null_count= 0;
00049 uint32_t null_pack_length;
00050
00051 getMutableShare()->setFields(field_count + 1);
00052 setFields(getMutableShare()->getFields(true));
00053 field_arg= getMutableShare()->getFields(true);
00054 getMutableShare()->blob_field.resize(field_count+1);
00055 getMutableShare()->setFieldSize(field_count);
00056 getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
00057 setup_tmp_table_column_bitmaps();
00058
00059 in_use= session;
00060
00061
00062 List<CreateField>::iterator it(field_list.begin());
00063 message::Table::Field null_field;
00064 while ((cdef= it++))
00065 {
00066 *field_arg= getMutableShare()->make_field(null_field,
00067 NULL,
00068 cdef->length,
00069 (cdef->flags & NOT_NULL_FLAG) ? false : true,
00070 (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
00071 (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
00072 cdef->decimals,
00073 cdef->sql_type,
00074 cdef->charset,
00075 cdef->unireg_check,
00076 cdef->interval,
00077 cdef->field_name,
00078 cdef->flags & UNSIGNED_FLAG ? true : false);
00079 if (!*field_arg)
00080 {
00081 throw "Memory allocation failure";
00082 }
00083
00084 (*field_arg)->init(this);
00085 record_length+= (*field_arg)->pack_length();
00086 if (! ((*field_arg)->flags & NOT_NULL_FLAG))
00087 null_count++;
00088
00089 if ((*field_arg)->flags & BLOB_FLAG)
00090 getMutableShare()->blob_field[blob_count++]= (uint32_t) (field_arg - getFields());
00091
00092 field_arg++;
00093 }
00094 *field_arg= NULL;
00095 getMutableShare()->blob_field[blob_count]= 0;
00096 getMutableShare()->blob_fields= blob_count;
00097
00098 null_pack_length= (null_count + 7)/8;
00099 getMutableShare()->setRecordLength(record_length + null_pack_length);
00100 getMutableShare()->rec_buff_length= ALIGN_SIZE(getMutableShare()->getRecordLength() + 1);
00101 record[0]= (unsigned char*)session->getMemRoot()->allocate(getMutableShare()->rec_buff_length);
00102 if (not getInsertRecord())
00103 {
00104 throw "Memory allocation failure";
00105 }
00106
00107 if (null_pack_length)
00108 {
00109 null_flags= (unsigned char*) getInsertRecord();
00110 getMutableShare()->null_fields= null_count;
00111 getMutableShare()->null_bytes= null_pack_length;
00112 }
00113 {
00114
00115 unsigned char *null_pos= getInsertRecord();
00116 unsigned char *field_pos= null_pos + getMutableShare()->null_bytes;
00117 uint32_t null_bit= 1;
00118
00119 for (field_arg= getFields(); *field_arg; ++field_arg)
00120 {
00121 Field *cur_field= *field_arg;
00122 if ((cur_field->flags & NOT_NULL_FLAG))
00123 cur_field->move_field(field_pos);
00124 else
00125 {
00126 cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
00127 null_bit<<= 1;
00128 if (null_bit == (1 << 8))
00129 {
00130 ++null_pos;
00131 null_bit= 1;
00132 }
00133 }
00134 cur_field->reset();
00135
00136 field_pos+= cur_field->pack_length();
00137 }
00138 }
00139 }
00140
00141 bool Singular::open_tmp_table()
00142 {
00143 int error;
00144
00145 identifier::Table identifier(getShare()->getSchemaName(), getShare()->getTableName(), getShare()->getPath());
00146 if ((error=cursor->ha_open(identifier,
00147 O_RDWR,
00148 HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
00149 {
00150 print_error(error, MYF(0));
00151 db_stat= 0;
00152 return true;
00153 }
00154 (void) cursor->extra(HA_EXTRA_QUICK);
00155 return false;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 bool Singular::create_myisam_tmp_table(KeyInfo *keyinfo,
00189 MI_COLUMNDEF *start_recinfo,
00190 MI_COLUMNDEF **recinfo,
00191 uint64_t options)
00192 {
00193 int error;
00194 MI_KEYDEF keydef;
00195 MI_UNIQUEDEF uniquedef;
00196
00197 if (getShare()->sizeKeys())
00198 {
00199 bool using_unique_constraint= false;
00200 HA_KEYSEG *seg= (HA_KEYSEG*) getMemRoot()->alloc_root(sizeof(*seg) * keyinfo->key_parts);
00201 if (not seg)
00202 return true;
00203
00204 memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
00205 if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
00206 keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
00207 getShare()->uniques)
00208 {
00209
00210 getMutableShare()->keys= 0;
00211 getMutableShare()->uniques= 1;
00212 using_unique_constraint= true;
00213 memset(&uniquedef, 0, sizeof(uniquedef));
00214 uniquedef.keysegs=keyinfo->key_parts;
00215 uniquedef.seg=seg;
00216 uniquedef.null_are_equal=1;
00217
00218
00219 memset(*recinfo, 0, sizeof(**recinfo));
00220 (*recinfo)->type= FIELD_CHECK;
00221 (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
00222 (*recinfo)++;
00223 getMutableShare()->setRecordLength(getShare()->getRecordLength() + MI_UNIQUE_HASH_LENGTH);
00224 }
00225 else
00226 {
00227
00228 memset(&keydef, 0, sizeof(keydef));
00229 keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
00230 keydef.keysegs= keyinfo->key_parts;
00231 keydef.seg= seg;
00232 }
00233 for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
00234 {
00235 Field *key_field=keyinfo->key_part[i].field;
00236 seg->flag= 0;
00237 seg->language= key_field->charset()->number;
00238 seg->length= keyinfo->key_part[i].length;
00239 seg->start= keyinfo->key_part[i].offset;
00240 if (key_field->flags & BLOB_FLAG)
00241 {
00242 seg->type= ((keyinfo->key_part[i].key_type & 1 ) ?
00243 HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
00244 seg->bit_start= (uint8_t)(key_field->pack_length() - getShare()->blob_ptr_size);
00245 seg->flag= HA_BLOB_PART;
00246 seg->length= 0;
00247 }
00248 else
00249 {
00250 seg->type= keyinfo->key_part[i].type;
00251 }
00252 if (!(key_field->flags & NOT_NULL_FLAG))
00253 {
00254 seg->null_bit= key_field->null_bit;
00255 seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) getInsertRecord());
00256
00257
00258
00259
00260
00261 if (! using_unique_constraint)
00262 keydef.flag|= HA_NULL_ARE_EQUAL;
00263 }
00264 }
00265 }
00266 MI_CREATE_INFO create_info;
00267
00268 if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
00269 OPTION_BIG_TABLES)
00270 create_info.data_file_length= ~(uint64_t) 0;
00271
00272 if ((error= mi_create(getShare()->getTableName(), getShare()->sizeKeys(), &keydef,
00273 (uint32_t) (*recinfo-start_recinfo),
00274 start_recinfo,
00275 getShare()->uniques, &uniquedef,
00276 &create_info,
00277 HA_CREATE_TMP_TABLE)))
00278 {
00279 print_error(error, MYF(0));
00280 db_stat= 0;
00281
00282 return true;
00283 }
00284 in_use->status_var.created_tmp_disk_tables++;
00285 getMutableShare()->db_record_offset= 1;
00286 return false;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 void Singular::setup_tmp_table_column_bitmaps()
00298 {
00299 uint32_t field_count= getShare()->sizeFields();
00300
00301 def_read_set.resize(field_count);
00302 def_write_set.resize(field_count);
00303 tmp_set.resize(field_count);
00304 getMutableShare()->all_set.resize(field_count);
00305 getMutableShare()->all_set.set();
00306 def_write_set.set();
00307 def_read_set.set();
00308 default_column_bitmaps();
00309 }
00310
00311 Singular::~Singular()
00312 {
00313 const char *save_proc_info;
00314
00315 save_proc_info= in_use->get_proc_info();
00316 in_use->set_proc_info("removing tmp table");
00317
00318
00319 plugin::TransactionalStorageEngine::releaseTemporaryLatches(in_use);
00320
00321 if (cursor)
00322 {
00323 if (db_stat)
00324 {
00325 cursor->closeMarkForDelete(getShare()->getTableName());
00326 }
00327
00328 identifier::Table identifier(getShare()->getSchemaName(), getShare()->getTableName(), getShare()->getTableName());
00329 drizzled::error_t ignored;
00330 plugin::StorageEngine::dropTable(*in_use,
00331 *getShare()->getEngine(),
00332 identifier,
00333 ignored);
00334
00335 delete cursor;
00336 }
00337
00338
00339 for (Field **ptr= getFields() ; *ptr ; ptr++)
00340 {
00341 (*ptr)->free();
00342 }
00343 free_io_cache();
00344
00345 getMemRoot()->free_root(MYF(0));
00346 in_use->set_proc_info(save_proc_info);
00347 }
00348
00349
00350 }
00351 }