1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into mysql.com:/media/sda1/mysql/mysql-5.0-926
This commit is contained in:
konstantin@mysql.com
2005-03-13 23:53:30 +03:00
9 changed files with 635 additions and 192 deletions

View File

@ -8359,6 +8359,117 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
/****************************************************************************/
/*
Create a reduced TABLE object with properly set up Field list from a
list of field definitions.
SYNOPSIS
create_virtual_tmp_table()
thd connection handle
field_list list of column definitions
DESCRIPTION
The created table doesn't have a table handler assotiated with
it, has no keys, no group/distinct, no copy_funcs array.
The sole purpose of this TABLE object is to use the power of Field
class to read/write data to/from table->record[0]. Then one can store
the record in any container (RB tree, hash, etc).
The table is created in THD mem_root, so are the table's fields.
Consequently, if you don't BLOB fields, you don't need to free it.
RETURN
0 if out of memory, TABLE object in case of success
*/
TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
{
uint field_count= field_list.elements;
Field **field;
create_field *cdef; /* column definition */
uint record_length= 0;
uint null_count= 0; /* number of columns which may be null */
uint null_pack_length; /* NULL representation array length */
TABLE_SHARE *s;
/* Create the table and list of all fields */
TABLE *table= (TABLE*) thd->calloc(sizeof(*table));
field= (Field**) thd->alloc((field_count + 1) * sizeof(Field*));
if (!table || !field)
return 0;
table->field= field;
table->s= s= &table->share_not_to_be_used;
s->fields= field_count;
/* Create all fields and calculate the total length of record */
List_iterator_fast<create_field> it(field_list);
while ((cdef= it++))
{
*field= make_field(0, cdef->length,
(uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
f_maybe_null(cdef->pack_flag) ? 1 : 0,
cdef->pack_flag, cdef->sql_type, cdef->charset,
cdef->geom_type, cdef->unireg_check,
cdef->interval, cdef->field_name, table);
if (!*field)
goto error;
record_length+= (**field).pack_length();
if (! ((**field).flags & NOT_NULL_FLAG))
++null_count;
++field;
}
*field= NULL; /* mark the end of the list */
null_pack_length= (null_count + 7)/8;
s->reclength= record_length + null_pack_length;
s->rec_buff_length= ALIGN_SIZE(s->reclength + 1);
table->record[0]= (byte*) thd->alloc(s->rec_buff_length);
if (!table->record[0])
goto error;
if (null_pack_length)
{
table->null_flags= (uchar*) table->record[0];
s->null_fields= null_count;
s->null_bytes= null_pack_length;
}
table->in_use= thd; /* field->reset() may access table->in_use */
{
/* Set up field pointers */
byte *null_pos= table->record[0];
byte *field_pos= null_pos + s->null_bytes;
uint null_bit= 1;
for (field= table->field; *field; ++field)
{
Field *cur_field= *field;
if ((cur_field->flags & NOT_NULL_FLAG))
cur_field->move_field((char*) field_pos);
else
{
cur_field->move_field((char*) field_pos, (uchar*) null_pos, null_bit);
null_bit<<= 1;
if (null_bit == (1 << 8))
{
++null_pos;
null_bit= 1;
}
}
cur_field->reset();
field_pos+= cur_field->pack_length();
}
}
return table;
error:
for (field= table->field; *field; ++field)
delete *field; /* just invokes field destructor */
return 0;
}
static bool open_tmp_table(TABLE *table)
{
int error;