17
17
/* Some general useful functions */
19
21
#include <drizzled/server_includes.h>
20
#include <drizzled/drizzled_error_messages.h>
22
#include "tmp_table.h"
23
#include "sj_tmp_table.h"
22
#include <drizzled/error.h>
23
#include <drizzled/gettext.h>
25
#include <drizzled/tmp_table.h>
26
#include <drizzled/sj_tmp_table.h>
27
#include <drizzled/nested_join.h>
28
#include <drizzled/data_home.h>
29
#include <drizzled/sql_parse.h>
25
35
/* INFORMATION_SCHEMA name */
26
36
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
38
/* Keyword for parsing virtual column functions */
39
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
28
41
/* Functions defined in this file */
30
43
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
31
44
myf errortype, int errarg);
32
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
33
uchar *head, File file);
45
static int open_binary_frm(Session *session, TABLE_SHARE *share,
46
unsigned char *head, File file);
34
47
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
35
uint types, char **names);
36
static uint find_field(Field **fields, uchar *record, uint start, uint length);
48
uint32_t types, char **names);
49
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length);
38
51
/*************************************************************************/
40
53
/* Get column name from column hash */
42
static uchar *get_field_name(Field **buff, size_t *length,
43
bool not_used __attribute__((unused)))
55
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
45
57
*length= (uint) strlen((*buff)->field_name);
46
return (uchar*) (*buff)->field_name;
58
return (unsigned char*) (*buff)->field_name;
407
427
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
410
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
430
static int open_binary_frm(Session *session, TABLE_SHARE *share, unsigned char *head,
413
433
int error, errarg= 0;
414
uint new_frm_ver, field_pack_length, new_field_pack_flag;
415
uint interval_count, interval_parts, read_length, int_length;
416
uint db_create_options, keys, key_parts, n_length;
417
uint key_info_length, com_length, null_bit_pos=0;
418
uint extra_rec_buf_length;
434
uint32_t new_frm_ver, field_pack_length, new_field_pack_flag;
435
uint32_t interval_count, interval_parts, read_length, int_length;
436
uint32_t db_create_options, keys, key_parts, n_length;
437
uint32_t key_info_length, com_length, null_bit_pos=0;
438
uint32_t vcol_screen_length;
439
uint32_t extra_rec_buf_length;
422
char *keynames, *names, *comment_pos;
424
uchar *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
442
unsigned char forminfo[288];
443
char *keynames, *names, *comment_pos, *vcol_screen_pos;
444
unsigned char *record;
445
unsigned char *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
425
446
ulong pos, record_offset, *rec_per_key, rec_buff_length;
426
447
handler *handler_file= 0;
1265
Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
1266
This routine is used for error handling purposes.
1270
table Table object for which virtual columns are set-up
1275
static void clear_field_flag(Table *table)
1279
for (ptr= table->field; *ptr; ptr++)
1280
(*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
1284
The function uses the feature in fix_fields where the flag
1285
GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
1286
This field must always be reset before returning from the function
1287
since it is used for other purposes as well.
1290
fix_fields_vcol_func()
1291
session The thread object
1292
func_item The item tree reference of the virtual columnfunction
1293
table The table object
1294
field_name The name of the processed field
1297
true An error occurred, something was wrong with the
1299
false Ok, a partition field array was created
1302
bool fix_fields_vcol_func(Session *session,
1305
const char *field_name)
1307
uint dir_length, home_dir_length;
1310
TableList *save_table_list, *save_first_table, *save_last_table;
1312
Name_resolution_context *context;
1313
const char *save_where;
1315
char db_name_string[FN_REFLEN];
1316
bool save_use_only_table_context;
1317
Field **ptr, *field;
1318
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
1322
Set-up the TABLE_LIST object to be a list with a single table
1323
Set the object to zero to create NULL pointers and set alias
1324
and real name to table name and get database name from file name.
1327
bzero((void*)&tables, sizeof(TableList));
1328
tables.alias= tables.table_name= (char*) table->s->table_name.str;
1329
tables.table= table;
1330
tables.next_local= NULL;
1331
tables.next_name_resolution_table= NULL;
1332
memcpy(db_name_string,
1333
table->s->normalized_path.str,
1334
table->s->normalized_path.length);
1335
dir_length= dirname_length(db_name_string);
1336
db_name_string[dir_length - 1]= 0;
1337
home_dir_length= dirname_length(db_name_string);
1338
db_name= &db_name_string[home_dir_length];
1341
session->mark_used_columns= MARK_COLUMNS_NONE;
1343
context= session->lex->current_context();
1344
table->map= 1; //To ensure correct calculation of const item
1345
table->get_fields_in_item_tree= true;
1346
save_table_list= context->table_list;
1347
save_first_table= context->first_name_resolution_table;
1348
save_last_table= context->last_name_resolution_table;
1349
context->table_list= &tables;
1350
context->first_name_resolution_table= &tables;
1351
context->last_name_resolution_table= NULL;
1352
func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
1353
save_where= session->where;
1354
session->where= "virtual column function";
1356
/* Save the context before fixing the fields*/
1357
save_use_only_table_context= session->lex->use_only_table_context;
1358
session->lex->use_only_table_context= true;
1359
/* Fix fields referenced to by the virtual column function */
1360
error= func_expr->fix_fields(session, (Item**)0);
1361
/* Restore the original context*/
1362
session->lex->use_only_table_context= save_use_only_table_context;
1363
context->table_list= save_table_list;
1364
context->first_name_resolution_table= save_first_table;
1365
context->last_name_resolution_table= save_last_table;
1367
if (unlikely(error))
1369
clear_field_flag(table);
1372
session->where= save_where;
1374
Walk through the Item tree checking if all items are valid
1375
to be part of the virtual column
1377
error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
1380
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
1381
clear_field_flag(table);
1384
if (unlikely(func_expr->const_item()))
1386
my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
1387
clear_field_flag(table);
1390
/* Ensure that this virtual column is not based on another virtual field. */
1392
while ((field= *(ptr++)))
1394
if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
1397
my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
1398
clear_field_flag(table);
1403
Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
1404
when calling fix_fields.
1406
clear_field_flag(table);
1410
table->get_fields_in_item_tree= false;
1411
session->mark_used_columns= save_mark_used_columns;
1412
table->map= 0; //Restore old value
1417
Unpack the definition of a virtual column
1420
unpack_vcol_info_from_frm()
1421
session Thread handler
1422
table Table with the checked field
1423
field Pointer to Field object
1424
open_mode Open table mode needed to determine
1425
which errors need to be generated in a failure
1426
error_reported updated flag for the caller that no other error
1427
messages are to be generated.
1433
bool unpack_vcol_info_from_frm(Session *session,
1436
LEX_STRING *vcol_expr,
1437
open_table_mode open_mode,
1438
bool *error_reported)
1443
Step 1: Construct a statement for the parser.
1444
The parsed string needs to take the following format:
1445
"PARSE_VCOL_EXPR (<expr_string_from_frm>)"
1447
char *vcol_expr_str;
1450
if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
1452
parse_vcol_keyword.length + 3)))
1456
memcpy(vcol_expr_str,
1457
(char*) parse_vcol_keyword.str,
1458
parse_vcol_keyword.length);
1459
str_len= parse_vcol_keyword.length;
1460
memcpy(vcol_expr_str + str_len, "(", 1);
1462
memcpy(vcol_expr_str + str_len,
1463
(char*) vcol_expr->str,
1465
str_len+= vcol_expr->length;
1466
memcpy(vcol_expr_str + str_len, ")", 1);
1468
memcpy(vcol_expr_str + str_len, "\0", 1);
1470
Lex_input_stream lip(session, vcol_expr_str, str_len);
1473
Step 2: Setup session for parsing.
1474
1) make Item objects be created in the memory allocated for the Table
1475
object (not TABLE_SHARE)
1476
2) ensure that created Item's are not put on to session->free_list
1477
(which is associated with the parsed statement and hence cleared after
1479
3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
1480
to be parsed as a SQL command.
1482
MEM_ROOT **root_ptr, *old_root;
1483
Item *backup_free_list= session->free_list;
1484
root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
1485
old_root= *root_ptr;
1486
*root_ptr= &table->mem_root;
1487
session->free_list= NULL;
1488
session->lex->parse_vcol_expr= true;
1491
Step 3: Use the parser to build an Item object from.
1493
if (parse_sql(session, &lip))
1497
/* From now on use vcol_info generated by the parser. */
1498
field->vcol_info= session->lex->vcol_info;
1500
/* Validate the Item tree. */
1501
if (fix_fields_vcol_func(session,
1502
field->vcol_info->expr_item,
1506
if (open_mode == OTM_CREATE)
1509
During CREATE/ALTER TABLE it is ok to receive errors here.
1510
It is not ok if it happens during the opening of an frm
1511
file as part of a normal query.
1513
*error_reported= true;
1515
field->vcol_info= NULL;
1518
field->vcol_info->item_free_list= session->free_list;
1519
session->free_list= backup_free_list;
1520
*root_ptr= old_root;
1525
session->lex->parse_vcol_expr= false;
1526
session->free_items();
1527
*root_ptr= old_root;
1528
session->free_list= backup_free_list;
1182
1534
Open a table based on a TABLE_SHARE
1185
1537
open_table_from_share()
1538
session Thread handler
1187
1539
share Table definition
1188
1540
alias Alias for table
1189
1541
db_stat open flags (for example HA_OPEN_KEYFILE|
1206
1558
7 Table definition has changed in engine
1209
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
1210
uint db_stat, uint prgflag, uint ha_open_flags,
1561
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1562
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1211
1563
Table *outparam, open_table_mode open_mode)
1214
uint records, i, bitmap_size;
1566
uint32_t records, i, bitmap_size;
1215
1567
bool error_reported= false;
1216
uchar *record, *bitmaps;
1568
unsigned char *record, *bitmaps;
1569
Field **field_ptr, **vfield_ptr;
1219
/* Parsing of partitioning information from .frm needs thd->lex set up. */
1220
assert(thd->lex->is_lex_started);
1571
/* Parsing of partitioning information from .frm needs session->lex set up. */
1572
assert(session->lex->is_lex_started);
1223
1575
memset(outparam, 0, sizeof(*outparam));
1224
outparam->in_use= thd;
1576
outparam->in_use= session;
1225
1577
outparam->s= share;
1226
1578
outparam->db_stat= db_stat;
1227
1579
outparam->write_row_record= NULL;
1720
Process virtual columns, if any.
1722
if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
1723
(uint) ((share->vfields+1)*
1727
outparam->vfield= vfield_ptr;
1729
for (field_ptr= outparam->field; *field_ptr; field_ptr++)
1731
if ((*field_ptr)->vcol_info)
1733
if (unpack_vcol_info_from_frm(session,
1736
&(*field_ptr)->vcol_info->expr_str,
1740
error= 4; // in case no error is reported
1743
*(vfield_ptr++)= *field_ptr;
1746
*vfield_ptr= NULL; // End marker
1747
/* Check virtual columns against table's storage engine. */
1748
if ((share->vfields && outparam->file) &&
1749
(not outparam->file->check_if_supported_virtual_columns()))
1751
my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
1753
"Specified storage engine");
1754
error_reported= true;
1367
1758
/* Allocate bitmaps */
1369
1760
bitmap_size= share->column_bitmap_size;
1370
if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1761
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1372
1763
bitmap_init(&outparam->def_read_set,
1373
1764
(my_bitmap_map*) bitmaps, share->fields, false);
1595
1987
while (endpos > maxlength)
1597
VOID(my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0)));
1989
my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0));
1598
1990
if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
1600
VOID(my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1992
my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1602
1994
if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1604
1996
endpos-=bufflength; bufflength=IO_SIZE;
1606
1998
memset(buff, 0, IO_SIZE); /* Null new block */
1607
VOID(my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0)));
1999
my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0));
1608
2000
if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1610
2002
maxlength+=IO_SIZE; /* Fix old ref */
1611
2003
int2store(fileinfo+6,maxlength);
1612
for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ;
2004
for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i-- ;
1615
2007
endpos=uint4korr(pos)+IO_SIZE;
1620
2012
if (n_length == 1 )
1621
2013
{ /* First name */
1623
VOID(strxmov((char*) buff,"/",newname,"/",NullS));
2015
strxmov((char*) buff,"/",newname,"/",NULL);
1626
VOID(strxmov((char*) buff,newname,"/",NullS)); /* purecov: inspected */
1627
VOID(my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0)));
2018
strxmov((char*) buff,newname,"/",NULL); /* purecov: inspected */
2019
my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0));
1628
2020
if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1629
(names && my_write(file,(uchar*) (*formnames->type_names+n_length-1),
2021
(names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
1630
2022
names*4, MYF(MY_NABP+MY_WME))) ||
1631
2023
my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
1632
2024
return(0L); /* purecov: inspected */
1634
2026
int2store(fileinfo+8,names+1);
1635
2027
int2store(fileinfo+4,n_length+length);
1636
(void)ftruncate(file, newpos);/* Append file with '\0' */
2028
assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
1637
2029
return(newpos);
1638
2030
} /* make_new_entry */
3563
3993
TABLE_SHARE *share;
3564
3994
uint i,field_count,null_count,null_pack_length;
3565
uint copy_func_count= param->func_count;
3566
uint hidden_null_count, hidden_null_pack_length, hidden_field_count;
3567
uint blob_count,group_null_items, string_count;
3568
uint temp_pool_slot=MY_BIT_NONE;
3995
uint32_t copy_func_count= param->func_count;
3996
uint32_t hidden_null_count, hidden_null_pack_length, hidden_field_count;
3997
uint32_t blob_count,group_null_items, string_count;
3998
uint32_t temp_pool_slot=MY_BIT_NONE;
3999
uint32_t fieldnr= 0;
3570
4000
ulong reclength, string_total_length;
3571
4001
bool using_unique_constraint= 0;
3572
4002
bool use_packed_rows= 0;
3573
4003
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
3574
4004
char *tmpname,path[FN_REFLEN];
3575
uchar *pos, *group_buff, *bitmaps;
4005
unsigned char *pos, *group_buff, *bitmaps;
4006
unsigned char *null_flags;
3577
4007
Field **reg_field, **from_field, **default_field;
4008
uint32_t *blob_field;
3579
4009
Copy_field *copy=0;
3581
4011
KEY_PART_INFO *key_part_info;
3582
4012
Item **copy_func;
3583
4013
MI_COLUMNDEF *recinfo;
3584
uint total_uneven_bit_length= 0;
4014
uint32_t total_uneven_bit_length= 0;
3585
4015
bool force_copy_fields= param->force_copy_fields;
3587
status_var_increment(thd->status_var.created_tmp_tables);
4017
status_var_increment(session->status_var.created_tmp_tables);
3589
4019
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
3590
4020
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
4237
4667
The sole purpose of this Table object is to use the power of Field
4238
4668
class to read/write data to/from table->record[0]. Then one can store
4239
4669
the record in any container (RB tree, hash, etc).
4240
The table is created in THD mem_root, so are the table's fields.
4670
The table is created in Session mem_root, so are the table's fields.
4241
4671
Consequently, if you don't BLOB fields, you don't need to free it.
4243
@param thd connection handle
4673
@param session connection handle
4244
4674
@param field_list list of column definitions
4247
4677
0 if out of memory, Table object in case of success
4250
Table *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
4680
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4252
uint field_count= field_list.elements;
4682
uint32_t field_count= field_list.elements;
4683
uint32_t blob_count= 0;
4255
4685
Create_field *cdef; /* column definition */
4256
uint record_length= 0;
4257
uint null_count= 0; /* number of columns which may be null */
4258
uint null_pack_length; /* NULL representation array length */
4686
uint32_t record_length= 0;
4687
uint32_t null_count= 0; /* number of columns which may be null */
4688
uint32_t null_pack_length; /* NULL representation array length */
4689
uint32_t *blob_field;
4690
unsigned char *bitmaps;
4262
4692
TABLE_SHARE *share;
4264
if (!multi_alloc_root(thd->mem_root,
4694
if (!multi_alloc_root(session->mem_root,
4265
4695
&table, sizeof(*table),
4266
4696
&share, sizeof(*share),
4267
4697
&field, (field_count + 1) * sizeof(Field*),
4268
4698
&blob_field, (field_count+1) *sizeof(uint),
4269
4699
&bitmaps, bitmap_buffer_size(field_count)*2,
4273
4703
memset(table, 0, sizeof(*table));