4 #include "my_compare.h"
7 - /* defines used by heap-funktions */
8 +/* Define index limits to be identical to MyISAM ones for compatibility. */
10 +#if MAX_INDEXES > HA_MAX_POSSIBLE_KEY
11 +#define HP_MAX_KEY HA_MAX_POSSIBLE_KEY /* Max allowed keys */
13 +#define HP_MAX_KEY MAX_INDEXES /* Max allowed keys */
16 +#define HP_MAX_KEY_LENGTH 1000 /* Max length in bytes */
18 +/* defines used by heap-funktions */
20 #define HP_MAX_LEVELS 4 /* 128^5 records is enough */
21 #define HP_PTRS_IN_NOD 128
23 uint (*get_key_length)(struct st_hp_keydef *keydef, const uchar *key);
26 -typedef struct st_heap_share
27 +typedef struct st_heap_columndef /* column information */
29 + int16 type; /* en_fieldtype */
30 + uint32 length; /* length of field */
31 + uint32 offset; /* Offset to position in row */
32 + uint8 null_bit; /* If column may be 0 */
33 + uint16 null_pos; /* position for null marker */
34 + uint8 length_bytes; /* length of the size, 1 o 2 bytes */
37 +typedef struct st_heap_dataspace /* control data for data space */
40 + /* Total chunks ever allocated in this dataspace */
42 + uint del_chunk_count; /* Deleted chunks count */
43 + uchar *del_link; /* Link to last deleted chunk */
44 + uint chunk_length; /* Total length of one chunk */
45 + /* Length of payload that will be placed into one chunk */
46 + uint chunk_dataspace_length;
47 + /* Offset of the status flag relative to the chunk start */
49 + /* Offset of the linking pointer relative to the chunk start */
51 + /* Test whether records have variable size and so "next" pointer */
52 + uint is_variable_size;
53 + /* Total size allocated within this data space */
54 + ulonglong total_data_length;
57 +typedef struct st_heap_share
60 + HP_COLUMNDEF *column_defs;
61 + /* Describes "block", which contains actual records */
62 + HP_DATASPACE recordspace;
63 ulong min_records,max_records; /* Params to open */
64 - ulonglong data_length,index_length,max_table_size;
65 + ulonglong index_length, max_table_size;
66 uint key_stat_version; /* version to indicate insert/delete */
67 - uint records; /* records */
68 - uint blength; /* records rounded up to 2^n */
69 - uint deleted; /* Deleted records in database */
70 - uint reclength; /* Length of one record */
71 + uint records; /* Actual record (row) count */
72 + uint blength; /* used_chunk_count rounded up to 2^n */
74 + Length of record's fixed part, which contains keys and always fits into the
77 + uint fixed_data_length;
78 + uint fixed_column_count; /* Number of columns stored in fixed_data_length */
80 uint keys,max_key_length;
82 uint currently_disabled_keys; /* saved value from "keys" when disabled */
84 - uchar *del_link; /* Link to next block with del. rec */
85 char * name; /* Name of "memory-file" */
90 uint auto_key_type; /* real type of the auto key segment */
91 ulonglong auto_increment;
92 + uint blobs; /* Number of blobs in table */
95 struct st_hp_hash_info;
99 struct st_hp_hash_info *current_hash_ptr;
100 - ulong current_record,next_block;
101 + ulong current_record;
103 int mode; /* Mode of file (READONLY..) */
104 uint opt_flag,update;
106 my_bool implicit_emptied;
109 + uchar *blob_buffer; /* Temporary buffer used to return BLOB values */
110 + uint blob_size; /* Current blob_buffer size */
111 + uint blob_offset; /* Current offset in blob_buffer */
116 open_count to 1. Is only looked at if not internal_table.
120 + HP_COLUMNDEF *columndef;
121 + uint fixed_key_fieldnr;
122 + uint fixed_data_size;
123 + uint keys_memory_size;
124 + uint max_chunk_size;
129 /* Prototypes for heap-functions */
131 extern int heap_scan(register HP_INFO *info, uchar *record);
132 extern int heap_delete(HP_INFO *info,const uchar *buff);
133 extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag);
134 -extern int heap_create(const char *name,
135 - HP_CREATE_INFO *create_info, HP_SHARE **share,
136 - my_bool *created_new_share);
137 +extern int heap_create(const char *name, HP_CREATE_INFO *create_info,
138 + HP_SHARE **res, my_bool *created_new_share);
139 extern int heap_delete_table(const char *name);
140 extern void heap_drop_table(HP_INFO *info);
141 extern int heap_extra(HP_INFO *info,enum ha_extra_function function);
142 --- a/mysql-test/r/create.result
143 +++ b/mysql-test/r/create.result
145 create table t1 (b char(0) not null, index(b));
146 ERROR 42000: The used storage engine can't index column 'b'
147 create table t1 (a int not null,b text) engine=heap;
148 -ERROR 42000: The used table type doesn't support BLOB/TEXT columns
149 drop table if exists t1;
151 -Note 1051 Unknown table 't1'
152 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) engine=heap;
153 ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key
154 create table not_existing_database.test (a int);
155 --- a/mysql-test/r/ctype_utf8mb4_heap.result
156 +++ b/mysql-test/r/ctype_utf8mb4_heap.result
157 @@ -1124,6 +1124,8 @@
158 a varchar(255) NOT NULL default '',
160 ) ENGINE=heap DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
162 +Warning 1071 Specified key was too long; max key length is 1000 bytes
163 insert into t1 values (_utf8mb4 0xe880bd);
164 insert into t1 values (_utf8mb4 0x5b);
165 select hex(a) from t1;
166 @@ -1162,6 +1164,8 @@
168 Note 1051 Unknown table 't1'
169 CREATE TABLE t1(a VARCHAR(255), KEY(a)) ENGINE=heap DEFAULT CHARSET=utf8mb4;
171 +Warning 1071 Specified key was too long; max key length is 1000 bytes
172 INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̀ˆbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
173 INSERT INTO t1 VALUES('uu');
175 --- a/mysql-test/t/create.test
176 +++ b/mysql-test/t/create.test
178 drop table if exists t1,t2;
180 create table t1 (b char(0) not null, index(b));
182 +# BLOB/TEXT fields are now supported by HEAP
183 create table t1 (a int not null,b text) engine=heap;
184 drop table if exists t1;
186 --- a/storage/heap/CMakeLists.txt
187 +++ b/storage/heap/CMakeLists.txt
190 hp_delete.c hp_extra.c hp_hash.c hp_info.c hp_open.c hp_panic.c
191 hp_rename.c hp_rfirst.c hp_rkey.c hp_rlast.c hp_rnext.c hp_rprev.c
192 + hp_dspace.c hp_record.c
193 hp_rrnd.c hp_rsame.c hp_scan.c hp_static.c hp_update.c hp_write.c)
195 MYSQL_ADD_PLUGIN(heap ${HEAP_SOURCES} STORAGE_ENGINE MANDATORY RECOMPILE_FOR_EMBEDDED)
196 --- a/storage/heap/_check.c
197 +++ b/storage/heap/_check.c
202 - ulong records=0, deleted=0, pos, next_block;
203 + ulong records= 0, deleted= 0, chunk_count= 0, pos, next_block;
204 HP_SHARE *share=info->s;
205 HP_INFO save_info= *info; /* Needed because scan_init */
206 DBUG_ENTER("heap_check_heap");
209 if (pos < next_block)
211 - info->current_ptr+= share->block.recbuffer;
212 + info->current_ptr+= share->recordspace.block.recbuffer;
216 - next_block+= share->block.records_in_block;
217 - if (next_block >= share->records+share->deleted)
218 + next_block+= share->recordspace.block.records_in_block;
219 + if (next_block >= share->recordspace.chunk_count)
221 - next_block= share->records+share->deleted;
222 - if (pos >= next_block)
223 - break; /* End of file */
224 + next_block= share->recordspace.chunk_count;
225 + if (pos >= next_block)
226 + break; /* End of file */
229 hp_find_record(info,pos);
231 - if (!info->current_ptr[share->reclength])
232 + switch (get_chunk_status(&share->recordspace, info->current_ptr)) {
233 + case CHUNK_STATUS_DELETED:
238 + case CHUNK_STATUS_ACTIVE:
242 + case CHUNK_STATUS_LINKED:
246 + DBUG_PRINT("error",
247 + ("Unknown record status: Record: 0x%lx Status %lu",
248 + (long) info->current_ptr,
249 + (ulong) get_chunk_status(&share->recordspace,
250 + info->current_ptr)));
256 - if (records != share->records || deleted != share->deleted)
258 - DBUG_PRINT("error",("Found rows: %lu (%lu) deleted %lu (%lu)",
259 - records, (ulong) share->records,
260 - deleted, (ulong) share->deleted));
261 + /* TODO: verify linked chunks (no orphans, no cycles, no bad links) */
263 + if (records != share->records ||
264 + chunk_count != share->recordspace.chunk_count ||
265 + deleted != share->recordspace.del_chunk_count)
267 + DBUG_PRINT("error",
268 + ("Found rows: %lu (%lu) total chunks %lu (%lu) deleted chunks "
270 + records, (ulong) share->records,
271 + chunk_count, (ulong) share->recordspace.chunk_count,
272 + deleted, (ulong) share->recordspace.del_chunk_count));
279 memcpy(&recpos, key + (*keydef->get_key_length)(keydef,key), sizeof(uchar*));
280 - key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0);
281 + key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0, TRUE);
282 if (ha_key_cmp(keydef->seg, (uchar*) info->recbuf, (uchar*) key,
283 key_length, SEARCH_FIND | SEARCH_SAME, not_used))
285 --- a/storage/heap/_rectest.c
286 +++ b/storage/heap/_rectest.c
289 DBUG_ENTER("hp_rectest");
291 - if (memcmp(info->current_ptr,old,(size_t) info->s->reclength))
292 + if (hp_process_record_data_to_chunkset(info->s, old,
296 DBUG_RETURN((my_errno=HA_ERR_RECORD_CHANGED)); /* Record have changed */
298 --- a/storage/heap/ha_heap.cc
299 +++ b/storage/heap/ha_heap.cc
302 rc= heap_create(name, &create_info, &internal_share, &created_new_share);
303 my_free(create_info.keydef);
304 + my_free(create_info.columndef);
310 if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
311 btree_keys.set_bit(i);
313 + Reset per-key block size specification so they are not shown
314 + in SHOW CREATE TABLE.
316 + table->key_info[i].block_size= 0;
317 + table->key_info[i].flags&= ~HA_USES_BLOCK_SIZE;
325 +enum row_type ha_heap::get_row_type() const
327 + if (file->s->recordspace.is_variable_size)
328 + return ROW_TYPE_DYNAMIC;
330 + return ROW_TYPE_FIXED;
333 int ha_heap::extra(enum ha_extra_function operation)
335 @@ -646,23 +660,70 @@
336 heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
337 HP_CREATE_INFO *hp_create_info)
339 - uint key, parts, mem_per_row= 0, keys= table_arg->s->keys;
340 + uint key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
341 uint auto_key= 0, auto_key_type= 0;
343 + uint fixed_key_fieldnr = 0, fixed_data_size = 0, next_field_pos = 0;
344 + uint column_idx, column_count= table_arg->s->fields;
345 + HP_COLUMNDEF *columndef;
348 TABLE_SHARE *share= table_arg->s;
349 bool found_real_auto_increment= 0;
352 bzero(hp_create_info, sizeof(*hp_create_info));
354 + if (!(columndef= (HP_COLUMNDEF*) my_malloc(column_count *
355 + sizeof(HP_COLUMNDEF),
359 + for (column_idx= 0; column_idx < column_count; column_idx++)
361 + Field* field= *(table_arg->field + column_idx);
362 + HP_COLUMNDEF* column= columndef + column_idx;
363 + column->type= (uint16) field->type();
364 + column->length= field->pack_length();
365 + column->offset= field->offset(table_arg->record[0]);
367 + if (field->null_bit)
369 + column->null_bit= field->null_bit;
370 + column->null_pos= (uint) (field->null_ptr -
371 + (uchar*) table_arg->record[0]);
375 + column->null_bit= 0;
376 + column->null_pos= 0;
379 + if (field->type() == MYSQL_TYPE_VARCHAR)
381 + column->length_bytes= (uint8) (((Field_varstring *) field)->length_bytes);
383 + else if (field->type() == MYSQL_TYPE_BLOB)
386 + column->length_bytes= (uint8)
387 + (((Field_blob *) field)->pack_length_no_ptr());
391 + column->length_bytes= 0;
395 for (key= parts= 0; key < keys; key++)
396 parts+= table_arg->key_info[key].key_parts;
398 if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) +
399 parts * sizeof(HA_KEYSEG),
402 + my_free((uchar *) columndef);
405 seg= reinterpret_cast<HA_KEYSEG*>(keydef + keys);
406 for (key= 0; key < keys; key++)
408 @@ -678,11 +739,11 @@
409 case HA_KEY_ALG_UNDEF:
410 case HA_KEY_ALG_HASH:
411 keydef[key].algorithm= HA_KEY_ALG_HASH;
412 - mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
413 + mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
415 case HA_KEY_ALG_BTREE:
416 keydef[key].algorithm= HA_KEY_ALG_BTREE;
417 - mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
418 + mem_per_row_keys+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
421 DBUG_ASSERT(0); // cannot happen
423 seg->length= (uint) key_part->length;
424 seg->flag= key_part->key_part_flag;
426 + next_field_pos= seg->start;
427 + if (field->type() == MYSQL_TYPE_VARCHAR)
429 + Field *orig_field= *(table_arg->field + key_part->field->field_index);
430 + next_field_pos+= orig_field->pack_length();
434 + next_field_pos+= seg->length;
436 if (field->flags & (ENUM_FLAG | SET_FLAG))
437 seg->charset= &my_charset_bin;
441 auto_key_type= field->key_type();
444 + switch (seg->type) {
445 + case HA_KEYTYPE_SHORT_INT:
446 + case HA_KEYTYPE_LONG_INT:
447 + case HA_KEYTYPE_FLOAT:
448 + case HA_KEYTYPE_DOUBLE:
449 + case HA_KEYTYPE_USHORT_INT:
450 + case HA_KEYTYPE_ULONG_INT:
451 + case HA_KEYTYPE_LONGLONG:
452 + case HA_KEYTYPE_ULONGLONG:
453 + case HA_KEYTYPE_INT24:
454 + case HA_KEYTYPE_UINT24:
455 + case HA_KEYTYPE_INT8:
456 + seg->flag|= HA_SWAP_KEY;
458 + case HA_KEYTYPE_VARBINARY1:
459 + /* Case-insensitiveness is handled in coll->hash_sort */
460 + seg->type= HA_KEYTYPE_VARTEXT1;
462 + case HA_KEYTYPE_VARTEXT1:
463 + keydef[key].flag|= HA_VAR_LENGTH_KEY;
464 + /* Save number of bytes used to store length */
465 + if (seg->flag & HA_BLOB_PART)
466 + seg->bit_start= field->pack_length() - share->blob_ptr_size;
470 + case HA_KEYTYPE_VARBINARY2:
471 + /* Case-insensitiveness is handled in coll->hash_sort */
473 + case HA_KEYTYPE_VARTEXT2:
474 + keydef[key].flag|= HA_VAR_LENGTH_KEY;
475 + /* Save number of bytes used to store length */
476 + if (seg->flag & HA_BLOB_PART)
477 + seg->bit_start= field->pack_length() - share->blob_ptr_size;
481 + Make future comparison simpler by only having to check for
484 + seg->type= HA_KEYTYPE_VARTEXT1;
490 + if (next_field_pos > fixed_data_size)
492 + fixed_data_size= next_field_pos;
496 + if (field->field_index >= fixed_key_fieldnr)
499 + Do not use seg->fieldnr as it's not reliable in case of temp tables
501 + fixed_key_fieldnr= field->field_index + 1;
505 - mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*));
507 + if (fixed_data_size < share->null_bytes)
509 + /* Make sure to include null fields regardless of the presense of keys */
510 + fixed_data_size = share->null_bytes;
513 if (table_arg->found_next_number_field)
515 keydef[share->next_number_index].flag|= HA_AUTO_KEY;
516 @@ -745,16 +882,19 @@
517 hp_create_info->max_table_size=current_thd->variables.max_heap_table_size;
518 hp_create_info->with_auto_increment= found_real_auto_increment;
519 hp_create_info->internal_table= internal_table;
521 - max_rows= (ha_rows) (hp_create_info->max_table_size / mem_per_row);
522 - if (share->max_rows && share->max_rows < max_rows)
523 - max_rows= share->max_rows;
525 - hp_create_info->max_records= (ulong) max_rows;
526 + hp_create_info->max_chunk_size= share->key_block_size;
527 + hp_create_info->is_dynamic= (share->row_type == ROW_TYPE_DYNAMIC);
528 + hp_create_info->columns= column_count;
529 + hp_create_info->columndef= columndef;
530 + hp_create_info->fixed_key_fieldnr= fixed_key_fieldnr;
531 + hp_create_info->fixed_data_size= fixed_data_size;
532 + hp_create_info->max_records= (ulong) share->max_rows;
533 hp_create_info->min_records= (ulong) share->min_rows;
534 hp_create_info->keys= share->keys;
535 hp_create_info->reclength= share->reclength;
536 + hp_create_info->keys_memory_size= mem_per_row_keys;
537 hp_create_info->keydef= keydef;
538 + hp_create_info->blobs= blobs;
543 create_info->auto_increment_value - 1 : 0);
544 error= heap_create(name, &hp_create_info, &internal_share, &created);
545 my_free(hp_create_info.keydef);
546 + my_free(hp_create_info.columndef);
547 DBUG_ASSERT(file == 0);
551 table->file->info(HA_STATUS_AUTO);
552 if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
553 create_info->auto_increment_value= stats.auto_increment_value;
554 + if (!(create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
556 + if (file->s->recordspace.is_variable_size)
557 + create_info->key_block_size= file->s->recordspace.chunk_length;
559 + create_info->key_block_size= 0;
563 void ha_heap::get_auto_increment(ulonglong offset, ulonglong increment,
564 --- a/storage/heap/ha_heap.h
565 +++ b/storage/heap/ha_heap.h
567 return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
570 - /* Rows also use a fixed-size format */
571 - enum row_type get_row_type() const { return ROW_TYPE_FIXED; }
572 + enum row_type get_row_type() const;
573 const char **bas_ext() const;
574 ulonglong table_flags() const
576 - return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY |
577 + return (HA_FAST_KEY_READ | HA_NULL_IN_KEY |
578 HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
579 HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS |
580 HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT);
582 HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
584 const key_map *keys_to_use_for_scanning() { return &btree_keys; }
585 - uint max_supported_keys() const { return MAX_KEY; }
586 - uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
587 + uint max_supported_keys() const { return HP_MAX_KEY; }
588 + uint max_supported_key_length() const { return HP_MAX_KEY_LENGTH; }
589 + uint max_supported_key_part_length() const { return HP_MAX_KEY_LENGTH; }
591 { return (double) (stats.records+stats.deleted) / 20.0+10; }
592 double read_time(uint index, uint ranges, ha_rows rows)
593 --- a/storage/heap/heapdef.h
594 +++ b/storage/heap/heapdef.h
596 #define HP_MIN_RECORDS_IN_BLOCK 16
597 #define HP_MAX_RECORDS_IN_BLOCK 8192
599 +/* this chunk has been deleted and can be reused */
600 +#define CHUNK_STATUS_DELETED 0
601 +/* this chunk represents the first part of a live record */
602 +#define CHUNK_STATUS_ACTIVE 1
603 +/* this chunk is a continuation from another chunk (part of chunkset) */
604 +#define CHUNK_STATUS_LINKED 2
606 /* Some extern variables */
608 extern LIST *heap_open_list,*heap_share_list;
610 #define hp_find_hash(A,B) ((HASH_INFO*) hp_find_block((A),(B)))
612 /* Find pos for record and update it in info->current_ptr */
613 -#define hp_find_record(info,pos) (info)->current_ptr= hp_find_block(&(info)->s->block,pos)
614 +#define hp_find_record(info,pos) \
615 + (info)->current_ptr= hp_find_block(&(info)->s->recordspace.block,pos)
617 +#define get_chunk_status(info,ptr) (ptr[(info)->offset_status])
619 +#define get_chunk_count(info,rec_length) \
620 + ((rec_length + (info)->chunk_dataspace_length - 1) / \
621 + (info)->chunk_dataspace_length)
623 typedef struct st_hp_hash_info
627 extern void hp_make_key(HP_KEYDEF *keydef,uchar *key,const uchar *rec);
628 extern uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
629 - const uchar *rec, uchar *recpos);
630 + const uchar *rec, uchar *recpos, my_bool packed);
631 extern uint hp_rb_key_length(HP_KEYDEF *keydef, const uchar *key);
632 extern uint hp_rb_null_key_length(HP_KEYDEF *keydef, const uchar *key);
633 extern uint hp_rb_var_key_length(HP_KEYDEF *keydef, const uchar *key);
635 extern void hp_clear_keys(HP_SHARE *info);
636 extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
637 key_part_map keypart_map);
638 +extern uint hp_calc_blob_length(uint length, const uchar *pos);
640 +/* Chunkset management (alloc/free/encode/decode) functions */
641 +extern uchar *hp_allocate_chunkset(HP_DATASPACE *info, uint chunk_count);
642 +extern int hp_reallocate_chunkset(HP_DATASPACE *info, uint chunk_count,
644 +extern void hp_free_chunks(HP_DATASPACE *info, uchar *pos);
645 +extern void hp_clear_dataspace(HP_DATASPACE *info);
647 +extern uint hp_get_encoded_data_length(HP_SHARE *info, const uchar *record,
648 + uint *chunk_count);
649 +extern void hp_copy_record_data_to_chunkset(HP_SHARE *info, const uchar *record,
651 +extern int hp_extract_record(HP_INFO *info, uchar *record, const uchar *pos);
652 +extern uint hp_process_record_data_to_chunkset(HP_SHARE *info,
653 + const uchar *record, uchar *pos,
656 extern mysql_mutex_t THR_LOCK_heap;
658 --- a/storage/heap/hp_clear.c
659 +++ b/storage/heap/hp_clear.c
662 DBUG_ENTER("hp_clear");
664 - if (info->block.levels)
665 - (void) hp_free_level(&info->block,info->block.levels,info->block.root,
667 - info->block.levels=0;
668 + hp_clear_dataspace(&info->recordspace);
670 - info->records= info->deleted= 0;
671 - info->data_length= 0;
681 HP_SHARE *share= info->s;
683 - if (share->data_length || share->index_length)
684 + if (share->recordspace.total_data_length || share->index_length)
685 error= HA_ERR_CRASHED;
687 if (share->currently_disabled_keys)
688 --- a/storage/heap/hp_close.c
689 +++ b/storage/heap/hp_close.c
691 heap_open_list=list_delete(heap_open_list,&info->open_list);
692 if (!--info->s->open_count && info->s->delete_on_close)
693 hp_free(info->s); /* Table was deleted */
694 + if (info->blob_buffer)
696 + my_free(info->blob_buffer);
701 --- a/storage/heap/hp_create.c
702 +++ b/storage/heap/hp_create.c
704 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
707 +#include <mysql_com.h>
708 +#include <mysqld_error.h>
710 static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2);
711 -static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
712 +static void init_block(HP_BLOCK *block,uint chunk_length, ulong min_records,
715 +#define FIXED_REC_OVERHEAD (sizeof(uchar))
716 +#define VARIABLE_REC_OVERHEAD (sizeof(uchar **) + sizeof(uchar))
718 +/* Minimum size that a chunk can take, 12 bytes on 32bit, 24 bytes on 64bit */
719 +#define VARIABLE_MIN_CHUNK_SIZE \
720 + ((sizeof(uchar **) + VARIABLE_REC_OVERHEAD + sizeof(uchar **) - 1) & \
721 + ~(sizeof(uchar **) - 1))
723 /* Create a heap table */
725 int heap_create(const char *name, HP_CREATE_INFO *create_info,
727 uint keys= create_info->keys;
728 ulong min_records= create_info->min_records;
729 ulong max_records= create_info->max_records;
730 + ulong max_rows_for_stated_memory;
731 DBUG_ENTER("heap_create");
733 if (!create_info->internal_table)
738 + uint chunk_dataspace_length, chunk_length, is_variable_size;
739 + uint fixed_data_length, fixed_column_count;
741 DBUG_PRINT("info",("Initializing new table"));
744 + if (create_info->max_chunk_size)
746 + uint configured_chunk_size= create_info->max_chunk_size;
748 + /* User requested variable-size records, let's see if they're possible */
750 + if (configured_chunk_size < create_info->fixed_data_size)
753 + The resulting chunk_size cannot be smaller than fixed data part
754 + at the start of the first chunk which allows faster copying
755 + with a single memcpy().
757 + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "key_block_size");
761 + if (reclength > configured_chunk_size + VARIABLE_REC_OVERHEAD ||
762 + create_info->blobs > 0)
765 + Allow variable size only if we're saving some space, i.e.
766 + if a fixed-size record would take more space than variable-size
767 + one plus the variable-size overhead.
768 + There has to be at least one field after indexed fields.
769 + Note that NULL bits are already included in key_part_size.
771 + is_variable_size= 1;
772 + chunk_dataspace_length= configured_chunk_size;
776 + /* max_chunk_size is near the full reclength, let's use fixed size */
777 + is_variable_size= 0;
778 + chunk_dataspace_length= reclength;
781 + else if ((create_info->is_dynamic && reclength >
782 + 256 + VARIABLE_REC_OVERHEAD)
783 + || create_info->blobs > 0)
786 + User asked for dynamic records - use 256 as the chunk size, if that
787 + will may save some memory. Otherwise revert to fixed size format.
789 + if ((create_info->fixed_data_size + VARIABLE_REC_OVERHEAD) > 256)
790 + chunk_dataspace_length= create_info->fixed_data_size;
792 + chunk_dataspace_length= 256 - VARIABLE_REC_OVERHEAD;
794 + is_variable_size= 1;
799 + If max_chunk_size is not specified, put the whole record in one chunk
801 + is_variable_size= 0;
802 + chunk_dataspace_length= reclength;
805 + if (is_variable_size)
807 + /* Check whether we have any variable size records past key data */
808 + uint has_variable_fields= 0;
810 + fixed_data_length= create_info->fixed_data_size;
811 + fixed_column_count= create_info->fixed_key_fieldnr;
813 + for (i= create_info->fixed_key_fieldnr; i < create_info->columns; i++)
815 + HP_COLUMNDEF *column= create_info->columndef + i;
816 + if ((column->type == MYSQL_TYPE_VARCHAR &&
817 + (column->length - column->length_bytes) >= 32) ||
818 + column->type == MYSQL_TYPE_BLOB)
821 + The field has to be either blob or >= 5.0.3 true VARCHAR
822 + and have substantial length.
823 + TODO: do we want to calculate minimum length?
825 + has_variable_fields= 1;
829 + if (has_variable_fields)
834 + if ((column->offset + column->length) <= chunk_dataspace_length)
836 + /* Still no variable-size columns, add one fixed-length */
837 + fixed_column_count= i + 1;
838 + fixed_data_length= column->offset + column->length;
842 + if (!has_variable_fields && create_info->blobs == 0)
845 + There is no need to use variable-size records without variable-size
847 + Reset sizes if it's not variable size anymore.
849 + is_variable_size= 0;
850 + chunk_dataspace_length= reclength;
851 + fixed_data_length= reclength;
852 + fixed_column_count= create_info->columns;
857 + fixed_data_length= reclength;
858 + fixed_column_count= create_info->columns;
862 - We have to store sometimes uchar* del_link in records,
863 - so the record length should be at least sizeof(uchar*)
864 + We store uchar* del_link inside the data area of deleted records,
865 + so the data length should be at least sizeof(uchar*)
867 - set_if_bigger(reclength, sizeof (uchar*));
869 + set_if_bigger(chunk_dataspace_length, sizeof (uchar **));
871 + if (is_variable_size)
873 + chunk_length= chunk_dataspace_length + VARIABLE_REC_OVERHEAD;
877 + chunk_length= chunk_dataspace_length + FIXED_REC_OVERHEAD;
880 + /* Align chunk length to the next pointer */
881 + chunk_length= (uint) (chunk_length + sizeof(uchar **) - 1) &
882 + ~(sizeof(uchar **) - 1);
884 for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
886 bzero((char*) &keyinfo->block,sizeof(keyinfo->block));
888 keyinfo->rb_tree.size_of_element++;
890 switch (keyinfo->seg[j].type) {
891 - case HA_KEYTYPE_SHORT_INT:
892 - case HA_KEYTYPE_LONG_INT:
893 - case HA_KEYTYPE_FLOAT:
894 - case HA_KEYTYPE_DOUBLE:
895 - case HA_KEYTYPE_USHORT_INT:
896 - case HA_KEYTYPE_ULONG_INT:
897 - case HA_KEYTYPE_LONGLONG:
898 - case HA_KEYTYPE_ULONGLONG:
899 - case HA_KEYTYPE_INT24:
900 - case HA_KEYTYPE_UINT24:
901 - case HA_KEYTYPE_INT8:
902 - keyinfo->seg[j].flag|= HA_SWAP_KEY;
904 case HA_KEYTYPE_VARBINARY1:
905 - /* Case-insensitiveness is handled in coll->hash_sort */
906 - keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
908 case HA_KEYTYPE_VARTEXT1:
909 - keyinfo->flag|= HA_VAR_LENGTH_KEY;
911 - /* Save number of bytes used to store length */
912 - keyinfo->seg[j].bit_start= 1;
914 case HA_KEYTYPE_VARBINARY2:
915 - /* Case-insensitiveness is handled in coll->hash_sort */
917 case HA_KEYTYPE_VARTEXT2:
918 - keyinfo->flag|= HA_VAR_LENGTH_KEY;
920 - /* Save number of bytes used to store length */
921 - keyinfo->seg[j].bit_start= 2;
923 - Make future comparison simpler by only having to check for
926 - keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
930 @@ -133,13 +245,34 @@
932 if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
933 keys*sizeof(HP_KEYDEF)+
934 + (create_info->columns *
935 + sizeof(HP_COLUMNDEF)) +
936 key_segs*sizeof(HA_KEYSEG),
939 - share->keydef= (HP_KEYDEF*) (share + 1);
942 + Max_records is used for estimating block sizes and for enforcement.
943 + Calculate the very maximum number of rows (if everything was one chunk)
944 + and then take either that value or configured max_records (pick smallest
947 + max_rows_for_stated_memory= (ha_rows) (create_info->max_table_size /
948 + (create_info->keys_memory_size +
950 + max_records = ((max_records && max_records < max_rows_for_stated_memory) ?
951 + max_records : max_rows_for_stated_memory);
953 + share->column_defs= (HP_COLUMNDEF*) (share + 1);
954 + memcpy(share->column_defs, create_info->columndef,
955 + (size_t) (sizeof(create_info->columndef[0]) *
956 + create_info->columns));
958 + share->keydef= (HP_KEYDEF*) (share->column_defs + create_info->columns);
959 share->key_stat_version= 1;
960 keyseg= (HA_KEYSEG*) (share->keydef + keys);
961 - init_block(&share->block, reclength + 1, min_records, max_records);
962 + init_block(&share->recordspace.block, chunk_length, min_records,
965 memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
966 for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
967 @@ -177,16 +310,36 @@
968 share->min_records= min_records;
969 share->max_records= max_records;
970 share->max_table_size= create_info->max_table_size;
971 - share->data_length= share->index_length= 0;
972 - share->reclength= reclength;
973 + share->index_length= 0;
976 share->max_key_length= max_length;
977 + share->column_count= create_info->columns;
979 share->auto_key= create_info->auto_key;
980 share->auto_key_type= create_info->auto_key_type;
981 share->auto_increment= create_info->auto_increment;
982 share->create_time= (long) time((time_t*) 0);
984 + share->fixed_data_length= fixed_data_length;
985 + share->fixed_column_count= fixed_column_count;
986 + share->blobs= create_info->blobs;
988 + share->recordspace.chunk_length= chunk_length;
989 + share->recordspace.chunk_dataspace_length= chunk_dataspace_length;
990 + share->recordspace.is_variable_size= is_variable_size;
991 + share->recordspace.total_data_length= 0;
993 + if (is_variable_size) {
994 + share->recordspace.offset_link= chunk_dataspace_length;
995 + share->recordspace.offset_status= share->recordspace.offset_link +
998 + /* Make it likely to fail if anyone uses this offset */
999 + share->recordspace.offset_link= 1 << 22;
1000 + share->recordspace.offset_status= chunk_dataspace_length;
1003 /* Must be allocated separately for rename to work */
1004 if (!(share->name= my_strdup(name,MYF(0))))
1007 param->search_flag, not_used);
1010 -static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
1011 +static void init_block(HP_BLOCK *block, uint chunk_length, ulong min_records,
1014 uint i,recbuffer,records_in_block;
1015 @@ -236,7 +389,12 @@
1016 max_records= max(min_records,max_records);
1018 max_records= 1000; /* As good as quess as anything */
1019 - recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
1021 + We want to start each chunk at 8 bytes boundary, round recbuffer to the
1024 + recbuffer= (uint) (chunk_length + sizeof(uchar**) - 1) &
1025 + ~(sizeof(uchar**) - 1);
1026 records_in_block= max_records / 10;
1027 if (records_in_block < 10 && max_records)
1028 records_in_block= 10;
1029 --- a/storage/heap/hp_delete.c
1030 +++ b/storage/heap/hp_delete.c
1033 HP_SHARE *share=info->s;
1034 HP_KEYDEF *keydef, *end, *p_lastinx;
1036 DBUG_ENTER("heap_delete");
1037 DBUG_PRINT("enter",("info: 0x%lx record: 0x%lx", (long) info, (long) record));
1042 info->update=HA_STATE_DELETED;
1043 - *((uchar**) pos)=share->del_link;
1044 - share->del_link=pos;
1045 - pos[share->reclength]=0; /* Record deleted */
1047 + hp_free_chunks(&share->recordspace, pos);
1048 info->current_hash_ptr=0;
1049 #if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
1050 DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
1052 info->last_pos= NULL; /* For heap_rnext/heap_rprev */
1054 custom_arg.keyseg= keyinfo->seg;
1055 - custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
1056 + custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos,
1058 custom_arg.search_flag= SEARCH_SAME;
1059 old_allocated= keyinfo->rb_tree.allocated;
1060 res= tree_delete(&keyinfo->rb_tree, info->recbuf, custom_arg.key_length,
1062 blength=share->blength;
1063 if (share->records+1 == blength)
1066 lastpos=hp_find_hash(&keyinfo->block,share->records);
1070 +++ b/storage/heap/hp_dspace.c
1072 +/* Copyright (C) 2000-2002 MySQL AB
1073 + Copyright (C) 2008 eBay, Inc
1075 + This program is free software; you can redistribute it and/or modify
1076 + it under the terms of the GNU General Public License as published by
1077 + the Free Software Foundation; version 2 of the License.
1079 + This program is distributed in the hope that it will be useful,
1080 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1081 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1082 + GNU General Public License for more details.
1084 + You should have received a copy of the GNU General Public License
1085 + along with this program; if not, write to the Free Software
1086 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
1089 + Implements various base dataspace-related functions - allocate, free, clear
1092 +#include "heapdef.h"
1096 + MySQL Heap tables keep data in arrays of fixed-size chunks.
1097 + These chunks are organized into two groups of HP_BLOCK structures:
1098 + - group1 contains indexes, with one HP_BLOCK per key
1099 + (part of HP_KEYDEF)
1100 + - group2 contains record data, with single HP_BLOCK
1101 + for all records, referenced by HP_SHARE.recordspace.block
1103 + While columns used in index are usually small, other columns
1104 + in the table may need to accomodate larger data. Typically,
1105 + larger data is placed into VARCHAR or BLOB columns. With actual
1106 + sizes varying, Heap Engine has to support variable-sized records
1107 + in memory. Heap Engine implements the concept of dataspace
1108 + (HP_DATASPACE), which incorporates HP_BLOCK for the record data,
1109 + and adds more information for managing variable-sized records.
1111 + Variable-size records are stored in multiple "chunks",
1112 + which means that a single record of data (database "row") can
1113 + consist of multiple chunks organized into one "set". HP_BLOCK
1114 + contains chunks. In variable-size format, one record
1115 + is represented as one or many chunks, depending on the actual
1116 + data, while in fixed-size mode, one record is always represented
1117 + as one chunk. The index structures would always point to the first
1118 + chunk in the chunkset.
1120 + At the time of table creation, Heap Engine attempts to find out if
1121 + variable-size records are desired. A user can request
1122 + variable-size records by providing either row_type=dynamic or
1123 + key_block_size=NNN table create option. Heap Engine will check
1124 + whether key_block_size provides enough space in the first chunk
1125 + to keep all null bits and columns that are used in indexes.
1126 + If key_block_size is too small, table creation will be aborted
1127 + with an error. Heap Engine will revert to fixed-size allocation
1128 + mode if key_block_size provides no memory benefits (if the
1129 + fixed-size record would always be shorter then the first chunk
1130 + in the chunkset with the specified key_block_size).
1132 + In order to improve index search performance, Heap Engine needs
1133 + to keep all null flags and all columns used as keys inside
1134 + the first chunk of a chunkset. In particular, this means that
1135 + all columns used as keys should be defined first in the table
1136 + creation SQL. The length of data used by null bits and key columns
1137 + is stored as fixed_data_length inside HP_SHARE. fixed_data_length
1138 + will extend past last key column if more fixed-length fields can
1139 + fit into the first chunk.
1141 + Variable-size records are necessary only in the presence of
1142 + variable-size columns. Heap Engine will be looking for BLOB
1143 + columns or VARCHAR columns, which declare length of 32 or more. If
1144 + no such columns are found, table will be switched to fixed-size
1145 + format. You should always try to put such columns at the end of
1146 + the table definition.
1148 + Whenever data is being inserted or updated in the table
1149 + Heap Engine will calculate how many chunks are necessary.
1150 + For insert operations, Heap Engine allocates new chunkset in
1151 + the recordspace. For update operations it will modify length of
1152 + the existing chunkset, unlinking unnecessary chunks at the end,
1153 + or allocating and adding more if larger length is necessary.
1155 + When writing data to chunks or copying data back to record,
1156 + fixed-size columns are copied in their full format. VARCHARs and
1157 + BLOBs are copied based on their actual length. Any NULL values
1158 + after fixed_data_length are skipped.
1160 + The allocation and contents of the actual chunks varies between
1161 + fixed and variable-size modes. Total chunk length is always
1162 + aligned to the next sizeof(uchar*). Here is the format of
1164 + uchar[] - sizeof=chunk_dataspace_length, but at least
1165 + sizeof(uchar*) bytes. Keeps actual data or pointer
1166 + to the next deleted chunk.
1167 + chunk_dataspace_length equals to full record length
1168 + uchar - status field (1 means "in use", 0 means "deleted")
1170 + Variable-size chunk uses different format:
1171 + uchar[] - sizeof=chunk_dataspace_length, but at least
1172 + sizeof(uchar*) bytes. Keeps actual data or pointer
1173 + to the next deleted chunk.
1174 + chunk_dataspace_length is set according to table
1175 + setup (key_block_size)
1176 + uchar* - pointer to the next chunk in this chunkset,
1177 + or NULL for the last chunk
1178 + uchar - status field (1 means "first", 0 means "deleted",
1181 + When allocating a new chunkset of N chunks, Heap Engine will try
1182 + to allocate chunks one-by-one, linking them as they become
1183 + allocated. Allocation of a single chunk will attempt to reuse
1184 + a deleted (freed) chunk. If no free chunks are available,
1185 + it will attempt to allocate a new area inside HP_BLOCK.
1186 + Freeing chunks will place them at the front of free list
1187 + referenced by del_link in HP_DATASPACE. The newly freed chunk
1188 + will contain reference to the previously freed chunk in its first
1189 + sizeof(uchar*) of the payload space.
1191 + Here is open issues:
1192 + - It is not very nice to require people to keep key columns
1193 + at the beginning of the table creation SQL. There are three
1194 + proposed resolutions:
1195 + a. Leave it as is. It's a reasonable limitation
1196 + b. Add new HA_KEEP_KEY_COLUMNS_TO_FRONT flag to handler.h and
1197 + make table.cpp align columns when it creates the table
1198 + c. Make HeapEngine reorder columns in the chunk data, so that
1199 + key columns go first. Add parallel HA_KEYSEG structures
1200 + to distinguish positions in record vs. positions in
1201 + the first chunk. Copy all data field-by-field rather than
1202 + using single memcpy unless DBA kept key columns to
1204 + - heap_check_heap needs verify linked chunks, looking for
1205 + issues such as orphans, cycles, and bad links. However,
1206 + Heap Engine today does not do similar things even for
1208 + - In a more sophisticated implementation, some space can
1209 + be saved even with all fixed-size columns if many of them
1210 + have NULL value, as long as these columns are not used
1212 + - In variable-size format status should be moved to lower
1213 + bits of the "next" pointer. Pointer is always aligned
1214 + to sizeof(byte*), which is at least 4, leaving 2 lower
1215 + bits free. This will save 8 bytes per chunk
1216 + on 64-bit platform.
1217 + - As we do not want to modify FRM format or to add new SQL
1218 + keywords, KEY_BLOCK_SIZE option of "CREATE TABLE" is reused
1219 + to specify block size for Heap Engine tables.
1220 + - since all key columns must fit in the first chunk, having keys
1221 + on BLOB columns is currently impossible. This limitation is
1222 + relatively easiy to remove in future.
1225 +static uchar *hp_allocate_one_chunk(HP_DATASPACE *info);
1231 + Frees memory and zeros-out any relevant counters in the dataspace
1233 + @param info the dataspace to clear
1236 +void hp_clear_dataspace(HP_DATASPACE *info)
1238 + if (info->block.levels)
1240 + hp_free_level(&info->block,info->block.levels,info->block.root,
1243 + info->block.levels= 0;
1244 + info->del_chunk_count= info->chunk_count= 0;
1245 + info->del_link= 0;
1246 + info->total_data_length= 0;
1251 + Allocate or reallocate a chunkset in the dataspace
1253 + Attempts to allocate a new chunkset or change the size of an existing chunkset
1255 + @param info the hosting dataspace
1256 + @param chunk_count the number of chunks that we expect as the result
1257 + @param existing_set non-null value asks function to resize existing
1258 + chunkset, return value would point to this set
1260 + @return Pointer to the first chunk in the new or updated chunkset, or NULL
1264 +static uchar *hp_allocate_variable_chunkset(HP_DATASPACE *info,
1266 + uchar *existing_set)
1268 + int alloc_count= chunk_count, i;
1269 + uchar *first_chunk= 0, *curr_chunk= 0, *prev_chunk= 0;
1270 + uchar *last_existing_chunk= 0;
1272 + DBUG_ASSERT(alloc_count);
1276 + first_chunk= existing_set;
1278 + curr_chunk= existing_set;
1279 + while (curr_chunk && alloc_count)
1281 + prev_chunk= curr_chunk;
1282 + curr_chunk= *((uchar **) (curr_chunk + info->offset_link));
1291 + We came through all chunks and there is more left, let's truncate the
1294 + *((uchar **) (prev_chunk + info->offset_link))= NULL;
1295 + hp_free_chunks(info, curr_chunk);
1298 + return first_chunk;
1301 + last_existing_chunk= prev_chunk;
1305 + We can reach this point only if we're allocating new chunkset or more chunks
1309 + for (i= 0; i < alloc_count; i++)
1311 + curr_chunk= hp_allocate_one_chunk(info);
1314 + /* no space in the current block */
1316 + if (last_existing_chunk)
1318 + /* Truncate whatever was added at the end of the existing chunkset */
1319 + prev_chunk= last_existing_chunk;
1320 + curr_chunk= *((uchar **)(prev_chunk + info->offset_link));
1321 + *((uchar **)(prev_chunk + info->offset_link))= NULL;
1322 + hp_free_chunks(info, curr_chunk);
1324 + else if (first_chunk)
1326 + /* free any chunks previously allocated */
1327 + hp_free_chunks(info, first_chunk);
1333 + /* mark as if this chunk is last in the chunkset */
1334 + *((uchar **) (curr_chunk + info->offset_link))= 0;
1338 + /* tie them into a linked list */
1339 + *((uchar **) (prev_chunk + info->offset_link))= curr_chunk;
1340 + /* Record linked from active */
1341 + curr_chunk[info->offset_status]= CHUNK_STATUS_LINKED;
1345 + /* Record active */
1346 + curr_chunk[info->offset_status]= CHUNK_STATUS_ACTIVE;
1351 + first_chunk= curr_chunk;
1354 + prev_chunk= curr_chunk;
1357 + return first_chunk;
1362 + Allocate a new chunkset in the dataspace
1364 + Attempts to allocate a new chunkset
1366 + @param info the hosting dataspace
1367 + @param chunk_count the number of chunks that we expect as the result
1369 + @return Pointer to the first chunk in the new or updated chunkset, or NULL if
1373 +uchar *hp_allocate_chunkset(HP_DATASPACE *info, uint chunk_count)
1377 + DBUG_ENTER("hp_allocate_chunks");
1379 + if (info->is_variable_size)
1381 + result = hp_allocate_variable_chunkset(info, chunk_count, NULL);
1385 + result= hp_allocate_one_chunk(info);
1388 + result[info->offset_status]= CHUNK_STATUS_ACTIVE;
1391 + DBUG_RETURN(result);
1394 + DBUG_RETURN(result);
1399 + Reallocate an existing chunkset in the dataspace
1401 + Attempts to change the size of an existing chunkset
1403 + @param info the hosting dataspace
1404 + @param chunk_count the number of chunks that we expect as the result
1405 + @param pos pointer to the existing chunkset
1407 + @return Error code or zero if successful
1410 +int hp_reallocate_chunkset(HP_DATASPACE *info, uint chunk_count, uchar *pos)
1412 + DBUG_ENTER("hp_reallocate_chunks");
1414 + if (!info->is_variable_size)
1416 + /* Update should never change chunk_count in fixed-size mode */
1417 + my_errno= HA_ERR_WRONG_COMMAND;
1421 + /* Reallocate never moves the first chunk */
1422 + if (!hp_allocate_variable_chunkset(info, chunk_count, pos))
1423 + DBUG_RETURN(my_errno);
1430 + Allocate a single chunk in the dataspace
1432 + Attempts to allocate a new chunk or reuse one from deleted list
1434 + @param info the hosting dataspace
1436 + @return Pointer to the chunk, or NULL if unsuccessful
1439 +static uchar *hp_allocate_one_chunk(HP_DATASPACE *info)
1441 + uchar *curr_chunk;
1445 + if (info->del_link)
1447 + curr_chunk= info->del_link;
1448 + info->del_link= *((uchar **) curr_chunk);
1449 + info->del_chunk_count--;
1451 + DBUG_PRINT("hp_allocate_one_chunk",
1452 + ("Used old position: 0x%lx",(long) curr_chunk));
1453 + return curr_chunk;
1456 + block_pos= (info->chunk_count % info->block.records_in_block);
1459 + if (hp_get_new_block(&info->block, &length))
1461 + /* no space in the current block */
1465 + info->total_data_length+= length;
1468 + info->chunk_count++;
1469 + curr_chunk= ((uchar *) info->block.level_info[0].last_blocks +
1470 + block_pos * info->block.recbuffer);
1472 + DBUG_PRINT("hp_allocate_one_chunk",
1473 + ("Used new position: 0x%lx", (long) curr_chunk));
1475 + return curr_chunk;
1480 + Free a list of chunks
1482 + Reclaims all chunks linked by the pointer,
1483 + which could be the whole chunkset or a part of an existing chunkset
1485 + @param info the hosting dataspace
1486 + @param pos pointer to the head of the chunkset
1489 +void hp_free_chunks(HP_DATASPACE *info, uchar *pos)
1491 + uchar *curr_chunk= pos;
1493 + while (curr_chunk)
1495 + info->del_chunk_count++;
1496 + *((uchar **) curr_chunk)= info->del_link;
1497 + info->del_link= curr_chunk;
1499 + curr_chunk[info->offset_status]= CHUNK_STATUS_DELETED;
1501 + DBUG_PRINT("hp_free_chunks",("Freed position: 0x%lx", (long) curr_chunk));
1503 + if (!info->is_variable_size)
1508 + /* Delete next chunk in this chunkset */
1509 + curr_chunk= *((uchar **)(curr_chunk + info->offset_link));
1512 --- a/storage/heap/hp_extra.c
1513 +++ b/storage/heap/hp_extra.c
1515 info->current_record= (ulong) ~0L;
1516 info->current_hash_ptr=0;
1518 - info->next_block=0;
1522 --- a/storage/heap/hp_hash.c
1523 +++ b/storage/heap/hp_hash.c
1524 @@ -336,16 +336,26 @@
1526 CHARSET_INFO *cs= seg->charset;
1527 uint pack_length= seg->bit_start;
1528 - uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
1529 + uint length= hp_calc_blob_length(pack_length, pos);
1531 + if (seg->flag & HA_BLOB_PART)
1533 + memcpy(&pos, pos + pack_length, sizeof(char *));
1537 + pos+= pack_length;
1540 if (cs->mbmaxlen > 1)
1543 - char_length= my_charpos(cs, pos + pack_length,
1544 - pos + pack_length + length,
1545 + char_length= my_charpos(cs, pos,
1547 seg->length/cs->mbmaxlen);
1548 set_if_smaller(length, char_length);
1550 - cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2);
1551 + cs->coll->hash_sort(cs, pos, length, &nr, &nr2);
1555 @@ -545,18 +555,18 @@
1556 uint char_length1, char_length2;
1557 uint pack_length= seg->bit_start;
1558 CHARSET_INFO *cs= seg->charset;
1559 - if (pack_length == 1)
1561 - char_length1= (uint) *(uchar*) pos1++;
1562 - char_length2= (uint) *(uchar*) pos2++;
1566 + char_length1= hp_calc_blob_length(pack_length, pos1);
1567 + char_length2= hp_calc_blob_length(pack_length, pos2);
1568 + pos1+= pack_length;
1569 + pos2+= pack_length;
1571 + if (seg->flag & HA_BLOB_PART)
1573 - char_length1= uint2korr(pos1);
1574 - char_length2= uint2korr(pos2);
1577 + memcpy(&pos1, pos1, sizeof(char *));
1578 + memcpy(&pos2, pos2, sizeof(char *));
1581 if (cs->mbmaxlen > 1)
1583 uint safe_length1= char_length1;
1584 @@ -668,6 +678,34 @@
1589 + Returns a BLOB length stored in the specified number of bytes at the
1590 + specified location.
1592 + @param length the number of bytes used to store length
1593 + @param pos pointer to length bytes
1595 + @return Length of BLOB data.
1598 +uint hp_calc_blob_length(uint bytes, const uchar *pos)
1602 + return (uint) *pos;
1604 + return uint2korr(pos);
1606 + return uint3korr(pos);
1608 + return uint4korr(pos);
1613 + return 0; /* Impossible */
1616 /* Copy a key from a record to a keybuffer */
1618 void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec)
1619 @@ -678,18 +716,37 @@
1621 CHARSET_INFO *cs= seg->charset;
1622 uint char_length= seg->length;
1623 - uchar *pos= (uchar*) rec + seg->start;
1624 + const uchar *pos= rec + seg->start;
1626 *key++= test(rec[seg->null_pos] & seg->null_bit);
1627 - if (cs->mbmaxlen > 1)
1629 + if (seg->flag & HA_BLOB_PART)
1631 - char_length= my_charpos(cs, pos, pos + seg->length,
1632 - char_length / cs->mbmaxlen);
1633 - set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
1634 + uint tmp_length= hp_calc_blob_length(seg->bit_start, pos);
1635 + uint length= min(seg->length, tmp_length);
1637 + memcpy(&pos, rec + seg->bit_start, sizeof(char *));
1638 + if (cs->mbmaxlen > 1)
1640 + char_length= my_charpos(cs, pos, pos + seg->length,
1641 + char_length / cs->mbmaxlen);
1642 + set_if_smaller(char_length, length); /* QQ: ok to remove? */
1644 + store_key_length_inc(key, char_length);
1646 - if (seg->type == HA_KEYTYPE_VARTEXT1)
1647 - char_length+= seg->bit_start; /* Copy also length */
1648 - memcpy(key,rec+seg->start,(size_t) char_length);
1651 + if (cs->mbmaxlen > 1)
1653 + char_length= my_charpos(cs, pos, pos + seg->length,
1654 + char_length / cs->mbmaxlen);
1655 + set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
1657 + if (seg->type == HA_KEYTYPE_VARTEXT1)
1658 + char_length+= seg->bit_start; /* Copy also length */
1661 + memcpy(key, pos, (size_t) char_length);
1669 -uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
1670 - const uchar *rec, uchar *recpos)
1671 +uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
1672 + const uchar *rec, uchar *recpos, my_bool packed)
1674 uchar *start_key= key;
1675 HA_KEYSEG *seg, *endseg;
1676 @@ -772,6 +829,29 @@
1680 + else if (seg->flag & HA_BLOB_PART)
1682 + uchar *pos= (uchar*) rec + seg->start;
1683 + uint tmp_length= hp_calc_blob_length(seg->bit_start, pos);
1684 + uint length= min(seg->length, tmp_length);
1685 + CHARSET_INFO *cs= seg->charset;
1686 + char_length= seg->length / cs->mbmaxlen;
1688 + /* check_one_rb_key() calls hp_rb_make_key() for already packed records */
1691 + memcpy(&pos, pos + seg->bit_start, sizeof(char *));
1695 + pos+= seg->bit_start;
1697 + FIX_LENGTH(cs, pos, length, char_length);
1698 + store_key_length_inc(key, char_length);
1699 + memcpy(key, pos, (size_t) char_length);
1700 + key+= char_length;
1704 char_length= seg->length;
1705 if (seg->charset->mbmaxlen > 1)
1706 --- a/storage/heap/hp_info.c
1707 +++ b/storage/heap/hp_info.c
1710 DBUG_ENTER("heap_info");
1711 x->records = info->s->records;
1712 - x->deleted = info->s->deleted;
1713 - x->reclength = info->s->reclength;
1714 - x->data_length = info->s->data_length;
1715 + x->deleted = info->s->recordspace.del_chunk_count;
1717 + if (info->s->recordspace.is_variable_size)
1719 + if (info->s->records)
1720 + x->reclength = (uint) (info->s->recordspace.total_data_length /
1721 + (ulonglong) info->s->records);
1723 + x->reclength = info->s->recordspace.chunk_length;
1727 + x->reclength = info->s->recordspace.chunk_dataspace_length;
1730 + x->data_length = info->s->recordspace.total_data_length;
1731 x->index_length = info->s->index_length;
1732 x->max_records = info->s->max_records;
1733 x->errkey = info->errkey;
1734 --- a/storage/heap/hp_open.c
1735 +++ b/storage/heap/hp_open.c
1738 info->opt_flag= READ_CHECK_USED; /* Check when changing */
1740 - DBUG_PRINT("exit",("heap: 0x%lx reclength: %d records_in_block: %d",
1741 - (long) info, share->reclength,
1742 - share->block.records_in_block));
1743 + DBUG_PRINT("exit",("heap: 0x%lx chunk_length: %d records_in_block: %d",
1744 + (long) info, share->recordspace.chunk_length,
1745 + share->recordspace.block.records_in_block));
1750 +++ b/storage/heap/hp_record.c
1752 +/* Copyright (C) 2000-2002 MySQL AB
1753 + Copyright (C) 2008 eBay, Inc
1755 + This program is free software; you can redistribute it and/or modify
1756 + it under the terms of the GNU General Public License as published by
1757 + the Free Software Foundation; version 2 of the License.
1759 + This program is distributed in the hope that it will be useful,
1760 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1761 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1762 + GNU General Public License for more details.
1764 + You should have received a copy of the GNU General Public License
1765 + along with this program; if not, write to the Free Software
1766 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
1769 + Implements various base record-related functions, such as encode and decode
1773 +#include "heapdef.h"
1774 +#include <mysql_com.h>
1777 + Calculate size of the record for the purpose of storing in chunks
1779 + Walk through the fields of the record and calculates the exact space
1780 + needed in chunks as well the the total chunk count
1782 + @param info the hosting table
1783 + @param record the record in standard unpacked format
1784 + @param[out] chunk_count the number of chunks needed for this record
1786 + @return The size of the required storage in bytes
1789 +uint hp_get_encoded_data_length(HP_SHARE *info, const uchar *record,
1790 + uint *chunk_count)
1792 + uint i, dst_offset;
1794 + dst_offset= info->fixed_data_length;
1796 + if (!info->recordspace.is_variable_size)
1798 + /* Nothing more to copy */
1800 + return dst_offset;
1803 + for (i= info->fixed_column_count; i < info->column_count; i++)
1805 + uint src_offset, length;
1807 + HP_COLUMNDEF *column= info->column_defs + i;
1809 + if (column->null_bit)
1811 + if (record[column->null_pos] & column->null_bit)
1813 + /* Skip all NULL values */
1818 + src_offset= column->offset;
1819 + if (column->type == MYSQL_TYPE_VARCHAR)
1823 + /* >= 5.0.3 true VARCHAR */
1825 + pack_length= column->length_bytes;
1826 + length= pack_length + (pack_length == 1 ?
1827 + (uint) *(uchar *) (record + src_offset) :
1828 + uint2korr(record + src_offset));
1830 + else if (column->type == MYSQL_TYPE_BLOB)
1832 + uint pack_length= column->length_bytes;
1834 + length= pack_length + hp_calc_blob_length(pack_length,
1835 + record + src_offset);
1839 + length= column->length;
1842 + dst_offset+= length;
1845 + *chunk_count= get_chunk_count(&info->recordspace, dst_offset);
1847 + return dst_offset;
1851 +#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
1852 +static void dump_chunk(HP_SHARE *info, const uchar *curr_chunk)
1855 + fprintf(stdout, "Chunk dump at 0x%lx: ", (long) curr_chunk);
1856 + for (i= 0; i < info->recordspace.chunk_dataspace_length; i++)
1858 + uint b= *((uchar *)(curr_chunk + i));
1861 + fprintf(stdout, "0");
1863 + fprintf(stdout, "%lx ", (long) b);
1865 + fprintf(stdout, ". Next = 0x%lx, Status = %d\n",
1866 + (long) (*((uchar **) (curr_chunk + info->recordspace.offset_link))),
1867 + (uint) (*((uchar *) (curr_chunk + info->recordspace.offset_status))));
1872 + Stores data from packed field into the preallocated chunkset,
1873 + or performs data comparison
1875 + @param info the hosting table
1876 + @param data the field data in packed format
1877 + @param length the field data length
1878 + @param pos_ptr the target chunkset
1879 + @param off_ptr the pointer to the offset within the current chunkset
1880 + @param is_compare flag indicating whether we should compare data or store
1883 + @return Status of comparison
1884 + @retval non-zero if comparison found data differences
1885 + @retval zero otherwise
1889 +hp_process_field_data_to_chunkset(HP_SHARE *info, const uchar *data,
1890 + uint length, uchar **pos_ptr, uint *off_ptr,
1894 + uchar *curr_chunk= *pos_ptr;
1895 + uint dst_offset= *off_ptr;
1898 + while (length > 0)
1901 + to_copy= info->recordspace.chunk_dataspace_length - dst_offset;
1904 + /* Jump to the next chunk */
1905 +#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
1906 + dump_chunk(info, curr_chunk);
1908 + curr_chunk= *((uchar **) (curr_chunk + info->recordspace.offset_link));
1913 + to_copy= min(length, to_copy);
1917 + if (memcmp(curr_chunk + dst_offset, data, (size_t) to_copy))
1924 + memcpy(curr_chunk + dst_offset, data, (size_t) to_copy);
1928 + dst_offset+= to_copy;
1935 + *pos_ptr= curr_chunk;
1936 + *off_ptr= dst_offset;
1942 + Encodes or compares record
1944 + Copies data from original unpacked record into the preallocated chunkset,
1945 + or performs data comparison
1947 + @param info the hosting table
1948 + @param record the record in standard unpacked format
1949 + @param pos the target chunkset
1950 + @param is_compare flag indicating whether we should compare data or store
1953 + @return Status of comparison
1954 + @retval non-zero if comparison fond data differences
1955 + @retval zero otherwise
1958 +uint hp_process_record_data_to_chunkset(HP_SHARE *info, const uchar *record,
1959 + uchar *pos, uint is_compare)
1961 + uint i, dst_offset;
1962 + uchar *curr_chunk= pos;
1966 + if (memcmp(curr_chunk, record, (size_t) info->fixed_data_length))
1973 + memcpy(curr_chunk, record, (size_t) info->fixed_data_length);
1976 + if (!info->recordspace.is_variable_size)
1978 + /* Nothing more to copy */
1982 + dst_offset= info->fixed_data_length;
1984 + for (i= info->fixed_column_count; i < info->column_count; i++)
1987 + const uchar *data;
1989 + HP_COLUMNDEF *column= info->column_defs + i;
1991 + if (column->null_bit)
1993 + if (record[column->null_pos] & column->null_bit)
1995 + /* Skip all NULL values */
2000 + data= record + column->offset;
2001 + if (column->type == MYSQL_TYPE_VARCHAR)
2005 + /* >= 5.0.3 true VARCHAR */
2007 + /* Make sure to copy length indicator and actuals string bytes */
2008 + pack_length= column->length_bytes;
2009 + length= pack_length + (pack_length == 1 ? (uint) *data : uint2korr(data));
2011 + else if (column->type == MYSQL_TYPE_BLOB)
2015 + pack_length= column->length_bytes;
2016 + /* Just want to store the length, so not interested in the return code */
2017 + (void) hp_process_field_data_to_chunkset(info, data, pack_length,
2018 + &curr_chunk, &dst_offset, 0);
2019 + length= hp_calc_blob_length(pack_length, data);
2020 + memcpy(&data, data + pack_length, sizeof(char *));
2024 + length= column->length;
2027 + if (hp_process_field_data_to_chunkset(info, data, length, &curr_chunk,
2028 + &dst_offset, is_compare))
2034 +#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
2035 + dump_chunk(info, curr_chunk);
2043 + Stores record in the heap table chunks
2045 + Copies data from original unpacked record into the preallocated chunkset
2047 + @param info the hosting table
2048 + @param record the record in standard unpacked format
2049 + @param pos the target chunkset
2052 +void hp_copy_record_data_to_chunkset(HP_SHARE *info, const uchar *record,
2055 + DBUG_ENTER("hp_copy_record_data_to_chunks");
2057 + hp_process_record_data_to_chunkset(info, record, pos, 0);
2064 + Macro to switch curr_chunk to the next chunk in the chunkset and reset
2067 +#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
2068 +#define SWITCH_TO_NEXT_CHUNK_FOR_READ(share, curr_chunk, src_offset) \
2070 + curr_chunk= *((uchar**) (curr_chunk + share->recordspace.offset_link)); \
2072 + dump_chunk(share, curr_chunk); \
2075 +#define SWITCH_TO_NEXT_CHUNK_FOR_READ(share, curr_chunk, src_offset) \
2077 + curr_chunk= *((uchar**) (curr_chunk + share->recordspace.offset_link)); \
2083 + Copies record data from storage to unpacked record format
2085 + Copies data from chunkset into its original unpacked record
2087 + @param info the hosting table
2088 + @param[out] record the target record in standard unpacked format
2089 + @param pos the source chunkset
2091 + @return Status of conversion
2093 + @retval 1 out of memory
2096 +int hp_extract_record(HP_INFO *info, uchar *record, const uchar *pos)
2098 + uint i, src_offset;
2099 + const uchar *curr_chunk= pos;
2100 + HP_SHARE *share= info->s;
2101 + uint *rec_offsets= NULL;
2102 + uint *buf_offsets= NULL;
2104 + uint init_offset= share->blobs * sizeof(uint) * 2;
2106 + DBUG_ENTER("hp_extract_record");
2108 +#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
2109 + if (share->recordspace.is_variable_size)
2111 + dump_chunk(share, curr_chunk);
2115 + memcpy(record, curr_chunk, (size_t) share->fixed_data_length);
2117 + if (!share->recordspace.is_variable_size)
2119 + /* Nothing more to copy */
2123 + /* Reserve space for rec_offsets and buf_offsets.*/
2124 + info->blob_offset= init_offset;
2125 + src_offset= share->fixed_data_length;
2127 + for (i= share->fixed_column_count; i < share->column_count; i++)
2129 + uint length, is_null= 0;
2132 + HP_COLUMNDEF *column= share->column_defs + i;
2134 + if (column->null_bit)
2136 + if (record[column->null_pos] & column->null_bit)
2144 + /* TODO: is memset really needed? */
2145 + memset(record + column->offset, 0, column->length);
2149 + to= record + column->offset;
2150 + if (column->type == MYSQL_TYPE_VARCHAR || column->type == MYSQL_TYPE_BLOB)
2152 + uint pack_length, i;
2155 + pack_length= column->length_bytes;
2157 + for (i= 0; i < pack_length; i++)
2159 + if (src_offset == share->recordspace.chunk_dataspace_length)
2161 + SWITCH_TO_NEXT_CHUNK_FOR_READ(share, curr_chunk, src_offset);
2163 + *to++= curr_chunk[src_offset++];
2166 + We copy byte-by-byte and then use hp_calc_blob_length to combine bytes
2167 + in the right order.
2169 + length= hp_calc_blob_length(pack_length, tmp);
2171 + if (column->type == MYSQL_TYPE_BLOB && length == 0)
2174 + Store a zero pointer for zero-length BLOBs because the server
2175 + relies on that (see Field_blob::val_*().
2177 + *(uchar **) to= 0;
2179 + else if (column->type == MYSQL_TYPE_BLOB && length > 0)
2181 + uint newsize= info->blob_offset + length;
2183 + DBUG_ASSERT(share->blobs > 0);
2185 + Make sure we have enough space in blob_buffer and store the pointer
2186 + to this blob in record.
2188 + if (info->blob_size < newsize)
2191 + ptr= my_realloc(info->blob_buffer, newsize, MYF(MY_ALLOW_ZERO_PTR));
2197 + if (info->blob_buffer == NULL)
2199 + memset(ptr, 0, init_offset);
2201 + info->blob_buffer= ptr;
2202 + info->blob_size= newsize;
2205 + rec_offsets= (uint *) info->blob_buffer;
2206 + buf_offsets= rec_offsets + share->blobs;
2208 + rec_offsets[nblobs]= (uint) (to - record);
2209 + buf_offsets[nblobs]= info->blob_offset;
2212 + /* Change 'to' so blob data is copied into blob_buffer */
2213 + to= info->blob_buffer + info->blob_offset;
2214 + info->blob_offset= newsize;
2219 + length= column->length;
2222 + while (length > 0)
2226 + to_copy= share->recordspace.chunk_dataspace_length - src_offset;
2229 + SWITCH_TO_NEXT_CHUNK_FOR_READ(share, curr_chunk, src_offset);
2230 + to_copy= share->recordspace.chunk_dataspace_length;
2233 + to_copy= min(length, to_copy);
2235 + memcpy(to, curr_chunk + src_offset, (size_t) to_copy);
2236 + src_offset+= to_copy;
2242 + /* Store pointers to blob data in record */
2243 + for (i= 0; i < nblobs; i++)
2245 + *(uchar **) (record + rec_offsets[i]) = info->blob_buffer + buf_offsets[i];
2250 --- a/storage/heap/hp_rfirst.c
2251 +++ b/storage/heap/hp_rfirst.c
2253 memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
2255 info->current_ptr = pos;
2256 - memcpy(record, pos, (size_t)share->reclength);
2257 + if (hp_extract_record(info, record, pos))
2259 + DBUG_RETURN(my_errno);
2262 If we're performing index_first on a table that was taken from
2263 table cache, info->lastkey_len is initialized to previous query.
2264 --- a/storage/heap/hp_rkey.c
2265 +++ b/storage/heap/hp_rkey.c
2267 if (!(keyinfo->flag & HA_NOSAME))
2268 memcpy(info->lastkey, key, (size_t) keyinfo->length);
2270 - memcpy(record, pos, (size_t) share->reclength);
2271 + if (hp_extract_record(info, record, pos))
2273 + DBUG_RETURN(my_errno);
2275 info->update= HA_STATE_AKTIV;
2278 --- a/storage/heap/hp_rlast.c
2279 +++ b/storage/heap/hp_rlast.c
2281 memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
2283 info->current_ptr = pos;
2284 - memcpy(record, pos, (size_t)share->reclength);
2285 + if (hp_extract_record(info, record, pos))
2287 + DBUG_RETURN(my_errno);
2289 info->update = HA_STATE_AKTIV;
2292 --- a/storage/heap/hp_rnext.c
2293 +++ b/storage/heap/hp_rnext.c
2294 @@ -109,7 +109,10 @@
2295 my_errno=HA_ERR_END_OF_FILE;
2296 DBUG_RETURN(my_errno);
2298 - memcpy(record,pos,(size_t) share->reclength);
2299 + if (hp_extract_record(info, record, pos))
2301 + DBUG_RETURN(my_errno);
2303 info->update=HA_STATE_AKTIV | HA_STATE_NEXT_FOUND;
2306 --- a/storage/heap/hp_rprev.c
2307 +++ b/storage/heap/hp_rprev.c
2309 my_errno=HA_ERR_END_OF_FILE;
2310 DBUG_RETURN(my_errno);
2312 - memcpy(record,pos,(size_t) share->reclength);
2313 + if (hp_extract_record(info, record, pos))
2315 + DBUG_RETURN(my_errno);
2317 info->update=HA_STATE_AKTIV | HA_STATE_PREV_FOUND;
2320 --- a/storage/heap/hp_rrnd.c
2321 +++ b/storage/heap/hp_rrnd.c
2324 DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
2326 - if (!info->current_ptr[share->reclength])
2327 + if (get_chunk_status(&share->recordspace, info->current_ptr) !=
2328 + CHUNK_STATUS_ACTIVE)
2330 + /* treat deleted and linked chunks as deleted */
2331 info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
2332 DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
2334 info->update=HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND | HA_STATE_AKTIV;
2335 - memcpy(record,info->current_ptr,(size_t) share->reclength);
2336 + if (hp_extract_record(info, record, info->current_ptr))
2338 + DBUG_RETURN(my_errno);
2340 DBUG_PRINT("exit", ("found record at 0x%lx", (long) info->current_ptr));
2341 info->current_hash_ptr=0; /* Can't use rnext */
2345 pos= ++info->current_record;
2346 if (pos % share->block.records_in_block && /* Quick next record */
2347 - pos < share->records+share->deleted &&
2348 - (info->update & HA_STATE_PREV_FOUND))
2349 + pos < share->used_chunk_count + share->deleted_chunk_count &&
2350 + (info->update & HA_STATE_PREV_FOUND))
2352 - info->current_ptr+=share->block.recbuffer;
2353 + info->current_ptr+= share->block.recbufferlen;
2358 info->current_record=pos;
2360 - if (pos >= share->records+share->deleted)
2361 + if (pos >= share->used_chunk_count + share->deleted_chunk_count)
2364 DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
2366 hp_find_record(info, pos);
2369 - if (!info->current_ptr[share->reclength])
2370 + if (GET_CHUNK_STATUS(info, info->current_ptr) != CHUNK_STATUS_ACTIVE)
2372 + /* treat deleted and linked chunks as deleted */
2373 info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
2374 DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
2376 info->update=HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND | HA_STATE_AKTIV;
2377 - memcpy(record,info->current_ptr,(size_t) share->reclength);
2378 + if (hp_extract_record(info, record, info->current_ptr))
2380 + DBUG_RETURN(my_errno);
2382 DBUG_PRINT("exit",("found record at 0x%lx",info->current_ptr));
2383 info->current_hash_ptr=0; /* Can't use rnext */
2385 --- a/storage/heap/hp_rsame.c
2386 +++ b/storage/heap/hp_rsame.c
2388 DBUG_ENTER("heap_rsame");
2391 - if (info->current_ptr[share->reclength])
2392 + if (get_chunk_status(&share->recordspace, info->current_ptr) ==
2393 + CHUNK_STATUS_ACTIVE)
2395 if (inx < -1 || inx >= (int) share->keys)
2398 DBUG_RETURN(my_errno);
2401 - memcpy(record,info->current_ptr,(size_t) share->reclength);
2402 + if (hp_extract_record(info, record, info->current_ptr))
2404 + DBUG_RETURN(my_errno);
2409 + /* treat deleted and linked chunks as deleted */
2413 DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
2414 --- a/storage/heap/hp_scan.c
2415 +++ b/storage/heap/hp_scan.c
2418 info->current_record= (ulong) ~0L; /* No current record */
2420 - info->next_block=0;
2425 DBUG_ENTER("heap_scan");
2427 pos= ++info->current_record;
2428 - if (pos < info->next_block)
2429 + if (pos >= share->recordspace.chunk_count)
2431 - info->current_ptr+=share->block.recbuffer;
2433 + DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
2437 - info->next_block+=share->block.records_in_block;
2438 - if (info->next_block >= share->records+share->deleted)
2440 - info->next_block= share->records+share->deleted;
2441 - if (pos >= info->next_block)
2444 - DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
2447 - hp_find_record(info, pos);
2449 - if (!info->current_ptr[share->reclength])
2451 + hp_find_record(info, pos);
2453 + if (get_chunk_status(&share->recordspace, info->current_ptr) !=
2454 + CHUNK_STATUS_ACTIVE)
2456 - DBUG_PRINT("warning",("Found deleted record"));
2457 + DBUG_PRINT("warning",("Found deleted record or secondary chunk"));
2458 info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
2459 DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
2461 info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND | HA_STATE_AKTIV;
2462 - memcpy(record,info->current_ptr,(size_t) share->reclength);
2463 + if (hp_extract_record(info, record, info->current_ptr))
2465 + DBUG_RETURN(my_errno);
2467 info->current_hash_ptr=0; /* Can't use read_next */
2470 --- a/storage/heap/hp_test1.c
2471 +++ b/storage/heap/hp_test1.c
2473 #include <my_global.h>
2475 #include <m_string.h>
2476 +#include <mysql_com.h>
2479 static int get_options(int argc, char *argv[]);
2481 uchar record[128],key[32];
2482 const char *filename;
2483 HP_KEYDEF keyinfo[10];
2484 + HP_COLUMNDEF columndef[2];
2485 HA_KEYSEG keyseg[4];
2486 HP_CREATE_INFO hp_create_info;
2487 HP_SHARE *tmp_share;
2489 hp_create_info.reclength= 30;
2490 hp_create_info.max_records= (ulong) flag*100000L;
2491 hp_create_info.min_records= 10UL;
2492 + hp_create_info.columns= 2;
2493 + hp_create_info.columndef= columndef;
2494 + hp_create_info.fixed_key_fieldnr= 30;
2495 + hp_create_info.fixed_data_size= sizeof(char*) * 2;
2497 keyinfo[0].keysegs=1;
2498 keyinfo[0].seg=keyseg;
2500 keyinfo[0].seg[0].null_bit= 0;
2501 keyinfo[0].flag = HA_NOSAME;
2503 + memset(columndef, 0, 2 * sizeof(HP_COLUMNDEF));
2504 + columndef[0].type= MYSQL_TYPE_STRING;
2505 + columndef[0].offset= 1;
2506 + columndef[0].length= 6;
2507 + columndef[1].type= MYSQL_TYPE_STRING;
2508 + columndef[1].offset= 7;
2509 + columndef[1].length= 23;
2512 bzero((uchar*) flags,sizeof(flags));
2514 printf("- Creating heap-file\n");
2515 - if (heap_create(filename, &hp_create_info, &tmp_share, &unused) ||
2516 + if (heap_create(filename, &hp_create_info,
2517 + &tmp_share, &unused) ||
2518 !(file= heap_open(filename, 2)))
2520 printf("- Writing records:s\n");
2521 --- a/storage/heap/hp_test2.c
2522 +++ b/storage/heap/hp_test2.c
2525 #include "heapdef.h" /* Because of hp_find_block */
2527 +#include <mysql_com.h>
2529 #define MAX_RECORDS 100000
2532 HP_SHARE *tmp_share;
2533 HP_KEYDEF keyinfo[MAX_KEYS];
2534 HA_KEYSEG keyseg[MAX_KEYS*5];
2535 + HP_COLUMNDEF columndef[4];
2536 HEAP_PTR UNINIT_VAR(position);
2537 HP_CREATE_INFO hp_create_info;
2538 CHARSET_INFO *cs= &my_charset_latin1;
2540 get_options(argc,argv);
2542 bzero(&hp_create_info, sizeof(hp_create_info));
2543 - hp_create_info.max_table_size= 1024L*1024L;
2544 + hp_create_info.max_table_size= 1024L*1024L*1024L;
2545 hp_create_info.keys= keys;
2546 hp_create_info.keydef= keyinfo;
2547 hp_create_info.reclength= reclength;
2548 hp_create_info.max_records= (ulong) flag*100000L;
2549 hp_create_info.min_records= (ulong) recant/2;
2550 + hp_create_info.columns= 4;
2551 + hp_create_info.columndef= columndef;
2552 + hp_create_info.fixed_key_fieldnr= 4;
2553 + hp_create_info.fixed_data_size= 39;
2555 write_count=update=opt_delete=0;
2557 @@ -118,11 +124,28 @@
2558 keyinfo[3].seg[0].null_pos=38;
2559 keyinfo[3].seg[0].charset=cs;
2561 + memset(columndef, 0, 4 * sizeof(HP_COLUMNDEF));
2562 + columndef[0].type= MYSQL_TYPE_STRING;
2563 + columndef[0].offset= 0;
2564 + columndef[0].length= 6;
2565 + columndef[1].type= MYSQL_TYPE_STRING;
2566 + columndef[1].offset= 7;
2567 + columndef[1].length= 6;
2568 + columndef[2].type= MYSQL_TYPE_STRING;
2569 + columndef[2].offset= 12;
2570 + columndef[2].length= 8;
2571 + columndef[3].type= MYSQL_TYPE_TINY;
2572 + columndef[3].offset= 37;
2573 + columndef[3].length= 1;
2574 + columndef[3].null_bit= 1;
2575 + columndef[3].null_pos= 38;
2577 bzero((char*) key1,sizeof(key1));
2578 bzero((char*) key3,sizeof(key3));
2580 printf("- Creating heap-file\n");
2581 - if (heap_create(filename, &hp_create_info, &tmp_share, &unused) ||
2582 + if (heap_create(filename, &hp_create_info,
2583 + &tmp_share, &unused) ||
2584 !(file= heap_open(filename, 2)))
2586 signal(SIGINT,endprog);
2587 --- a/storage/heap/hp_write.c
2588 +++ b/storage/heap/hp_write.c
2593 -static uchar *next_free_record_pos(HP_SHARE *info);
2594 static HASH_INFO *hp_find_free_hash(HP_SHARE *info, HP_BLOCK *block,
2598 HP_KEYDEF *keydef, *end;
2600 HP_SHARE *share=info->s;
2603 DBUG_ENTER("heap_write");
2605 if (info->mode & O_RDONLY)
2607 DBUG_RETURN(my_errno=EACCES);
2610 - if (!(pos=next_free_record_pos(share)))
2612 + if ((share->records >= share->max_records && share->max_records) ||
2613 + (share->recordspace.total_data_length + share->index_length >=
2614 + share->max_table_size))
2616 + my_errno= HA_ERR_RECORD_FILE_FULL;
2617 + DBUG_RETURN(my_errno);
2620 + hp_get_encoded_data_length(share, record, &chunk_count);
2622 + if (!(pos= hp_allocate_chunkset(&share->recordspace, chunk_count)))
2623 DBUG_RETURN(my_errno);
2630 - memcpy(pos,record,(size_t) share->reclength);
2631 - pos[share->reclength]=1; /* Mark record as not deleted */
2632 + hp_copy_record_data_to_chunkset(share, record, pos);
2634 if (++share->records == share->blength)
2635 share->blength+= share->blength;
2636 info->current_ptr=pos;
2642 - *((uchar**) pos)=share->del_link;
2643 - share->del_link=pos;
2644 - pos[share->reclength]=0; /* Record deleted */
2645 + hp_free_chunks(&share->recordspace, pos);
2647 DBUG_RETURN(my_errno);
2652 custom_arg.keyseg= keyinfo->seg;
2653 - custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
2654 + custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos,
2656 if (keyinfo->flag & HA_NOSAME)
2658 custom_arg.search_flag= SEARCH_FIND | SEARCH_UPDATE;
2659 @@ -129,42 +139,6 @@
2663 - /* Find where to place new record */
2665 -static uchar *next_free_record_pos(HP_SHARE *info)
2670 - DBUG_ENTER("next_free_record_pos");
2672 - if (info->del_link)
2674 - pos=info->del_link;
2675 - info->del_link= *((uchar**) pos);
2677 - DBUG_PRINT("exit",("Used old position: 0x%lx",(long) pos));
2680 - if (!(block_pos=(info->records % info->block.records_in_block)))
2682 - if ((info->records > info->max_records && info->max_records) ||
2683 - (info->data_length + info->index_length >= info->max_table_size))
2685 - my_errno=HA_ERR_RECORD_FILE_FULL;
2686 - DBUG_RETURN(NULL);
2688 - if (hp_get_new_block(&info->block,&length))
2689 - DBUG_RETURN(NULL);
2690 - info->data_length+=length;
2692 - DBUG_PRINT("exit",("Used new position: 0x%lx",
2693 - (long) ((uchar*) info->block.level_info[0].last_blocks+
2694 - block_pos * info->block.recbuffer)));
2695 - DBUG_RETURN((uchar*) info->block.level_info[0].last_blocks+
2696 - block_pos*info->block.recbuffer);
2701 Write a hash-key to the hash-index
2702 --- a/storage/heap/hp_update.c
2703 +++ b/storage/heap/hp_update.c
2706 #include "heapdef.h"
2708 -int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new)
2709 +int heap_update(HP_INFO *info, const uchar *old_record, const uchar *new_record)
2711 HP_KEYDEF *keydef, *end, *p_lastinx;
2713 my_bool auto_key_changed= 0;
2714 HP_SHARE *share= info->s;
2715 + uint old_chunk_count, new_chunk_count;
2717 DBUG_ENTER("heap_update");
2720 pos=info->current_ptr;
2722 - if (info->opt_flag & READ_CHECK_USED && hp_rectest(info,old))
2723 + if (info->opt_flag & READ_CHECK_USED && hp_rectest(info, old_record))
2724 DBUG_RETURN(my_errno); /* Record changed */
2726 + hp_get_encoded_data_length(share, old_record, &old_chunk_count);
2727 + hp_get_encoded_data_length(share, new_record, &new_chunk_count);
2729 + if (new_chunk_count > old_chunk_count)
2731 + /* extend the old chunkset size as necessary, but do not shrink yet */
2732 + if (hp_reallocate_chunkset(&share->recordspace, new_chunk_count, pos))
2734 + DBUG_RETURN(my_errno); /* Out of memory or table space */
2738 if (--(share->records) < share->blength >> 1) share->blength>>= 1;
2741 p_lastinx= share->keydef + info->lastinx;
2742 for (keydef= share->keydef, end= keydef + share->keys; keydef < end; keydef++)
2744 - if (hp_rec_key_cmp(keydef, old, heap_new, 0))
2745 + if (hp_rec_key_cmp(keydef, old_record, new_record, 0))
2747 - if ((*keydef->delete_key)(info, keydef, old, pos, keydef == p_lastinx) ||
2748 - (*keydef->write_key)(info, keydef, heap_new, pos))
2749 + if ((*keydef->delete_key)(info, keydef, old_record, pos,
2750 + keydef == p_lastinx) ||
2751 + (*keydef->write_key)(info, keydef, new_record, pos))
2753 if (share->auto_key == (uint) (keydef - share->keydef + 1))
2754 auto_key_changed= 1;
2758 - memcpy(pos,heap_new,(size_t) share->reclength);
2759 + hp_copy_record_data_to_chunkset(share, new_record, pos);
2760 if (++(share->records) == share->blength) share->blength+= share->blength;
2762 + if (new_chunk_count < old_chunk_count)
2764 + /* Shrink the chunkset to its new size */
2765 + hp_reallocate_chunkset(&share->recordspace, new_chunk_count, pos);
2768 #if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
2769 DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
2771 if (auto_key_changed)
2772 - heap_update_auto_increment(info, heap_new);
2773 + heap_update_auto_increment(info, new_record);
2778 if (keydef->algorithm == HA_KEY_ALG_BTREE)
2780 /* we don't need to delete non-inserted key from rb-tree */
2781 - if ((*keydef->write_key)(info, keydef, old, pos))
2782 + if ((*keydef->write_key)(info, keydef, old_record, pos))
2784 if (++(share->records) == share->blength)
2785 share->blength+= share->blength;
2788 while (keydef >= share->keydef)
2790 - if (hp_rec_key_cmp(keydef, old, heap_new, 0))
2791 + if (hp_rec_key_cmp(keydef, old_record, new_record, 0))
2793 - if ((*keydef->delete_key)(info, keydef, heap_new, pos, 0) ||
2794 - (*keydef->write_key)(info, keydef, old, pos))
2795 + if ((*keydef->delete_key)(info, keydef, new_record, pos, 0) ||
2796 + (*keydef->write_key)(info, keydef, old_record, pos))
2802 if (++(share->records) == share->blength)
2803 share->blength+= share->blength;
2805 + if (new_chunk_count > old_chunk_count)
2807 + /* Shrink the chunkset to its original size */
2808 + hp_reallocate_chunkset(&share->recordspace, old_chunk_count, pos);
2811 DBUG_RETURN(my_errno);
2814 +++ b/mysql-test/r/percona_heap_blob.result
2816 +SET @old_default_storage_engine=@@default_storage_engine;
2817 +SET default_storage_engine=MEMORY;
2818 +drop table if exists t1,t2,t3,t4,t5,t6,t7;
2819 +CREATE TABLE t1 (a blob, b text, c blob(250), d text(70000), e text(70000000));
2820 +show columns from t1;
2821 +Field Type Null Key Default Extra
2824 +c tinyblob YES NULL
2825 +d mediumtext YES NULL
2826 +e longtext YES NULL
2827 +CREATE TABLE t2 (a char(255), b varbinary(70000), c varchar(70000000));
2829 +Note 1246 Converting column 'b' from VARBINARY to BLOB
2830 +Note 1246 Converting column 'c' from VARCHAR to TEXT
2831 +CREATE TABLE t4 (c varchar(65530) character set utf8 not null);
2833 +Note 1246 Converting column 'c' from VARCHAR to TEXT
2834 +show columns from t2;
2835 +Field Type Null Key Default Extra
2836 +a char(255) YES NULL
2837 +b mediumblob YES NULL
2838 +c longtext YES NULL
2839 +create table t3 (a long, b long byte);
2840 +show create TABLE t3;
2842 +t3 CREATE TABLE `t3` (
2845 +) ENGINE=MEMORY DEFAULT CHARSET=latin1
2846 +show create TABLE t4;
2848 +t4 CREATE TABLE `t4` (
2849 + `c` mediumtext CHARACTER SET utf8 NOT NULL
2850 +) ENGINE=MEMORY DEFAULT CHARSET=latin1
2851 +drop table t1,t2,t3,t4;
2852 +CREATE TABLE t1 (a char(257) default "hello");
2853 +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
2854 +CREATE TABLE t2 (a char(256));
2855 +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
2856 +CREATE TABLE t1 (a varchar(70000) default "hello");
2857 +ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
2858 +CREATE TABLE t2 (a blob default "hello");
2859 +ERROR 42000: BLOB/TEXT column 'a' can't have a default value
2860 +drop table if exists t1,t2;
2861 +create table t1 (nr int(5) not null auto_increment,b blob,str char(10), primary key (nr));
2862 +insert into t1 values (null,"a","A");
2863 +insert into t1 values (null,"bbb","BBB");
2864 +insert into t1 values (null,"ccc","CCC");
2865 +select last_insert_id();
2868 +select * from t1,t1 as t2;
2874 +2 bbb BBB 2 bbb BBB
2875 +3 ccc CCC 2 bbb BBB
2877 +2 bbb BBB 3 ccc CCC
2878 +3 ccc CCC 3 ccc CCC
2880 +create table t1 (a text);
2881 +insert into t1 values ('where');
2882 +update t1 set a='Where';
2887 +create table t1 (t text,c char(10),b blob, d varbinary(10)) collate latin1_general_cs;
2888 +insert into t1 values (NULL,NULL,NULL,NULL);
2889 +insert into t1 values ("","","","");
2890 +insert into t1 values ("hello","hello","hello","hello");
2891 +insert into t1 values ("HELLO","HELLO","HELLO","HELLO");
2892 +insert into t1 values ("HELLO MY","HELLO MY","HELLO MY","HELLO MY");
2893 +insert into t1 values ("a","a","a","a");
2894 +insert into t1 values (1,1,1,1);
2895 +insert into t1 values (NULL,NULL,NULL,NULL);
2896 +update t1 set c="",b=null where c="1";
2897 +lock tables t1 READ;
2898 +show full fields from t1;
2899 +Field Type Collation Null Key Default Extra Privileges Comment
2900 +t text latin1_general_cs YES NULL #
2901 +c char(10) latin1_general_cs YES NULL #
2902 +b blob NULL YES NULL #
2903 +d varbinary(10) NULL YES NULL #
2904 +lock tables t1 WRITE;
2905 +show full fields from t1;
2906 +Field Type Collation Null Key Default Extra Privileges Comment
2907 +t text latin1_general_cs YES NULL #
2908 +c char(10) latin1_general_cs YES NULL #
2909 +b blob NULL YES NULL #
2910 +d varbinary(10) NULL YES NULL #
2912 +select t from t1 where t like "hello";
2915 +select c from t1 where c like "hello";
2918 +select b from t1 where b like "hello";
2921 +select d from t1 where d like "hello";
2924 +select c from t1 having c like "hello";
2927 +select d from t1 having d like "hello";
2930 +select t from t1 where t like "%HELLO%";
2934 +select c from t1 where c like "%HELLO%";
2938 +select b from t1 where b like "%HELLO%";
2942 +select d from t1 where d like "%HELLO%";
2946 +select c from t1 having c like "%HELLO%";
2950 +select d from t1 having d like "%HELLO%";
2954 +select d from t1 having d like "%HE%LLO%";
2958 +select t from t1 order by t;
2968 +select c from t1 order by c;
2978 +select b from t1 order by b;
2988 +select d from t1 order by d;
2998 +select distinct t from t1;
3007 +select distinct b from t1;
3015 +select distinct t from t1 order by t;
3024 +select distinct b from t1 order by b;
3032 +select t from t1 group by t;
3041 +select b from t1 group by b;
3049 +set option sql_big_tables=1;
3050 +select distinct t from t1;
3059 +select distinct b from t1;
3067 +select distinct t from t1 order by t;
3076 +select distinct b from t1 order by b;
3084 +select distinct c from t1;
3092 +select distinct d from t1;
3101 +select distinct c from t1 order by c;
3109 +select distinct d from t1 order by d;
3118 +select c from t1 group by c;
3126 +select d from t1 group by d;
3135 +set option sql_big_tables=0;
3136 +select distinct * from t1;
3138 +NULL NULL NULL NULL
3140 +hello hello hello hello
3141 +HELLO HELLO HELLO HELLO
3142 +HELLO MY HELLO MY HELLO MY HELLO MY
3145 +select t,count(*) from t1 group by t;
3154 +select b,count(*) from t1 group by b;
3162 +select c,count(*) from t1 group by c;
3170 +select d,count(*) from t1 group by d;
3181 +t1_id bigint(21) NOT NULL auto_increment,
3182 +_field_72 varchar(128) DEFAULT '' NOT NULL,
3183 +_field_95 varchar(32),
3184 +_field_115 tinyint(4) DEFAULT '0' NOT NULL,
3185 +_field_122 tinyint(4) DEFAULT '0' NOT NULL,
3186 +_field_126 tinyint(4),
3187 +_field_134 tinyint(4),
3188 +PRIMARY KEY (t1_id),
3189 +UNIQUE _field_72 (_field_72),
3190 +KEY _field_115 (_field_115),
3191 +KEY _field_122 (_field_122)
3193 +INSERT INTO t1 VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',0,1,NULL,NULL);
3194 +INSERT INTO t1 VALUES (2,'hroberts','7415275a8c95952901e42b13a6b78566',0,1,NULL,NULL);
3195 +INSERT INTO t1 VALUES (3,'guest','d41d8cd98f00b204e9800998ecf8427e',1,0,NULL,NULL);
3197 +seq_0_id bigint(21) DEFAULT '0' NOT NULL,
3198 +seq_1_id bigint(21) DEFAULT '0' NOT NULL,
3199 +PRIMARY KEY (seq_0_id,seq_1_id)
3201 +INSERT INTO t2 VALUES (1,1);
3202 +INSERT INTO t2 VALUES (2,1);
3203 +INSERT INTO t2 VALUES (2,2);
3205 +t3_id bigint(21) NOT NULL auto_increment,
3206 +_field_131 varchar(128),
3207 +_field_133 tinyint(4) DEFAULT '0' NOT NULL,
3208 +_field_135 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
3209 +_field_137 tinyint(4),
3210 +_field_139 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
3212 +_field_142 tinyint(4) DEFAULT '0' NOT NULL,
3213 +_field_145 tinyint(4) DEFAULT '0' NOT NULL,
3214 +_field_148 tinyint(4) DEFAULT '0' NOT NULL,
3215 +PRIMARY KEY (t3_id),
3216 +KEY _field_133 (_field_133),
3217 +KEY _field_135 (_field_135),
3218 +KEY _field_139 (_field_139),
3219 +KEY _field_142 (_field_142),
3220 +KEY _field_145 (_field_145),
3221 +KEY _field_148 (_field_148)
3223 +INSERT INTO t3 VALUES (1,'test job 1',0,'0000-00-00 00:00:00',0,'1999-02-25 22:43:32','test\r\njob\r\n1',0,0,0);
3224 +INSERT INTO t3 VALUES (2,'test job 2',0,'0000-00-00 00:00:00',0,'1999-02-26 21:08:04','',0,0,0);
3226 +seq_0_id bigint(21) DEFAULT '0' NOT NULL,
3227 +seq_1_id bigint(21) DEFAULT '0' NOT NULL,
3228 +PRIMARY KEY (seq_0_id,seq_1_id)
3230 +INSERT INTO t4 VALUES (1,1);
3231 +INSERT INTO t4 VALUES (2,1);
3233 +t5_id bigint(21) NOT NULL auto_increment,
3234 +_field_149 tinyint(4),
3235 +_field_156 varchar(128) DEFAULT '' NOT NULL,
3236 +_field_157 varchar(128) DEFAULT '' NOT NULL,
3237 +_field_158 varchar(128) DEFAULT '' NOT NULL,
3238 +_field_159 varchar(128) DEFAULT '' NOT NULL,
3239 +_field_160 varchar(128) DEFAULT '' NOT NULL,
3240 +_field_161 varchar(128) DEFAULT '' NOT NULL,
3241 +PRIMARY KEY (t5_id),
3242 +KEY _field_156 (_field_156),
3243 +KEY _field_157 (_field_157),
3244 +KEY _field_158 (_field_158),
3245 +KEY _field_159 (_field_159),
3246 +KEY _field_160 (_field_160),
3247 +KEY _field_161 (_field_161)
3249 +INSERT INTO t5 VALUES (1,0,'tomato','','','','','');
3250 +INSERT INTO t5 VALUES (2,0,'cilantro','','','','','');
3252 +seq_0_id bigint(21) DEFAULT '0' NOT NULL,
3253 +seq_1_id bigint(21) DEFAULT '0' NOT NULL,
3254 +PRIMARY KEY (seq_0_id,seq_1_id)
3256 +INSERT INTO t6 VALUES (1,1);
3257 +INSERT INTO t6 VALUES (1,2);
3258 +INSERT INTO t6 VALUES (2,2);
3260 +t7_id bigint(21) NOT NULL auto_increment,
3261 +_field_143 tinyint(4),
3262 +_field_165 varchar(32),
3263 +_field_166 smallint(6) DEFAULT '0' NOT NULL,
3264 +PRIMARY KEY (t7_id),
3265 +KEY _field_166 (_field_166)
3267 +INSERT INTO t7 VALUES (1,0,'High',1);
3268 +INSERT INTO t7 VALUES (2,0,'Medium',2);
3269 +INSERT INTO t7 VALUES (3,0,'Low',3);
3270 +select replace(t3._field_140, "\r","^M"),t3_id,min(t3._field_131), min(t3._field_135), min(t3._field_139), min(t3._field_137), min(link_alias_142._field_165), min(link_alias_133._field_72), min(t3._field_145), min(link_alias_148._field_156), replace(min(t3._field_140), "\r","^M"),t3.t3_id from t3 left join t4 on t4.seq_0_id = t3.t3_id left join t7 link_alias_142 on t4.seq_1_id = link_alias_142.t7_id left join t6 on t6.seq_0_id = t3.t3_id left join t1 link_alias_133 on t6.seq_1_id = link_alias_133.t1_id left join t2 on t2.seq_0_id = t3.t3_id left join t5 link_alias_148 on t2.seq_1_id = link_alias_148.t5_id where t3.t3_id in (1) group by t3.t3_id order by link_alias_142._field_166, _field_139, link_alias_133._field_72, _field_135, link_alias_148._field_156;
3271 +replace(t3._field_140, "\r","^M") t3_id min(t3._field_131) min(t3._field_135) min(t3._field_139) min(t3._field_137) min(link_alias_142._field_165) min(link_alias_133._field_72) min(t3._field_145) min(link_alias_148._field_156) replace(min(t3._field_140), "\r","^M") t3_id
3274 +1 1 test job 1 0000-00-00 00:00:00 1999-02-25 22:43:32 0 High admin 0 tomato test^M
3277 +drop table t1,t2,t3,t4,t5,t6,t7;
3278 +create table t1 (a blob);
3279 +insert into t1 values ("empty"),("");
3280 +select a,reverse(a) from t1;
3285 +create table t1 (id integer auto_increment unique,imagem LONGBLOB not null default '');
3287 +Warning 1101 BLOB/TEXT column 'imagem' can't have a default value
3288 +insert into t1 (id) values (1);
3290 +charset(load_file('../../std_data/words.dat')),
3291 +collation(load_file('../../std_data/words.dat')),
3292 +coercibility(load_file('../../std_data/words.dat'));
3293 +charset(load_file('../../std_data/words.dat')) collation(load_file('../../std_data/words.dat')) coercibility(load_file('../../std_data/words.dat'))
3295 +explain extended select
3296 +charset(load_file('MYSQLTEST_VARDIR/std_data/words.dat')),
3297 +collation(load_file('MYSQLTEST_VARDIR/std_data/words.dat')),
3298 +coercibility(load_file('MYSQLTEST_VARDIR/std_data/words.dat'));
3299 +id select_type table type possible_keys key key_len ref rows filtered Extra
3300 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
3302 +Note 1003 select charset(load_file('MYSQLTEST_VARDIR/std_data/words.dat')) AS `charset(load_file('MYSQLTEST_VARDIR/std_data/words.dat'))`,collation(load_file('MYSQLTEST_VARDIR/std_data/words.dat')) AS `collation(load_file('MYSQLTEST_VARDIR/std_data/words.dat'))`,coercibility(load_file('MYSQLTEST_VARDIR/std_data/words.dat')) AS `coercibility(load_file('MYSQLTEST_VARDIR/std_data/words.dat'))`
3303 +update t1 set imagem=load_file('MYSQLTEST_VARDIR/std_data/words.dat') where id=1;
3304 +select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1;
3305 +if(imagem is null, "ERROR", "OK") length(imagem)
3308 +create table t1 select load_file('MYSQLTEST_VARDIR/std_data/words.dat') l;
3309 +show full fields from t1;
3310 +Field Type Collation Null Key Default Extra Privileges Comment
3311 +l longblob NULL YES NULL #
3313 +create table t1 (id integer primary key auto_increment, txt text not null);
3314 +insert into t1 (txt) values ('Chevy ');
3315 +select * from t1 where txt='Chevy';
3318 +select * from t1 where txt='Chevy ';
3321 +select * from t1 where txt='Chevy ' or txt='Chevy';
3324 +select * from t1 where txt='Chevy' or txt='Chevy ';
3327 +select * from t1 where id='1' or id='2';
3330 +insert into t1 (txt) values('Ford');
3331 +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
3335 +select * from t1 where txt='Chevy' or txt='Chevy ';
3338 +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
3341 +select * from t1 where txt in ('Chevy ','Chevy');
3344 +select * from t1 where txt in ('Chevy');
3347 +select * from t1 where txt between 'Chevy' and 'Chevy';
3350 +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
3353 +select * from t1 where txt between 'Chevy' and 'Chevy ';
3356 +select * from t1 where txt < 'Chevy ';
3358 +select * from t1 where txt <= 'Chevy';
3361 +select * from t1 where txt > 'Chevy';
3364 +select * from t1 where txt >= 'Chevy';
3369 +create table t1 (id integer primary key auto_increment, txt text);
3370 +insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
3371 +select * from t1 where txt='Chevy' or txt is NULL;
3376 +explain select * from t1 where txt='Chevy' or txt is NULL;
3377 +id select_type table type possible_keys key key_len ref rows Extra
3378 +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
3379 +select * from t1 where txt='Chevy ';
3383 +select * from t1 where txt='Chevy ' or txt='Chevy';
3387 +select * from t1 where txt='Chevy' or txt='Chevy ';
3391 +select * from t1 where id='1' or id='2';
3395 +insert into t1 (txt) values('Ford');
3396 +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
3401 +select * from t1 where txt='Chevy' or txt='Chevy ';
3405 +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
3409 +select * from t1 where txt in ('Chevy ','Chevy');
3413 +select * from t1 where txt in ('Chevy');
3417 +select * from t1 where txt between 'Chevy' and 'Chevy';
3421 +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
3425 +select * from t1 where txt between 'Chevy' and 'Chevy ';
3429 +select * from t1 where txt < 'Chevy ';
3431 +select * from t1 where txt < 'Chevy ' or txt is NULL;
3434 +select * from t1 where txt <= 'Chevy';
3438 +select * from t1 where txt > 'Chevy';
3441 +select * from t1 where txt >= 'Chevy';
3446 +alter table t1 modify column txt blob;
3447 +explain select * from t1 where txt='Chevy' or txt is NULL;
3448 +id select_type table type possible_keys key key_len ref rows Extra
3449 +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
3450 +select * from t1 where txt='Chevy' or txt is NULL;
3454 +explain select * from t1 where txt='Chevy' or txt is NULL order by txt;
3455 +id select_type table type possible_keys key key_len ref rows Extra
3456 +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where; Using filesort
3457 +select * from t1 where txt='Chevy' or txt is NULL order by txt;
3462 +CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, d varchar(1) NOT NULL DEFAULT ' ', PRIMARY KEY (i));
3463 +INSERT t1 (i, c) VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
3464 +select max(i) from t1 where c = '';
3468 +CREATE table t1 (a blob);
3469 +insert into t1 values ('b'),('a\0'),('a'),('a '),('aa'),(NULL);
3470 +select hex(a) from t1 order by a;
3478 +select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0');
3486 +alter table t1 modify a varbinary(5);
3487 +select hex(a) from t1 order by a;
3495 +select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0');
3503 +alter table t1 modify a char(5);
3504 +select hex(a) from t1 order by a;
3512 +select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0');
3520 +alter table t1 modify a binary(5);
3521 +select hex(a) from t1 order by a;
3529 +select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0');
3538 +create table t1 (a text default '');
3540 +Warning 1101 BLOB/TEXT column 'a' can't have a default value
3541 +show create table t1;
3543 +t1 CREATE TABLE `t1` (
3545 +) ENGINE=MEMORY DEFAULT CHARSET=latin1
3546 +insert into t1 values (default);
3551 +set @@sql_mode='TRADITIONAL';
3552 +create table t1 (a text default '');
3553 +ERROR 42000: BLOB/TEXT column 'a' can't have a default value
3555 +CREATE TABLE t (c TEXT CHARSET ASCII);
3556 +INSERT INTO t (c) VALUES (REPEAT('1',65537));
3558 +Warning 1265 Data truncated for column 'c' at row 1
3559 +INSERT INTO t (c) VALUES (REPEAT('2',65536));
3561 +Warning 1265 Data truncated for column 'c' at row 1
3562 +INSERT INTO t (c) VALUES (REPEAT('3',65535));
3563 +SELECT LENGTH(c), CHAR_LENGTH(c) FROM t;
3564 +LENGTH(c) CHAR_LENGTH(c)
3569 +drop table if exists b15776;
3570 +create table b15776 (data blob(2147483647));
3572 +create table b15776 (data blob(-1));
3573 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1
3574 +create table b15776 (data blob(2147483648));
3576 +create table b15776 (data blob(4294967294));
3578 +create table b15776 (data blob(4294967295));
3580 +create table b15776 (data blob(4294967296));
3581 +ERROR 42000: Display width out of range for column 'data' (max = 4294967295)
3582 +CREATE TABLE b15776 (a blob(2147483647), b blob(2147483648), c blob(4294967295), a1 text(2147483647), b1 text(2147483648), c1 text(4294967295) );
3583 +show columns from b15776;
3584 +Field Type Null Key Default Extra
3585 +a longblob YES NULL
3586 +b longblob YES NULL
3587 +c longblob YES NULL
3588 +a1 longtext YES NULL
3589 +b1 longtext YES NULL
3590 +c1 longtext YES NULL
3592 +CREATE TABLE b15776 (a blob(4294967296));
3593 +ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
3594 +CREATE TABLE b15776 (a text(4294967296));
3595 +ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
3596 +CREATE TABLE b15776 (a blob(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
3597 +ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
3598 +CREATE TABLE b15776 (a text(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
3599 +ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
3600 +CREATE TABLE b15776 (a int(0));
3601 +INSERT INTO b15776 values (NULL), (1), (42), (654);
3602 +SELECT * from b15776 ORDER BY a;
3609 +CREATE TABLE b15776 (a int(-1));
3610 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1
3611 +CREATE TABLE b15776 (a int(255));
3613 +CREATE TABLE b15776 (a int(256));
3614 +ERROR 42000: Display width out of range for column 'a' (max = 255)
3615 +CREATE TABLE b15776 (data blob(-1));
3616 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1
3617 +CREATE TABLE b15776 (a char(2147483647));
3618 +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
3619 +CREATE TABLE b15776 (a char(2147483648));
3620 +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
3621 +CREATE TABLE b15776 (a char(4294967295));
3622 +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
3623 +CREATE TABLE b15776 (a char(4294967296));
3624 +ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
3625 +CREATE TABLE b15776 (a year(4294967295));
3626 +INSERT INTO b15776 VALUES (42);
3627 +SELECT * FROM b15776;
3631 +CREATE TABLE b15776 (a year(4294967296));
3632 +ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
3633 +CREATE TABLE b15776 (a year(0));
3635 +CREATE TABLE b15776 (a year(-2));
3636 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-2))' at line 1
3637 +CREATE TABLE b15776 (a int(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
3638 +ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
3639 +CREATE TABLE b15776 (a char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
3640 +ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
3641 +CREATE TABLE b15776 (a year(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
3642 +ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
3643 +CREATE TABLE b15776 select cast(null as char(4294967295));
3644 +show columns from b15776;
3645 +Field Type Null Key Default Extra
3646 +cast(null as char(4294967295)) char(0) YES NULL
3648 +CREATE TABLE b15776 select cast(null as nchar(4294967295));
3649 +show columns from b15776;
3650 +Field Type Null Key Default Extra
3651 +cast(null as nchar(4294967295)) char(0) YES NULL
3653 +CREATE TABLE b15776 select cast(null as binary(4294967295));
3654 +show columns from b15776;
3655 +Field Type Null Key Default Extra
3656 +cast(null as binary(4294967295)) binary(0) YES NULL
3658 +explain select cast(1 as char(4294967295));
3659 +id select_type table type possible_keys key key_len ref rows Extra
3660 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
3661 +explain select cast(1 as nchar(4294967295));
3662 +id select_type table type possible_keys key key_len ref rows Extra
3663 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
3664 +explain select cast(1 as binary(4294967295));
3665 +id select_type table type possible_keys key key_len ref rows Extra
3666 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
3667 +explain select cast(1 as char(4294967296));
3668 +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
3669 +explain select cast(1 as nchar(4294967296));
3670 +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
3671 +explain select cast(1 as binary(4294967296));
3672 +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
3673 +explain select cast(1 as decimal(-1));
3674 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1
3675 +explain select cast(1 as decimal(64, 30));
3676 +id select_type table type possible_keys key key_len ref rows Extra
3677 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
3678 +explain select cast(1 as decimal(64, 999999999999999999999999999999));
3679 +Got one of the listed errors
3680 +explain select cast(1 as decimal(4294967296));
3681 +Got one of the listed errors
3682 +explain select cast(1 as decimal(999999999999999999999999999999999999));
3683 +Got one of the listed errors
3684 +explain select convert(1, char(4294967295));
3685 +id select_type table type possible_keys key key_len ref rows Extra
3686 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
3687 +explain select convert(1, char(4294967296));
3688 +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
3689 +explain select convert(1, char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
3690 +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
3691 +explain select convert(1, nchar(4294967295));
3692 +id select_type table type possible_keys key key_len ref rows Extra
3693 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
3694 +explain select convert(1, nchar(4294967296));
3695 +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
3696 +explain select convert(1, nchar(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
3697 +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
3698 +explain select convert(1, binary(4294967295));
3699 +id select_type table type possible_keys key key_len ref rows Extra
3700 +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
3701 +explain select convert(1, binary(4294967296));
3702 +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
3703 +explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
3704 +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
3706 +CREATE TABLE t1(id INT NOT NULL);
3707 +CREATE TABLE t2(id INT NOT NULL, c TEXT NOT NULL);
3708 +INSERT INTO t1 VALUES (1);
3709 +INSERT INTO t2 VALUES (1, '');
3710 +UPDATE t2 SET c = REPEAT('1', 70000);
3712 +Warning 1265 Data truncated for column 'c' at row 1
3713 +SELECT LENGTH(c) FROM t2;
3716 +UPDATE t1 LEFT JOIN t2 USING(id) SET t2.c = REPEAT('1', 70000) WHERE t1.id = 1;
3718 +Warning 1265 Data truncated for column 'c' at row 1
3719 +SELECT LENGTH(c) FROM t2;
3723 +# Bug #52160: crash and inconsistent results when grouping
3724 +# by a function and column
3725 +CREATE FUNCTION f1() RETURNS TINYBLOB RETURN 1;
3726 +CREATE TABLE t1(a CHAR(1));
3727 +INSERT INTO t1 VALUES ('0'), ('0');
3728 +SELECT COUNT(*) FROM t1 GROUP BY f1(), a;
3733 +SET @old_max_heap_table_size = @@global.max_heap_table_size;
3734 +SET @old_max_allowed_packet = @@global.max_allowed_packet;
3735 +SET GLOBAL max_heap_table_size = 18 * 1024 * 1024;
3736 +SET GLOBAL max_allowed_packet = 24 * 1024 * 1024;
3737 +drop table if exists t1;
3738 +CREATE TABLE t1 (data LONGBLOB);
3739 +INSERT INTO t1 (data) VALUES (NULL);
3740 +UPDATE t1 set data=repeat('a',18*1024*1024);
3741 +select length(data) from t1;
3744 +delete from t1 where left(data,1)='a';
3746 +INSERT INTO t1 (data) VALUES (repeat('a',1*1024*1024));
3747 +INSERT INTO t1 (data) VALUES (repeat('b',16*1024*1024-1024));
3748 +delete from t1 where left(data,1)='b';
3749 +UPDATE t1 set data=repeat('c',17*1024*1024);
3750 +delete from t1 where left(data,1)='c';
3751 +INSERT INTO t1 set data=repeat('a',18*1024*1024);
3752 +select length(data) from t1;
3755 +alter table t1 modify data blob;
3756 +select length(data) from t1;
3760 +CREATE TABLE t1 (data BLOB);
3761 +INSERT INTO t1 (data) VALUES (NULL);
3762 +UPDATE t1 set data=repeat('a',18*1024*1024);
3764 +Warning 1265 Data truncated for column 'data' at row 1
3765 +select length(data) from t1;
3769 +SET GLOBAL max_allowed_packet = @old_max_allowed_packet;
3770 +SET GLOBAL max_heap_table_size = @old_max_heap_table_size;
3771 +SET default_storage_engine=@old_default_storage_engine;
3773 +++ b/mysql-test/r/percona_heap_bug783366.result
3775 +drop table if exists t1;
3777 +f1 VARCHAR ( 128 ) ,
3779 +PRIMARY KEY ( f2 ( 2 ) , f1 )
3781 +ENGINE=HEAP KEY_BLOCK_SIZE = 512;
3782 +INSERT IGNORE INTO t1 VALUES ( 'te' , 'm') , ( NULL , 'think' );
3784 +Warning 1048 Column 'f1' cannot be null
3785 +INSERT IGNORE INTO t1 VALUES ( 'te' , 'm') , ( NULL , 'think' );
3787 +Warning 1048 Column 'f1' cannot be null
3790 +++ b/mysql-test/r/percona_heap_bug783451.result
3792 +DROP TABLE IF EXISTS local_1_1;
3793 +CREATE TABLE IF NOT EXISTS local_1_1 ( f1 VARCHAR ( 32 ) NOT NULL , f2 VARCHAR ( 128 ) NOT NULL DEFAULT 'cboepfaobilcchabvglgjdbynog' , f3 VARCHAR ( 32 ) NOT NULL , f4 VARBINARY ( 32 ) NOT NULL , f5 VARBINARY ( 1024 ) DEFAULT 'ycboepfao' , KEY ( f1 /* ( 2 ) */ , f2 /* ( 2 ) */ ) ) ENGINE=HEAP KEY_BLOCK_SIZE = 512;
3794 +INSERT IGNORE INTO local_1_1 VALUES ( REPEAT( 'ervydbimvmbqmsowdbsa' , 1 ) , 'v' , NULL , NULL , REPEAT( 'mervydbimvmbqms' , 5 ) ) , ( 'p' , 6 , 'n' , REPEAT( 'imervydbimvmbqmsowdbs' , 4 ) , 'do' ) , ( NULL , NULL , REPEAT( 'himervydbimvmbqmsowdbsaybudvwaamvhempuublmia' , 6 ) , REPEAT('X', POW(2, 20) * 2) , REPEAT('X', POW(2, 20) * 2) ) , ( REPEAT('X', POW(2, 20) * 2) , REPEAT( 'Y' , 763 ) , NULL , REPEAT('X', POW(2, 20) * 2) , NULL ) , ( REPEAT('X', POW(2, 20) * 2) , 'time' , 'how' , 2 , REPEAT( 'Y' , 107 ) ) , ( REPEAT( 'hyshimervydbimvmbqmsowdbsaybud' , 5 ) , 2 , 8 , NULL , REPEAT('X', POW(2, 20) * 2) ) , ( 'come' , NULL , 'i' , NULL , REPEAT('X', POW(2, 20) * 2) );
3796 +Warning 1048 Column 'f3' cannot be null
3797 +Warning 1048 Column 'f4' cannot be null
3798 +Warning 1265 Data truncated for column 'f4' at row 2
3799 +Warning 1048 Column 'f1' cannot be null
3800 +Warning 1048 Column 'f2' cannot be null
3801 +Warning 1265 Data truncated for column 'f3' at row 3
3802 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3803 +Warning 1048 Column 'f4' cannot be null
3804 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3805 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3806 +Warning 1048 Column 'f1' cannot be null
3807 +Warning 1265 Data truncated for column 'f2' at row 4
3808 +Warning 1048 Column 'f3' cannot be null
3809 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3810 +Warning 1048 Column 'f4' cannot be null
3811 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3812 +Warning 1048 Column 'f1' cannot be null
3813 +Warning 1265 Data truncated for column 'f1' at row 6
3814 +Warning 1048 Column 'f4' cannot be null
3815 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3816 +Warning 1048 Column 'f2' cannot be null
3817 +Warning 1048 Column 'f4' cannot be null
3818 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3819 +INSERT IGNORE INTO local_1_1 VALUES ( 'ok' , NULL , REPEAT( 'Y' , 651 ) , 2 , 5 ) , ( REPEAT( 'zylcdzkfrqpihyshimervydbimvmbqmsowdbsaybu' , 3 ) , REPEAT( 'Y' , 282 ) , REPEAT( 'X' , 0 ) , REPEAT( 'Y' , 369 ) , 'g' ) , ( 'think' , REPEAT('X', POW(2, 20) * 2), NULL , NULL , REPEAT('X', POW(2, 20) * 2) ) , ( REPEAT( 'Y' , 468 ) , REPEAT( 'dfvbrzylcd' , 6 ) , REPEAT( 'Y' , 264 ) , NULL , 'c' ) , ( NULL , NULL , REPEAT( 'srdfvbrzylcdzkfrqpihyshimervydbimvmbqms' , 0 ) , REPEAT( 'Y' , 244 ) , 7 ) , ( REPEAT( 'Y' , 0 ) , 'how' , 'going' , 'q' , NULL );
3821 +Warning 1048 Column 'f2' cannot be null
3822 +Warning 1265 Data truncated for column 'f3' at row 1
3823 +Warning 1265 Data truncated for column 'f1' at row 2
3824 +Warning 1265 Data truncated for column 'f2' at row 2
3825 +Warning 1265 Data truncated for column 'f4' at row 2
3826 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3827 +Warning 1048 Column 'f2' cannot be null
3828 +Warning 1048 Column 'f3' cannot be null
3829 +Warning 1048 Column 'f4' cannot be null
3830 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3831 +Warning 1265 Data truncated for column 'f1' at row 4
3832 +Warning 1265 Data truncated for column 'f3' at row 4
3833 +Warning 1048 Column 'f4' cannot be null
3834 +Warning 1048 Column 'f1' cannot be null
3835 +Warning 1048 Column 'f2' cannot be null
3836 +Warning 1265 Data truncated for column 'f4' at row 5
3837 +INSERT IGNORE INTO local_1_1 VALUES ( REPEAT('X', POW(2, 20) * 2) , NULL , NULL , NULL , REPEAT('X', POW(2, 20) * 2) ) , ( REPEAT('X', POW(2, 20) * 2) , NULL , REPEAT('X', POW(2, 20) * 2) , 'this' , 'e' ) , ( NULL , 'think' , NULL , 'were' , NULL ) , ( 9 , 'l' , 'c' , 3 , REPEAT( 'geysrdfvbrzylcdzkfrqpihyshimervydbi' , 5 ) ) , ( NULL , NULL , NULL , 'h' , 'w' );
3839 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3840 +Warning 1048 Column 'f1' cannot be null
3841 +Warning 1048 Column 'f2' cannot be null
3842 +Warning 1048 Column 'f3' cannot be null
3843 +Warning 1048 Column 'f4' cannot be null
3844 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3845 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3846 +Warning 1048 Column 'f1' cannot be null
3847 +Warning 1048 Column 'f2' cannot be null
3848 +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
3849 +Warning 1048 Column 'f3' cannot be null
3850 +Warning 1048 Column 'f1' cannot be null
3851 +Warning 1048 Column 'f3' cannot be null
3852 +Warning 1048 Column 'f1' cannot be null
3853 +Warning 1048 Column 'f2' cannot be null
3854 +Warning 1048 Column 'f3' cannot be null
3855 +INSERT IGNORE INTO local_1_1 SELECT * FROM local_1_1;
3856 +INSERT IGNORE INTO local_1_1 SELECT * FROM local_1_1;
3857 +UPDATE local_1_1 SET f5 = REPEAT ('X', 215566);
3859 +Warning 1265 Data truncated for column 'f5' at row 1
3860 +Warning 1265 Data truncated for column 'f5' at row 2
3861 +Warning 1265 Data truncated for column 'f5' at row 3
3862 +Warning 1265 Data truncated for column 'f5' at row 4
3863 +Warning 1265 Data truncated for column 'f5' at row 5
3864 +Warning 1265 Data truncated for column 'f5' at row 6
3865 +Warning 1265 Data truncated for column 'f5' at row 7
3866 +Warning 1265 Data truncated for column 'f5' at row 8
3867 +Warning 1265 Data truncated for column 'f5' at row 9
3868 +Warning 1265 Data truncated for column 'f5' at row 10
3869 +Warning 1265 Data truncated for column 'f5' at row 11
3870 +Warning 1265 Data truncated for column 'f5' at row 12
3871 +Warning 1265 Data truncated for column 'f5' at row 13
3872 +Warning 1265 Data truncated for column 'f5' at row 14
3873 +Warning 1265 Data truncated for column 'f5' at row 15
3874 +Warning 1265 Data truncated for column 'f5' at row 16
3875 +Warning 1265 Data truncated for column 'f5' at row 17
3876 +Warning 1265 Data truncated for column 'f5' at row 18
3877 +Warning 1265 Data truncated for column 'f5' at row 19
3878 +Warning 1265 Data truncated for column 'f5' at row 20
3879 +Warning 1265 Data truncated for column 'f5' at row 21
3880 +Warning 1265 Data truncated for column 'f5' at row 22
3881 +Warning 1265 Data truncated for column 'f5' at row 23
3882 +Warning 1265 Data truncated for column 'f5' at row 24
3883 +Warning 1265 Data truncated for column 'f5' at row 25
3884 +Warning 1265 Data truncated for column 'f5' at row 26
3885 +Warning 1265 Data truncated for column 'f5' at row 27
3886 +Warning 1265 Data truncated for column 'f5' at row 28
3887 +Warning 1265 Data truncated for column 'f5' at row 29
3888 +Warning 1265 Data truncated for column 'f5' at row 30
3889 +Warning 1265 Data truncated for column 'f5' at row 31
3890 +Warning 1265 Data truncated for column 'f5' at row 32
3891 +Warning 1265 Data truncated for column 'f5' at row 33
3892 +Warning 1265 Data truncated for column 'f5' at row 34
3893 +Warning 1265 Data truncated for column 'f5' at row 35
3894 +Warning 1265 Data truncated for column 'f5' at row 36
3895 +Warning 1265 Data truncated for column 'f5' at row 37
3896 +Warning 1265 Data truncated for column 'f5' at row 38
3897 +Warning 1265 Data truncated for column 'f5' at row 39
3898 +Warning 1265 Data truncated for column 'f5' at row 40
3899 +Warning 1265 Data truncated for column 'f5' at row 41
3900 +Warning 1265 Data truncated for column 'f5' at row 42
3901 +Warning 1265 Data truncated for column 'f5' at row 43
3902 +Warning 1265 Data truncated for column 'f5' at row 44
3903 +Warning 1265 Data truncated for column 'f5' at row 45
3904 +Warning 1265 Data truncated for column 'f5' at row 46
3905 +Warning 1265 Data truncated for column 'f5' at row 47
3906 +Warning 1265 Data truncated for column 'f5' at row 48
3907 +Warning 1265 Data truncated for column 'f5' at row 49
3908 +Warning 1265 Data truncated for column 'f5' at row 50
3909 +Warning 1265 Data truncated for column 'f5' at row 51
3910 +Warning 1265 Data truncated for column 'f5' at row 52
3911 +Warning 1265 Data truncated for column 'f5' at row 53
3912 +Warning 1265 Data truncated for column 'f5' at row 54
3913 +Warning 1265 Data truncated for column 'f5' at row 55
3914 +Warning 1265 Data truncated for column 'f5' at row 56
3915 +Warning 1265 Data truncated for column 'f5' at row 57
3916 +Warning 1265 Data truncated for column 'f5' at row 58
3917 +Warning 1265 Data truncated for column 'f5' at row 59
3918 +Warning 1265 Data truncated for column 'f5' at row 60
3919 +Warning 1265 Data truncated for column 'f5' at row 61
3920 +Warning 1265 Data truncated for column 'f5' at row 62
3921 +Warning 1265 Data truncated for column 'f5' at row 63
3922 +Warning 1265 Data truncated for column 'f5' at row 64
3923 +DROP TABLE local_1_1;
3925 +++ b/mysql-test/r/percona_heap_bug784464.result
3927 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
3928 +PRIMARY KEY (f1)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3929 +SHOW TABLE STATUS LIKE 't1';
3930 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3931 +t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC
3933 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
3934 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=33 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3935 +ERROR 42000: Incorrect usage/placement of 'key_block_size'
3936 +SHOW TABLE STATUS LIKE 't1';
3937 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3938 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
3939 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=34 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3940 +SHOW TABLE STATUS LIKE 't1';
3941 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3942 +t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=34
3944 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
3945 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=123 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3946 +SHOW TABLE STATUS LIKE 't1';
3947 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3948 +t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=123
3950 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
3951 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=1000 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3952 +SHOW TABLE STATUS LIKE 't1';
3953 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3954 +t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=1000
3956 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
3957 +PRIMARY KEY (f1)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3958 +SHOW TABLE STATUS LIKE 't1';
3959 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3960 +t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC
3962 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
3963 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=33 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3964 +ERROR 42000: Incorrect usage/placement of 'key_block_size'
3965 +SHOW TABLE STATUS LIKE 't1';
3966 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3967 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
3968 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=34 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3969 +SHOW TABLE STATUS LIKE 't1';
3970 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3971 +t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=34
3973 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
3974 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=121 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3975 +SHOW TABLE STATUS LIKE 't1';
3976 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3977 +t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=121
3979 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
3980 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=1000 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3981 +SHOW TABLE STATUS LIKE 't1';
3982 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3983 +t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=1000
3986 +++ b/mysql-test/r/percona_heap_bug784464_32bit.result
3988 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
3989 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=124 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3990 +SHOW TABLE STATUS LIKE 't1';
3991 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3992 +t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=124
3994 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
3995 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=122 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
3996 +SHOW TABLE STATUS LIKE 't1';
3997 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
3998 +t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=122
4001 +++ b/mysql-test/r/percona_heap_bug784464_64bit.result
4003 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
4004 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=124 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
4005 +SHOW TABLE STATUS LIKE 't1';
4006 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
4007 +t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=124
4009 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
4010 +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=122 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
4011 +SHOW TABLE STATUS LIKE 't1';
4012 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
4013 +t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=122
4016 +++ b/mysql-test/r/percona_heap_bug784468.result
4018 +CREATE TABLE t1 ( f1 VARCHAR(30)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
4019 +SHOW TABLE STATUS LIKE 't1';
4020 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
4021 +t1 MEMORY 10 Fixed 0 32 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC
4023 +CREATE TABLE t1 ( f1 VARCHAR(31)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
4024 +SHOW TABLE STATUS LIKE 't1';
4025 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
4026 +t1 MEMORY 10 Fixed 0 33 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC
4028 +CREATE TABLE t1 ( f1 VARCHAR(32)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
4029 +SHOW TABLE STATUS LIKE 't1';
4030 +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
4031 +t1 MEMORY 10 Fixed 0 34 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC
4034 +++ b/mysql-test/r/percona_heap_bug788544.result
4036 +CREATE TABLE t1 (f2 VARCHAR (32), f4 LONGBLOB, f5 TEXT) ENGINE=HEAP;
4037 +INSERT INTO t1 VALUES ('a', NULL, NULL),
4038 +('b' , REPEAT('a' , 593338), REPEAT('a', 800));
4039 +UPDATE t1 SET f2 = 'c' WHERE f4 = 'd';
4040 +SELECT LENGTH(f2), LENGTH(f4), LENGTH(f5) FROM t1;
4041 +LENGTH(f2) LENGTH(f4) LENGTH(f5)
4046 +++ b/mysql-test/r/percona_heap_bug788576.result
4048 +CREATE TABLE t1 (f1 VARCHAR (32), f2 VARCHAR (128), f3 VARBINARY (128),
4049 +f4 VARBINARY (512), f5 VARBINARY (1024),
4050 +KEY (f2(1))) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
4051 +INSERT IGNORE INTO t1 VALUES (2, NULL, 6, REPEAT('glugcgqk', 5), 'look'),
4052 +(REPEAT( 'kglugcgqkin', 6), 'if', 'was', NULL, NULL),
4053 +(NULL, NULL, NULL, NULL, 7);
4055 +Warning 1265 Data truncated for column 'f1' at row 2
4058 +2 NULL 6 glugcgqkglugcgqkglugcgqkglugcgqkglugcgqk look
4059 +kglugcgqkinkglugcgqkinkglugcgqki if was NULL NULL
4060 +NULL NULL NULL NULL 7
4061 +DELETE FROM t1 WHERE f5 <=> NULL;
4064 +2 NULL 6 glugcgqkglugcgqkglugcgqkglugcgqkglugcgqk look
4065 +NULL NULL NULL NULL 7
4068 +++ b/mysql-test/r/percona_heap_bug788722.result
4070 +CREATE TABLE IF NOT EXISTS local_1_1 (f1 VARCHAR (32) NOT NULL,
4071 +f2 VARCHAR (128) NOT NULL,
4077 +) ENGINE=HEAP ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE = 2048;
4078 +INSERT IGNORE INTO local_1_1 VALUES
4079 +(REPEAT('egqeqfxwaejpqixuvvtentruyqadxiybjdfqjspfbyjdjczrrwjnagkzsoagatqookhsgtrvvbxacppljfzaseidqggxvuirm' , 5), NULL, NULL, NULL, REPEAT('hegqeqfxwaejpqixuvvtentruyqadxiy', 1)),
4080 +('you', NULL, 0, REPEAT("X", 2048) , 0);
4082 +Warning 1265 Data truncated for column 'f1' at row 1
4083 +Warning 1048 Column 'f2' cannot be null
4084 +Warning 1048 Column 'f3' cannot be null
4085 +Warning 1048 Column 'f2' cannot be null
4086 +INSERT IGNORE INTO local_1_1 SELECT * FROM local_1_1;
4087 +DROP TABLE local_1_1;
4089 +++ b/mysql-test/r/percona_heap_bug789131.result
4091 +CREATE TABLE t1 (f1 VARCHAR (128), f2 VARCHAR (128), f3 VARBINARY (512),
4092 +f4 TEXT (65525), f5 VARCHAR (128), KEY (f1(1))) ENGINE=HEAP;
4093 +INSERT IGNORE INTO t1 VALUES
4094 +( 'o' , "" , NULL , "" , 0 ) ,
4095 +(NULL, "" , "" , "" , 'f' ) ;
4096 +INSERT IGNORE INTO t1 SELECT * FROM t1;
4099 +++ b/mysql-test/r/percona_heap_var.result
4101 +drop table if exists t1;
4102 +set @@session.max_heap_table_size=16*1024*1024;
4103 +create table t1 (a int not null, b varchar(400), c int, primary key (a), key (c)) engine=heap comment="testing heaps" key_block_size=128;
4104 +ERROR 42000: Incorrect usage/placement of 'key_block_size'
4105 +create table t1 (a int not null, b int, c varchar(400), primary key (a), key (b)) engine=heap comment="testing heaps" key_block_size=4;
4106 +ERROR 42000: Incorrect usage/placement of 'key_block_size'
4107 +create table t1 (a int not null, b int, c varchar(400), d varchar(400), primary key (a), key (b)) engine=heap comment="testing heaps" key_block_size=24;
4108 +show table status like "t1";
4123 +Collation latin1_swedish_ci
4125 +Create_options KEY_BLOCK_SIZE=24
4126 +Comment testing heaps
4127 +insert into t1 values (1,1,'012',NULL), (2,2,'0123456789',NULL), (3,3,'012345678901234567890123456789',NULL), (4,4,NULL,'0123456789012345678901234567890123456789012345678901234567890123456789');
4131 +2 2 0123456789 NULL
4132 +3 3 012345678901234567890123456789 NULL
4133 +4 4 NULL 0123456789012345678901234567890123456789012345678901234567890123456789
4134 +delete from t1 where a = 3;
4138 +2 2 0123456789 NULL
4139 +4 4 NULL 0123456789012345678901234567890123456789012345678901234567890123456789
4140 +insert into t1 values (5,5,NULL,'0123'), (6,6,NULL,'0123');
4144 +2 2 0123456789 NULL
4147 +4 4 NULL 0123456789012345678901234567890123456789012345678901234567890123456789
4148 +update t1 set c = '012345678901234567890123456789' where a = 2;
4152 +2 2 012345678901234567890123456789 NULL
4155 +4 4 NULL 0123456789012345678901234567890123456789012345678901234567890123456789
4156 +update t1 set c = '0123456789' where a = 2;
4160 +2 2 0123456789 NULL
4163 +4 4 NULL 0123456789012345678901234567890123456789012345678901234567890123456789
4164 +insert into t1 values (7,7,'0123',NULL), (8,8,'0123',NULL);
4168 +2 2 0123456789 NULL
4171 +4 4 NULL 0123456789012345678901234567890123456789012345678901234567890123456789
4174 +show table status like "t1";
4189 +Collation latin1_swedish_ci
4191 +Create_options KEY_BLOCK_SIZE=24
4192 +Comment testing heaps
4193 +alter table t1 key_block_size = 0;
4194 +show table status like "t1";
4209 +Collation latin1_swedish_ci
4212 +Comment testing heaps
4213 +alter table t1 row_format = dynamic;
4214 +show table status like "t1";
4229 +Collation latin1_swedish_ci
4231 +Create_options row_format=DYNAMIC KEY_BLOCK_SIZE=X
4232 +Comment testing heaps
4233 +alter table t1 key_block_size = 128, max_rows = 10001;
4234 +show table status like "t1";
4249 +Collation latin1_swedish_ci
4251 +Create_options max_rows=10001 row_format=DYNAMIC KEY_BLOCK_SIZE=128
4252 +Comment testing heaps
4256 +2 2 0123456789 NULL
4259 +4 4 NULL 0123456789012345678901234567890123456789012345678901234567890123456789
4265 +call mtr.add_suppression("The table 't1' is full");
4266 +select count(*) from t1;
4269 +insert into t1 values (100000,100000,NULL,'0123'), (100000,100000,NULL,'0123');
4270 +ERROR HY000: The table 't1' is full
4271 +show table status like "t1";
4286 +Collation latin1_swedish_ci
4288 +Create_options max_rows=10001 row_format=DYNAMIC KEY_BLOCK_SIZE=128
4289 +Comment testing heaps
4290 +select count(*) from t1;
4293 +set @@session.max_heap_table_size=default;
4296 +++ b/mysql-test/t/percona_heap_blob.test
4298 +########################################################################
4299 +# Test blobs with the HEAP/MEMORY storage engine
4300 +########################################################################
4302 +########################################################################
4303 +# Modified tests from type_blob.test
4304 +########################################################################
4306 +SET @old_default_storage_engine=@@default_storage_engine;
4307 +SET default_storage_engine=MEMORY;
4313 +drop table if exists t1,t2,t3,t4,t5,t6,t7;
4318 +# Check syntax for creating BLOB/TEXT
4321 +CREATE TABLE t1 (a blob, b text, c blob(250), d text(70000), e text(70000000));
4322 +show columns from t1;
4323 +# PS doesn't give errors on prepare yet
4324 +CREATE TABLE t2 (a char(255), b varbinary(70000), c varchar(70000000));
4325 +CREATE TABLE t4 (c varchar(65530) character set utf8 not null);
4326 +show columns from t2;
4327 +create table t3 (a long, b long byte);
4328 +show create TABLE t3;
4329 +show create TABLE t4;
4330 +drop table t1,t2,t3,t4;
4333 +# Check errors with blob
4337 +CREATE TABLE t1 (a char(257) default "hello");
4339 +CREATE TABLE t2 (a char(256));
4341 +CREATE TABLE t1 (a varchar(70000) default "hello");
4343 +CREATE TABLE t2 (a blob default "hello");
4345 +# Safety to be able to continue with other tests if above fails
4347 +drop table if exists t1,t2;
4351 +# test of full join with blob
4354 +create table t1 (nr int(5) not null auto_increment,b blob,str char(10), primary key (nr));
4355 +insert into t1 values (null,"a","A");
4356 +insert into t1 values (null,"bbb","BBB");
4357 +insert into t1 values (null,"ccc","CCC");
4358 +select last_insert_id();
4359 +select * from t1,t1 as t2;
4364 +# Test of changing TEXT column
4367 +create table t1 (a text);
4368 +insert into t1 values ('where');
4369 +update t1 set a='Where';
4374 +# test of blob, text, char and varbinary
4376 +create table t1 (t text,c char(10),b blob, d varbinary(10)) collate latin1_general_cs;
4377 +insert into t1 values (NULL,NULL,NULL,NULL);
4378 +insert into t1 values ("","","","");
4379 +insert into t1 values ("hello","hello","hello","hello");
4380 +insert into t1 values ("HELLO","HELLO","HELLO","HELLO");
4381 +insert into t1 values ("HELLO MY","HELLO MY","HELLO MY","HELLO MY");
4382 +insert into t1 values ("a","a","a","a");
4383 +insert into t1 values (1,1,1,1);
4384 +insert into t1 values (NULL,NULL,NULL,NULL);
4385 +update t1 set c="",b=null where c="1";
4387 +lock tables t1 READ;
4388 +# We mask out the Privileges column because it differs for embedded server
4389 +--replace_column 8 #
4390 +show full fields from t1;
4391 +lock tables t1 WRITE;
4392 +--replace_column 8 #
4393 +show full fields from t1;
4396 +select t from t1 where t like "hello";
4397 +select c from t1 where c like "hello";
4398 +select b from t1 where b like "hello";
4399 +select d from t1 where d like "hello";
4400 +select c from t1 having c like "hello";
4401 +select d from t1 having d like "hello";
4402 +select t from t1 where t like "%HELLO%";
4403 +select c from t1 where c like "%HELLO%";
4404 +select b from t1 where b like "%HELLO%";
4405 +select d from t1 where d like "%HELLO%";
4406 +select c from t1 having c like "%HELLO%";
4407 +select d from t1 having d like "%HELLO%";
4408 +select d from t1 having d like "%HE%LLO%";
4409 +select t from t1 order by t;
4410 +select c from t1 order by c;
4411 +select b from t1 order by b;
4412 +select d from t1 order by d;
4413 +select distinct t from t1;
4414 +select distinct b from t1;
4415 +select distinct t from t1 order by t;
4416 +select distinct b from t1 order by b;
4417 +select t from t1 group by t;
4418 +select b from t1 group by b;
4419 +set option sql_big_tables=1;
4420 +select distinct t from t1;
4421 +select distinct b from t1;
4422 +select distinct t from t1 order by t;
4423 +select distinct b from t1 order by b;
4424 +select distinct c from t1;
4425 +select distinct d from t1;
4426 +select distinct c from t1 order by c;
4427 +select distinct d from t1 order by d;
4428 +select c from t1 group by c;
4429 +select d from t1 group by d;
4430 +set option sql_big_tables=0;
4431 +select distinct * from t1;
4432 +select t,count(*) from t1 group by t;
4433 +select b,count(*) from t1 group by b;
4434 +select c,count(*) from t1 group by c;
4435 +select d,count(*) from t1 group by d;
4440 +# Test of join with blobs and min
4444 + t1_id bigint(21) NOT NULL auto_increment,
4445 + _field_72 varchar(128) DEFAULT '' NOT NULL,
4446 + _field_95 varchar(32),
4447 + _field_115 tinyint(4) DEFAULT '0' NOT NULL,
4448 + _field_122 tinyint(4) DEFAULT '0' NOT NULL,
4449 + _field_126 tinyint(4),
4450 + _field_134 tinyint(4),
4451 + PRIMARY KEY (t1_id),
4452 + UNIQUE _field_72 (_field_72),
4453 + KEY _field_115 (_field_115),
4454 + KEY _field_122 (_field_122)
4458 +INSERT INTO t1 VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',0,1,NULL,NULL);
4459 +INSERT INTO t1 VALUES (2,'hroberts','7415275a8c95952901e42b13a6b78566',0,1,NULL,NULL);
4460 +INSERT INTO t1 VALUES (3,'guest','d41d8cd98f00b204e9800998ecf8427e',1,0,NULL,NULL);
4464 + seq_0_id bigint(21) DEFAULT '0' NOT NULL,
4465 + seq_1_id bigint(21) DEFAULT '0' NOT NULL,
4466 + PRIMARY KEY (seq_0_id,seq_1_id)
4470 +INSERT INTO t2 VALUES (1,1);
4471 +INSERT INTO t2 VALUES (2,1);
4472 +INSERT INTO t2 VALUES (2,2);
4475 + t3_id bigint(21) NOT NULL auto_increment,
4476 + _field_131 varchar(128),
4477 + _field_133 tinyint(4) DEFAULT '0' NOT NULL,
4478 + _field_135 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
4479 + _field_137 tinyint(4),
4480 + _field_139 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
4482 + _field_142 tinyint(4) DEFAULT '0' NOT NULL,
4483 + _field_145 tinyint(4) DEFAULT '0' NOT NULL,
4484 + _field_148 tinyint(4) DEFAULT '0' NOT NULL,
4485 + PRIMARY KEY (t3_id),
4486 + KEY _field_133 (_field_133),
4487 + KEY _field_135 (_field_135),
4488 + KEY _field_139 (_field_139),
4489 + KEY _field_142 (_field_142),
4490 + KEY _field_145 (_field_145),
4491 + KEY _field_148 (_field_148)
4495 +INSERT INTO t3 VALUES (1,'test job 1',0,'0000-00-00 00:00:00',0,'1999-02-25 22:43:32','test\r\njob\r\n1',0,0,0);
4496 +INSERT INTO t3 VALUES (2,'test job 2',0,'0000-00-00 00:00:00',0,'1999-02-26 21:08:04','',0,0,0);
4500 + seq_0_id bigint(21) DEFAULT '0' NOT NULL,
4501 + seq_1_id bigint(21) DEFAULT '0' NOT NULL,
4502 + PRIMARY KEY (seq_0_id,seq_1_id)
4506 +INSERT INTO t4 VALUES (1,1);
4507 +INSERT INTO t4 VALUES (2,1);
4510 + t5_id bigint(21) NOT NULL auto_increment,
4511 + _field_149 tinyint(4),
4512 + _field_156 varchar(128) DEFAULT '' NOT NULL,
4513 + _field_157 varchar(128) DEFAULT '' NOT NULL,
4514 + _field_158 varchar(128) DEFAULT '' NOT NULL,
4515 + _field_159 varchar(128) DEFAULT '' NOT NULL,
4516 + _field_160 varchar(128) DEFAULT '' NOT NULL,
4517 + _field_161 varchar(128) DEFAULT '' NOT NULL,
4518 + PRIMARY KEY (t5_id),
4519 + KEY _field_156 (_field_156),
4520 + KEY _field_157 (_field_157),
4521 + KEY _field_158 (_field_158),
4522 + KEY _field_159 (_field_159),
4523 + KEY _field_160 (_field_160),
4524 + KEY _field_161 (_field_161)
4528 +INSERT INTO t5 VALUES (1,0,'tomato','','','','','');
4529 +INSERT INTO t5 VALUES (2,0,'cilantro','','','','','');
4532 + seq_0_id bigint(21) DEFAULT '0' NOT NULL,
4533 + seq_1_id bigint(21) DEFAULT '0' NOT NULL,
4534 + PRIMARY KEY (seq_0_id,seq_1_id)
4537 +INSERT INTO t6 VALUES (1,1);
4538 +INSERT INTO t6 VALUES (1,2);
4539 +INSERT INTO t6 VALUES (2,2);
4542 + t7_id bigint(21) NOT NULL auto_increment,
4543 + _field_143 tinyint(4),
4544 + _field_165 varchar(32),
4545 + _field_166 smallint(6) DEFAULT '0' NOT NULL,
4546 + PRIMARY KEY (t7_id),
4547 + KEY _field_166 (_field_166)
4551 +INSERT INTO t7 VALUES (1,0,'High',1);
4552 +INSERT INTO t7 VALUES (2,0,'Medium',2);
4553 +INSERT INTO t7 VALUES (3,0,'Low',3);
4555 +select replace(t3._field_140, "\r","^M"),t3_id,min(t3._field_131), min(t3._field_135), min(t3._field_139), min(t3._field_137), min(link_alias_142._field_165), min(link_alias_133._field_72), min(t3._field_145), min(link_alias_148._field_156), replace(min(t3._field_140), "\r","^M"),t3.t3_id from t3 left join t4 on t4.seq_0_id = t3.t3_id left join t7 link_alias_142 on t4.seq_1_id = link_alias_142.t7_id left join t6 on t6.seq_0_id = t3.t3_id left join t1 link_alias_133 on t6.seq_1_id = link_alias_133.t1_id left join t2 on t2.seq_0_id = t3.t3_id left join t5 link_alias_148 on t2.seq_1_id = link_alias_148.t5_id where t3.t3_id in (1) group by t3.t3_id order by link_alias_142._field_166, _field_139, link_alias_133._field_72, _field_135, link_alias_148._field_156;
4557 +drop table t1,t2,t3,t4,t5,t6,t7;
4560 +# Test of reverse with empty blob
4563 +create table t1 (a blob);
4564 +insert into t1 values ("empty"),("");
4565 +select a,reverse(a) from t1;
4569 +# Bug when blob is updated
4572 +create table t1 (id integer auto_increment unique,imagem LONGBLOB not null default '');
4573 +insert into t1 (id) values (1);
4574 +# We have to clean up the path in the results for safe comparison
4576 + charset(load_file('../../std_data/words.dat')),
4577 + collation(load_file('../../std_data/words.dat')),
4578 + coercibility(load_file('../../std_data/words.dat'));
4579 +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
4580 +eval explain extended select
4581 + charset(load_file('$MYSQLTEST_VARDIR/std_data/words.dat')),
4582 + collation(load_file('$MYSQLTEST_VARDIR/std_data/words.dat')),
4583 + coercibility(load_file('$MYSQLTEST_VARDIR/std_data/words.dat'));
4584 +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
4585 +eval update t1 set imagem=load_file('$MYSQLTEST_VARDIR/std_data/words.dat') where id=1;
4586 +select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1;
4588 +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
4589 +eval create table t1 select load_file('$MYSQLTEST_VARDIR/std_data/words.dat') l;
4590 +# We mask out the Privileges column because it differs for embedded server
4591 +--replace_column 8 #
4592 +show full fields from t1;
4596 +# Test blob's with end space (Bug #1651)
4597 +# This is a bit changed since we now have true varchar
4600 +create table t1 (id integer primary key auto_increment, txt text not null);
4601 +insert into t1 (txt) values ('Chevy ');
4602 +select * from t1 where txt='Chevy';
4603 +select * from t1 where txt='Chevy ';
4604 +select * from t1 where txt='Chevy ' or txt='Chevy';
4605 +select * from t1 where txt='Chevy' or txt='Chevy ';
4606 +select * from t1 where id='1' or id='2';
4607 +insert into t1 (txt) values('Ford');
4608 +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
4609 +select * from t1 where txt='Chevy' or txt='Chevy ';
4610 +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
4611 +select * from t1 where txt in ('Chevy ','Chevy');
4612 +select * from t1 where txt in ('Chevy');
4613 +select * from t1 where txt between 'Chevy' and 'Chevy';
4614 +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
4615 +select * from t1 where txt between 'Chevy' and 'Chevy ';
4616 +select * from t1 where txt < 'Chevy ';
4617 +select * from t1 where txt <= 'Chevy';
4618 +select * from t1 where txt > 'Chevy';
4619 +select * from t1 where txt >= 'Chevy';
4622 +create table t1 (id integer primary key auto_increment, txt text);
4623 +insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
4624 +select * from t1 where txt='Chevy' or txt is NULL;
4625 +explain select * from t1 where txt='Chevy' or txt is NULL;
4626 +select * from t1 where txt='Chevy ';
4627 +select * from t1 where txt='Chevy ' or txt='Chevy';
4628 +select * from t1 where txt='Chevy' or txt='Chevy ';
4629 +select * from t1 where id='1' or id='2';
4630 +insert into t1 (txt) values('Ford');
4631 +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
4632 +select * from t1 where txt='Chevy' or txt='Chevy ';
4633 +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
4634 +select * from t1 where txt in ('Chevy ','Chevy');
4635 +select * from t1 where txt in ('Chevy');
4636 +select * from t1 where txt between 'Chevy' and 'Chevy';
4637 +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
4638 +select * from t1 where txt between 'Chevy' and 'Chevy ';
4639 +select * from t1 where txt < 'Chevy ';
4640 +select * from t1 where txt < 'Chevy ' or txt is NULL;
4641 +select * from t1 where txt <= 'Chevy';
4642 +select * from t1 where txt > 'Chevy';
4643 +select * from t1 where txt >= 'Chevy';
4644 +alter table t1 modify column txt blob;
4645 +explain select * from t1 where txt='Chevy' or txt is NULL;
4646 +select * from t1 where txt='Chevy' or txt is NULL;
4647 +explain select * from t1 where txt='Chevy' or txt is NULL order by txt;
4648 +select * from t1 where txt='Chevy' or txt is NULL order by txt;
4651 +CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, d varchar(1) NOT NULL DEFAULT ' ', PRIMARY KEY (i));
4652 +INSERT t1 (i, c) VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
4653 +select max(i) from t1 where c = '';
4659 +# Test that blob's and varbinary are sorted according to length
4662 +CREATE table t1 (a blob);
4663 +insert into t1 values ('b'),('a\0'),('a'),('a '),('aa'),(NULL);
4664 +select hex(a) from t1 order by a;
4665 +select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0');
4666 +alter table t1 modify a varbinary(5);
4667 +select hex(a) from t1 order by a;
4668 +select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0');
4669 +alter table t1 modify a char(5);
4670 +select hex(a) from t1 order by a;
4671 +select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0');
4672 +alter table t1 modify a binary(5);
4673 +select hex(a) from t1 order by a;
4674 +select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0');
4678 +# Bug #19489: Inconsistent support for DEFAULT in TEXT columns
4680 +create table t1 (a text default '');
4681 +show create table t1;
4682 +insert into t1 values (default);
4685 +set @@sql_mode='TRADITIONAL';
4686 +--error ER_BLOB_CANT_HAVE_DEFAULT
4687 +create table t1 (a text default '');
4691 +# Bug #32282: TEXT silently truncates when value is exactly 65536 bytes
4694 +CREATE TABLE t (c TEXT CHARSET ASCII);
4695 +INSERT INTO t (c) VALUES (REPEAT('1',65537));
4696 +INSERT INTO t (c) VALUES (REPEAT('2',65536));
4697 +INSERT INTO t (c) VALUES (REPEAT('3',65535));
4698 +SELECT LENGTH(c), CHAR_LENGTH(c) FROM t;
4700 +# Bug#15776: 32-bit signed int used for length of blob
4701 +# """LONGBLOB: A BLOB column with a maximum length of 4,294,967,295 or 4GB."""
4703 +# Conditions should be in this order:
4704 +# A size is not in the allowed bounds.
4705 +# If the type is char-ish AND size is within the max blob size:
4706 +# raise ER_TOO_BIG_FIELDLENGTH (suggest using BLOB)
4707 +# If size is too small:
4708 +# raise ER_PARSE_ERROR
4709 +# raise ER_TOO_BIG_DISPLAYWIDTH
4711 +# BLOB and TEXT types
4713 +drop table if exists b15776;
4715 +create table b15776 (data blob(2147483647));
4717 +--error ER_PARSE_ERROR
4718 +create table b15776 (data blob(-1));
4719 +create table b15776 (data blob(2147483648));
4721 +create table b15776 (data blob(4294967294));
4723 +create table b15776 (data blob(4294967295));
4725 +--error ER_TOO_BIG_DISPLAYWIDTH
4726 +create table b15776 (data blob(4294967296));
4728 +CREATE TABLE b15776 (a blob(2147483647), b blob(2147483648), c blob(4294967295), a1 text(2147483647), b1 text(2147483648), c1 text(4294967295) );
4729 +show columns from b15776;
4732 +--error ER_TOO_BIG_DISPLAYWIDTH
4733 +CREATE TABLE b15776 (a blob(4294967296));
4734 +--error ER_TOO_BIG_DISPLAYWIDTH
4735 +CREATE TABLE b15776 (a text(4294967296));
4736 +--error ER_TOO_BIG_DISPLAYWIDTH
4737 +CREATE TABLE b15776 (a blob(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
4738 +--error ER_TOO_BIG_DISPLAYWIDTH
4739 +CREATE TABLE b15776 (a text(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
4742 +# "Another extension is supported by MySQL for optionally specifying the
4743 +# display width of integer data types in parentheses following the base keyword
4744 +# for the type (for example, INT(4)). This optional display width is used to
4745 +# display integer values having a width less than the width specified for the
4746 +# column by left-padding them with spaces." § Numeric Types
4747 +CREATE TABLE b15776 (a int(0)); # 0 is special case, means default size
4748 +INSERT INTO b15776 values (NULL), (1), (42), (654);
4749 +SELECT * from b15776 ORDER BY a;
4751 +--error ER_PARSE_ERROR
4752 +CREATE TABLE b15776 (a int(-1));
4753 +CREATE TABLE b15776 (a int(255));
4755 +--error ER_TOO_BIG_DISPLAYWIDTH
4756 +CREATE TABLE b15776 (a int(256));
4757 +--error ER_PARSE_ERROR
4758 +CREATE TABLE b15776 (data blob(-1));
4762 +--error ER_TOO_BIG_FIELDLENGTH
4763 +CREATE TABLE b15776 (a char(2147483647));
4764 +--error ER_TOO_BIG_FIELDLENGTH
4765 +CREATE TABLE b15776 (a char(2147483648));
4766 +--error ER_TOO_BIG_FIELDLENGTH
4767 +CREATE TABLE b15776 (a char(4294967295));
4768 +# Even BLOB won't hold
4769 +--error ER_TOO_BIG_DISPLAYWIDTH
4770 +CREATE TABLE b15776 (a char(4294967296));
4773 +# Other numeric-ish types
4774 +## For year, widths not "2" or "4" are silently rewritten to "4". But
4775 +## When we complain about it, we say that the max is 255. We may be
4776 +## talking about different things. It's confusing.
4777 +CREATE TABLE b15776 (a year(4294967295));
4778 +INSERT INTO b15776 VALUES (42);
4779 +SELECT * FROM b15776;
4781 +--error ER_TOO_BIG_DISPLAYWIDTH
4782 +CREATE TABLE b15776 (a year(4294967296));
4783 +CREATE TABLE b15776 (a year(0)); # 0 is special case, means default size
4785 +--error ER_PARSE_ERROR
4786 +CREATE TABLE b15776 (a year(-2));
4789 +# We've already tested the case, but this should visually show that
4790 +# widths that are too large to be interpreted cause DISPLAYWIDTH errors.
4791 +--error ER_TOO_BIG_DISPLAYWIDTH
4792 +CREATE TABLE b15776 (a int(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
4793 +--error ER_TOO_BIG_DISPLAYWIDTH
4794 +CREATE TABLE b15776 (a char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
4795 +--error ER_TOO_BIG_DISPLAYWIDTH
4796 +CREATE TABLE b15776 (a year(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
4798 +## Do not select, too much memory needed.
4799 +CREATE TABLE b15776 select cast(null as char(4294967295));
4800 +show columns from b15776;
4802 +CREATE TABLE b15776 select cast(null as nchar(4294967295));
4803 +show columns from b15776;
4805 +CREATE TABLE b15776 select cast(null as binary(4294967295));
4806 +show columns from b15776;
4809 +explain select cast(1 as char(4294967295));
4810 +explain select cast(1 as nchar(4294967295));
4811 +explain select cast(1 as binary(4294967295));
4813 +--error ER_TOO_BIG_DISPLAYWIDTH
4814 +explain select cast(1 as char(4294967296));
4815 +--error ER_TOO_BIG_DISPLAYWIDTH
4816 +explain select cast(1 as nchar(4294967296));
4817 +--error ER_TOO_BIG_DISPLAYWIDTH
4818 +explain select cast(1 as binary(4294967296));
4820 +--error ER_PARSE_ERROR
4821 +explain select cast(1 as decimal(-1));
4822 +explain select cast(1 as decimal(64, 30));
4823 +# It's not as important which errors are raised for these, since the
4824 +# limit is nowhere near 2**32. We may fix these eventually to take
4825 +# 4294967295 and still reject it because it's greater than 64 or 30,
4826 +# but that's not a high priority and the parser needn't worry about
4827 +# such a weird case.
4828 +--error ER_TOO_BIG_SCALE,ER_PARSE_ERROR
4829 +explain select cast(1 as decimal(64, 999999999999999999999999999999));
4830 +--error ER_TOO_BIG_PRECISION,ER_PARSE_ERROR
4831 +explain select cast(1 as decimal(4294967296));
4832 +--error ER_TOO_BIG_PRECISION,ER_PARSE_ERROR
4833 +explain select cast(1 as decimal(999999999999999999999999999999999999));
4835 +explain select convert(1, char(4294967295));
4836 +--error ER_TOO_BIG_DISPLAYWIDTH
4837 +explain select convert(1, char(4294967296));
4838 +--error ER_TOO_BIG_DISPLAYWIDTH
4839 +explain select convert(1, char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
4840 +explain select convert(1, nchar(4294967295));
4841 +--error ER_TOO_BIG_DISPLAYWIDTH
4842 +explain select convert(1, nchar(4294967296));
4843 +--error ER_TOO_BIG_DISPLAYWIDTH
4844 +explain select convert(1, nchar(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
4845 +explain select convert(1, binary(4294967295));
4846 +--error ER_TOO_BIG_DISPLAYWIDTH
4847 +explain select convert(1, binary(4294967296));
4848 +--error ER_TOO_BIG_DISPLAYWIDTH
4849 +explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
4851 +--echo End of 5.0 tests
4854 +# Bug #33969: Updating a text field via a left join
4857 +CREATE TABLE t1(id INT NOT NULL);
4858 +CREATE TABLE t2(id INT NOT NULL, c TEXT NOT NULL);
4860 +INSERT INTO t1 VALUES (1);
4861 +INSERT INTO t2 VALUES (1, '');
4863 +UPDATE t2 SET c = REPEAT('1', 70000);
4864 +SELECT LENGTH(c) FROM t2;
4866 +UPDATE t1 LEFT JOIN t2 USING(id) SET t2.c = REPEAT('1', 70000) WHERE t1.id = 1;
4867 +SELECT LENGTH(c) FROM t2;
4871 +--echo # Bug #52160: crash and inconsistent results when grouping
4872 +--echo # by a function and column
4874 +CREATE FUNCTION f1() RETURNS TINYBLOB RETURN 1;
4876 +CREATE TABLE t1(a CHAR(1));
4877 +INSERT INTO t1 VALUES ('0'), ('0');
4879 +SELECT COUNT(*) FROM t1 GROUP BY f1(), a;
4888 +########################################################################
4889 +# Modified test from myisam-blob.test
4890 +########################################################################
4892 +SET @old_max_heap_table_size = @@global.max_heap_table_size;
4893 +SET @old_max_allowed_packet = @@global.max_allowed_packet;
4894 +SET GLOBAL max_heap_table_size = 18 * 1024 * 1024;
4895 +SET GLOBAL max_allowed_packet = 24 * 1024 * 1024;
4897 +connect(con1, localhost, root,,);
4901 +drop table if exists t1;
4904 +# Bug #2159 (Problem with update of blob to > 16M)
4906 +CREATE TABLE t1 (data LONGBLOB);
4907 +INSERT INTO t1 (data) VALUES (NULL);
4908 +UPDATE t1 set data=repeat('a',18*1024*1024);
4909 +select length(data) from t1;
4910 +delete from t1 where left(data,1)='a';
4912 +INSERT INTO t1 (data) VALUES (repeat('a',1*1024*1024));
4913 +INSERT INTO t1 (data) VALUES (repeat('b',16*1024*1024-1024));
4914 +delete from t1 where left(data,1)='b';
4916 +# now we have two blocks in the table, first is a 1M record and second is
4917 +# a 16M delete block.
4919 +UPDATE t1 set data=repeat('c',17*1024*1024);
4920 +delete from t1 where left(data,1)='c';
4922 +INSERT INTO t1 set data=repeat('a',18*1024*1024);
4923 +select length(data) from t1;
4924 +alter table t1 modify data blob;
4925 +select length(data) from t1;
4928 +CREATE TABLE t1 (data BLOB);
4929 +INSERT INTO t1 (data) VALUES (NULL);
4930 +UPDATE t1 set data=repeat('a',18*1024*1024);
4931 +select length(data) from t1;
4935 +connection default;
4937 +SET GLOBAL max_allowed_packet = @old_max_allowed_packet;
4938 +SET GLOBAL max_heap_table_size = @old_max_heap_table_size;
4939 +SET default_storage_engine=@old_default_storage_engine;
4941 +++ b/mysql-test/t/percona_heap_bug783366.test
4944 +# Test for bug lp:783366
4948 +drop table if exists t1;
4952 + f1 VARCHAR ( 128 ) ,
4953 + f2 VARCHAR ( 32 ),
4954 + PRIMARY KEY ( f2 ( 2 ) , f1 )
4956 +ENGINE=HEAP KEY_BLOCK_SIZE = 512;
4957 +INSERT IGNORE INTO t1 VALUES ( 'te' , 'm') , ( NULL , 'think' );
4958 +INSERT IGNORE INTO t1 VALUES ( 'te' , 'm') , ( NULL , 'think' );
4963 +++ b/mysql-test/t/percona_heap_bug783451.test
4965 +# Testcase for the bug https://bugs.launchpad.net/percona-projects-qa/+bug/783451
4966 +# With dynamic row format in HEAP and the UPDATE statement that significantly
4967 +# increases the data size, the table scan in-progress desyncs its table position state.
4968 +# Run with Valgrind if it does not crash for you.
4970 +DROP TABLE IF EXISTS local_1_1;
4972 +CREATE TABLE IF NOT EXISTS local_1_1 ( f1 VARCHAR ( 32 ) NOT NULL , f2 VARCHAR ( 128 ) NOT NULL DEFAULT 'cboepfaobilcchabvglgjdbynog' , f3 VARCHAR ( 32 ) NOT NULL , f4 VARBINARY ( 32 ) NOT NULL , f5 VARBINARY ( 1024 ) DEFAULT 'ycboepfao' , KEY ( f1 /* ( 2 ) */ , f2 /* ( 2 ) */ ) ) ENGINE=HEAP KEY_BLOCK_SIZE = 512;
4973 +INSERT IGNORE INTO local_1_1 VALUES ( REPEAT( 'ervydbimvmbqmsowdbsa' , 1 ) , 'v' , NULL , NULL , REPEAT( 'mervydbimvmbqms' , 5 ) ) , ( 'p' , 6 , 'n' , REPEAT( 'imervydbimvmbqmsowdbs' , 4 ) , 'do' ) , ( NULL , NULL , REPEAT( 'himervydbimvmbqmsowdbsaybudvwaamvhempuublmia' , 6 ) , REPEAT('X', POW(2, 20) * 2) , REPEAT('X', POW(2, 20) * 2) ) , ( REPEAT('X', POW(2, 20) * 2) , REPEAT( 'Y' , 763 ) , NULL , REPEAT('X', POW(2, 20) * 2) , NULL ) , ( REPEAT('X', POW(2, 20) * 2) , 'time' , 'how' , 2 , REPEAT( 'Y' , 107 ) ) , ( REPEAT( 'hyshimervydbimvmbqmsowdbsaybud' , 5 ) , 2 , 8 , NULL , REPEAT('X', POW(2, 20) * 2) ) , ( 'come' , NULL , 'i' , NULL , REPEAT('X', POW(2, 20) * 2) );
4974 +INSERT IGNORE INTO local_1_1 VALUES ( 'ok' , NULL , REPEAT( 'Y' , 651 ) , 2 , 5 ) , ( REPEAT( 'zylcdzkfrqpihyshimervydbimvmbqmsowdbsaybu' , 3 ) , REPEAT( 'Y' , 282 ) , REPEAT( 'X' , 0 ) , REPEAT( 'Y' , 369 ) , 'g' ) , ( 'think' , REPEAT('X', POW(2, 20) * 2), NULL , NULL , REPEAT('X', POW(2, 20) * 2) ) , ( REPEAT( 'Y' , 468 ) , REPEAT( 'dfvbrzylcd' , 6 ) , REPEAT( 'Y' , 264 ) , NULL , 'c' ) , ( NULL , NULL , REPEAT( 'srdfvbrzylcdzkfrqpihyshimervydbimvmbqms' , 0 ) , REPEAT( 'Y' , 244 ) , 7 ) , ( REPEAT( 'Y' , 0 ) , 'how' , 'going' , 'q' , NULL );
4975 +INSERT IGNORE INTO local_1_1 VALUES ( REPEAT('X', POW(2, 20) * 2) , NULL , NULL , NULL , REPEAT('X', POW(2, 20) * 2) ) , ( REPEAT('X', POW(2, 20) * 2) , NULL , REPEAT('X', POW(2, 20) * 2) , 'this' , 'e' ) , ( NULL , 'think' , NULL , 'were' , NULL ) , ( 9 , 'l' , 'c' , 3 , REPEAT( 'geysrdfvbrzylcdzkfrqpihyshimervydbi' , 5 ) ) , ( NULL , NULL , NULL , 'h' , 'w' );
4977 +INSERT IGNORE INTO local_1_1 SELECT * FROM local_1_1;
4978 +INSERT IGNORE INTO local_1_1 SELECT * FROM local_1_1;
4979 +UPDATE local_1_1 SET f5 = REPEAT ('X', 215566);
4980 +DROP TABLE local_1_1;
4982 +++ b/mysql-test/t/percona_heap_bug784464.test
4985 +# Bug #784464: Silent conversion from Dynamic to Fixed row_format for certain
4986 +# values of key_block_size.
4987 +# Also see percona_heap_bug784464_32bit and percona_heap_bug784464_64bit tests.
4990 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
4991 + PRIMARY KEY (f1)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
4992 +--replace_column 6 X 8 X 12 X 13 X
4993 +SHOW TABLE STATUS LIKE 't1';
4996 +--error ER_CANT_USE_OPTION_HERE
4997 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
4998 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=33 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
4999 +--replace_column 12 X 13 X
5000 +SHOW TABLE STATUS LIKE 't1';
5002 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
5003 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=34 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5004 +--replace_column 6 X 8 X 12 X 13 X
5005 +SHOW TABLE STATUS LIKE 't1';
5008 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
5009 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=123 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5010 +--replace_column 6 X 8 X 12 X 13 X
5011 +SHOW TABLE STATUS LIKE 't1';
5014 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
5015 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=1000 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5016 +--replace_column 6 X 8 X 12 X 13 X
5017 +SHOW TABLE STATUS LIKE 't1';
5020 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
5021 + PRIMARY KEY (f1)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5022 +--replace_column 6 X 8 X 12 X 13 X
5023 +SHOW TABLE STATUS LIKE 't1';
5026 +--error ER_CANT_USE_OPTION_HERE
5027 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
5028 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=33 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5029 +--replace_column 12 X 13 X
5030 +SHOW TABLE STATUS LIKE 't1';
5032 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
5033 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=34 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5034 +--replace_column 6 X 8 X 12 X 13 X
5035 +SHOW TABLE STATUS LIKE 't1';
5038 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
5039 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=121 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5040 +--replace_column 6 X 8 X 12 X 13 X
5041 +SHOW TABLE STATUS LIKE 't1';
5044 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
5045 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=1000 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5046 +--replace_column 6 X 8 X 12 X 13 X
5047 +SHOW TABLE STATUS LIKE 't1';
5051 +++ b/mysql-test/t/percona_heap_bug784464_32bit.test
5053 +# 32-bit platform specific parts of tests for LP bug #784464
5055 +--source include/have_32bit.inc
5057 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
5058 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=124 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5059 +--replace_column 6 X 8 X 12 X 13 X
5060 +SHOW TABLE STATUS LIKE 't1';
5063 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
5064 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=122 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5065 +--replace_column 6 X 8 X 12 X 13 X
5066 +SHOW TABLE STATUS LIKE 't1';
5069 +++ b/mysql-test/t/percona_heap_bug784464_64bit.test
5071 +# 64-bit platform specific parts of tests for LP bug #784464
5073 +--source include/have_64bit.inc
5075 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32),
5076 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=124 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5077 +--replace_column 6 X 8 X 12 X 13 X
5078 +SHOW TABLE STATUS LIKE 't1';
5081 +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96),
5082 + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=122 ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5083 +--replace_column 6 X 8 X 12 X 13 X
5084 +SHOW TABLE STATUS LIKE 't1';
5087 +++ b/mysql-test/t/percona_heap_bug784468.test
5090 +# Bug #784468: Tables with VARCHAR(<31) are created as row_format = Fixed
5093 +CREATE TABLE t1 ( f1 VARCHAR(30)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5094 +--replace_column 8 X 12 X 13 X
5095 +SHOW TABLE STATUS LIKE 't1';
5098 +CREATE TABLE t1 ( f1 VARCHAR(31)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5099 +--replace_column 8 X 12 X 13 X
5100 +SHOW TABLE STATUS LIKE 't1';
5103 +CREATE TABLE t1 ( f1 VARCHAR(32)) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5104 +--replace_column 8 X 12 X 13 X
5105 +SHOW TABLE STATUS LIKE 't1';
5109 +++ b/mysql-test/t/percona_heap_bug788544.test
5112 +# Bug #788544: Valgrind warnings/crash in mysql-55-eb-blobs in
5113 +# hp_extract_record / hp_process_field_data_to_chunkset
5116 +CREATE TABLE t1 (f2 VARCHAR (32), f4 LONGBLOB, f5 TEXT) ENGINE=HEAP;
5118 +INSERT INTO t1 VALUES ('a', NULL, NULL),
5119 + ('b' , REPEAT('a' , 593338), REPEAT('a', 800));
5121 +UPDATE t1 SET f2 = 'c' WHERE f4 = 'd';
5123 +SELECT LENGTH(f2), LENGTH(f4), LENGTH(f5) FROM t1;
5127 +++ b/mysql-test/t/percona_heap_bug788576.test
5130 +# Bug #788576: Second crash in hp_movelink with mysql-55-eb
5133 +CREATE TABLE t1 (f1 VARCHAR (32), f2 VARCHAR (128), f3 VARBINARY (128),
5134 + f4 VARBINARY (512), f5 VARBINARY (1024),
5135 + KEY (f2(1))) ENGINE=HEAP ROW_FORMAT=DYNAMIC;
5137 +INSERT IGNORE INTO t1 VALUES (2, NULL, 6, REPEAT('glugcgqk', 5), 'look'),
5138 + (REPEAT( 'kglugcgqkin', 6), 'if', 'was', NULL, NULL),
5139 + (NULL, NULL, NULL, NULL, 7);
5143 +DELETE FROM t1 WHERE f5 <=> NULL;
5149 +++ b/mysql-test/t/percona_heap_bug788722.test
5152 +# Bug #788722: Second valgrind warning around hp_extract_record in mysql-55-eb-blobs
5155 +CREATE TABLE IF NOT EXISTS local_1_1 (f1 VARCHAR (32) NOT NULL,
5156 + f2 VARCHAR (128) NOT NULL,
5162 +) ENGINE=HEAP ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE = 2048;
5164 +INSERT IGNORE INTO local_1_1 VALUES
5165 + (REPEAT('egqeqfxwaejpqixuvvtentruyqadxiybjdfqjspfbyjdjczrrwjnagkzsoagatqookhsgtrvvbxacppljfzaseidqggxvuirm' , 5), NULL, NULL, NULL, REPEAT('hegqeqfxwaejpqixuvvtentruyqadxiy', 1)),
5166 + ('you', NULL, 0, REPEAT("X", 2048) , 0);
5168 +INSERT IGNORE INTO local_1_1 SELECT * FROM local_1_1;
5170 +DROP TABLE local_1_1;
5172 +++ b/mysql-test/t/percona_heap_bug789131.test
5175 +# Bug #789131: Valgrind warning in MyISAM in mysql-55-eb-blobs
5178 +CREATE TABLE t1 (f1 VARCHAR (128), f2 VARCHAR (128), f3 VARBINARY (512),
5179 + f4 TEXT (65525), f5 VARCHAR (128), KEY (f1(1))) ENGINE=HEAP;
5181 +INSERT IGNORE INTO t1 VALUES
5182 + ( 'o' , "" , NULL , "" , 0 ) ,
5183 + (NULL, "" , "" , "" , 'f' ) ;
5185 +INSERT IGNORE INTO t1 SELECT * FROM t1;
5188 \ No newline at end of file
5190 +++ b/mysql-test/t/percona_heap_var.test
5193 +# Test heap tables with variable-sized records.
5197 +drop table if exists t1;
5200 +set @@session.max_heap_table_size=16*1024*1024;
5203 +create table t1 (a int not null, b varchar(400), c int, primary key (a), key (c)) engine=heap comment="testing heaps" key_block_size=128;
5206 +create table t1 (a int not null, b int, c varchar(400), primary key (a), key (b)) engine=heap comment="testing heaps" key_block_size=4;
5208 +create table t1 (a int not null, b int, c varchar(400), d varchar(400), primary key (a), key (b)) engine=heap comment="testing heaps" key_block_size=24;
5210 +--replace_column 6 X 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
5211 +--query_vertical show table status like "t1"
5213 +insert into t1 values (1,1,'012',NULL), (2,2,'0123456789',NULL), (3,3,'012345678901234567890123456789',NULL), (4,4,NULL,'0123456789012345678901234567890123456789012345678901234567890123456789');
5216 +delete from t1 where a = 3;
5219 +insert into t1 values (5,5,NULL,'0123'), (6,6,NULL,'0123');
5222 +update t1 set c = '012345678901234567890123456789' where a = 2;
5225 +update t1 set c = '0123456789' where a = 2;
5228 +insert into t1 values (7,7,'0123',NULL), (8,8,'0123',NULL);
5231 +--replace_column 6 X 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
5232 +--query_vertical show table status like "t1"
5233 +alter table t1 key_block_size = 0;
5234 +--replace_column 6 X 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
5235 +--query_vertical show table status like "t1"
5236 +alter table t1 row_format = dynamic;
5237 +--replace_column 6 X 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
5238 +--replace_regex /KEY_BLOCK_SIZE=[[:digit:]]+/KEY_BLOCK_SIZE=X/
5239 +--query_vertical show table status like "t1"
5240 +alter table t1 key_block_size = 128, max_rows = 10001;
5241 +--replace_column 6 X 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
5242 +--query_vertical show table status like "t1"
5251 +call mtr.add_suppression("The table 't1' is full");
5258 + eval insert into t1 values ($1,$1,$1,$1);
5265 +select count(*) from t1;
5268 +insert into t1 values (100000,100000,NULL,'0123'), (100000,100000,NULL,'0123');
5270 +--replace_column 6 X 7 X 8 X 9 X 10 X 11 X 12 X 13 X 14 X
5271 +--query_vertical show table status like "t1"
5272 +select count(*) from t1;
5274 +set @@session.max_heap_table_size=default;