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