Commit 072f4fbf authored by joreland@mysql.com's avatar joreland@mysql.com

Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb

into mysql.com:/home/jonas/src/mysql-4.1-ndb
parents cf6a6054 1778ac4f
This diff is collapsed.
drop table if exists t1;
CREATE TABLE t1 (a INT);
EXPLAIN
SELECT *
INTO OUTFILE '/tmp/t1.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\r\n'
FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
DROP TABLE t1;
...@@ -901,6 +901,8 @@ set group_concat_max_len=10; ...@@ -901,6 +901,8 @@ set group_concat_max_len=10;
select group_concat(a) FROM t1 group by b; select group_concat(a) FROM t1 group by b;
group_concat(a) group_concat(a)
1234567890 1234567890
Warnings:
Warning 1260 1 line(s) were cut by GROUP_CONCAT()
set group_concat_max_len=1024; set group_concat_max_len=1024;
select group_concat(a) FROM t1 group by b; select group_concat(a) FROM t1 group by b;
group_concat(a) group_concat(a)
......
...@@ -240,3 +240,40 @@ SELECT t1.A_ID, GROUP_CONCAT(t2.B_DESC) AS B_DESC FROM t1 LEFT JOIN t2 ON t1.A_I ...@@ -240,3 +240,40 @@ SELECT t1.A_ID, GROUP_CONCAT(t2.B_DESC) AS B_DESC FROM t1 LEFT JOIN t2 ON t1.A_I
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
#
# blobs
#
create table t1 (a int, b text);
insert into t1 values (1, 'bb'), (1, 'ccc'), (1, 'a'), (1, 'bb'), (1, 'ccc');
insert into t1 values (2, 'BB'), (2, 'CCC'), (2, 'A'), (2, 'BB'), (2, 'CCC');
select group_concat(b) from t1 group by a;
select group_concat(distinct b) from t1 group by a;
select group_concat(b order by b) from t1 group by a;
select group_concat(distinct b order by b) from t1 group by a;
set local group_concat_max_len=4;
select group_concat(b) from t1 group by a;
select group_concat(distinct b) from t1 group by a;
select group_concat(b order by b) from t1 group by a;
select group_concat(distinct b order by b) from t1 group by a;
#
# long blobs
#
insert into t1 values (1, concat(repeat('1', 300), '2')),
(1, concat(repeat('1', 300), '2')), (1, concat(repeat('0', 300), '1')),
(2, concat(repeat('1', 300), '2')), (2, concat(repeat('1', 300), '2')),
(2, concat(repeat('0', 300), '1'));
set local group_concat_max_len=1024;
select group_concat(b) from t1 group by a;
select group_concat(distinct b) from t1 group by a;
select group_concat(b order by b) from t1 group by a;
select group_concat(distinct b order by b) from t1 group by a;
set local group_concat_max_len=400;
select group_concat(b) from t1 group by a;
select group_concat(distinct b) from t1 group by a;
select group_concat(b order by b) from t1 group by a;
select group_concat(distinct b order by b) from t1 group by a;
drop table t1;
...@@ -2,9 +2,12 @@ ...@@ -2,9 +2,12 @@
# test of into outfile|dumpfile # test of into outfile|dumpfile
# #
--disable_warnings
drop table if exists t1;
--enable_warnings
# We need to check that we have 'file' privilege. # We need to check that we have 'file' privilege.
#drop table if exists t1;
#create table t1 (`a` blob); #create table t1 (`a` blob);
#insert into t1 values("hello world"),("Hello mars"),(NULL); #insert into t1 values("hello world"),("Hello mars"),(NULL);
#select * into outfile "/tmp/select-test.1" from t1; #select * into outfile "/tmp/select-test.1" from t1;
...@@ -26,3 +29,15 @@ ...@@ -26,3 +29,15 @@
#INSERT INTO t VALUES ('2002-12-20 12:01:20','',1,"aaa","bbb"); #INSERT INTO t VALUES ('2002-12-20 12:01:20','',1,"aaa","bbb");
#select * from t into outfile "check"; #select * from t into outfile "check";
#drop table if exists t; #drop table if exists t;
#
# Bug #5382: 'explain select into outfile' crashes the server
#
CREATE TABLE t1 (a INT);
EXPLAIN
SELECT *
INTO OUTFILE '/tmp/t1.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\r\n'
FROM t1;
DROP TABLE t1;
...@@ -122,7 +122,10 @@ extern "C" { ...@@ -122,7 +122,10 @@ extern "C" {
/* Service errors - Single User Mode */ /* Service errors - Single User Mode */
NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE = 4001, NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE = 4001,
NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE = 4002 NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE = 4002,
/* Usage errors */
NDB_MGM_USAGE_ERROR = 5001
}; };
struct Ndb_Mgm_Error_Msg { struct Ndb_Mgm_Error_Msg {
...@@ -158,7 +161,11 @@ extern "C" { ...@@ -158,7 +161,11 @@ extern "C" {
{ NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE, { NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE,
"Could not enter single user mode" }, "Could not enter single user mode" },
{ NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE, { NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE,
"Could not exit single user mode" } "Could not exit single user mode" },
/* Usage errors */
{ NDB_MGM_USAGE_ERROR,
"Usage error" }
}; };
const int ndb_mgm_noOfErrorMsgs = const int ndb_mgm_noOfErrorMsgs =
......
...@@ -446,6 +446,8 @@ const GsnName SignalNames [] = { ...@@ -446,6 +446,8 @@ const GsnName SignalNames [] = {
,{ GSN_STOP_REQ, "STOP_REQ" } ,{ GSN_STOP_REQ, "STOP_REQ" }
,{ GSN_STOP_REF, "STOP_REF" } ,{ GSN_STOP_REF, "STOP_REF" }
,{ GSN_API_VERSION_REQ, "API_VERSION_REQ" }
,{ GSN_API_VERSION_CONF, "API_VERSION_CONF" }
,{ GSN_ABORT_ALL_REQ, "ABORT_ALL_REQ" } ,{ GSN_ABORT_ALL_REQ, "ABORT_ALL_REQ" }
,{ GSN_ABORT_ALL_REF, "ABORT_ALL_REF" } ,{ GSN_ABORT_ALL_REF, "ABORT_ALL_REF" }
......
...@@ -1153,11 +1153,14 @@ ndb_mgm_dump_state(NdbMgmHandle handle, int nodeId, int* _args, ...@@ -1153,11 +1153,14 @@ ndb_mgm_dump_state(NdbMgmHandle handle, int nodeId, int* _args,
CHECK_CONNECTED(handle, -1); CHECK_CONNECTED(handle, -1);
char buf[256]; char buf[256];
char buf2[6];
buf[0] = 0; buf[0] = 0;
for (int i = 0; i < _num_args; i++){ for (int i = 0; i < _num_args; i++){
snprintf(buf2, 6, "%d ", _args[i]); unsigned n = strlen(buf);
strncat(buf, buf2, 256); if (n + 20 > sizeof(buf)) {
SET_ERROR(handle, NDB_MGM_USAGE_ERROR, "arguments too long");
return -1;
}
sprintf(buf + n, "%s%d", i ? " " : "", _args[i]);
} }
Properties args; Properties args;
......
...@@ -1363,36 +1363,29 @@ CommandInterpreter::executeLog(int processId, ...@@ -1363,36 +1363,29 @@ CommandInterpreter::executeLog(int processId,
if (! parseBlockSpecification(parameters, blocks)) { if (! parseBlockSpecification(parameters, blocks)) {
return; return;
} }
int len=0; int len=1;
Uint32 i; Uint32 i;
for(i=0; i<blocks.size(); i++) { for(i=0; i<blocks.size(); i++) {
ndbout_c("blocks %s %d",blocks[i], strlen(blocks[i])); len += strlen(blocks[i]) + 1;
len += strlen(blocks[i]);
} }
len += blocks.size()*2;
char * blockNames = (char*)my_malloc(len,MYF(MY_WME)); char * blockNames = (char*)my_malloc(len,MYF(MY_WME));
My_auto_ptr<char> ap1(blockNames); My_auto_ptr<char> ap1(blockNames);
blockNames[0] = 0;
for(i=0; i<blocks.size(); i++) { for(i=0; i<blocks.size(); i++) {
strcat(blockNames, blocks[i]); strcat(blockNames, blocks[i]);
strcat(blockNames, "|"); strcat(blockNames, "|");
} }
strcat(blockNames, "\0");
ndbout_c("blocknames %s", blockNames);
/*int res =*/ndb_mgm_log_signals(m_mgmsrv, int result = ndb_mgm_log_signals(m_mgmsrv,
processId, processId,
NDB_MGM_SIGNAL_LOG_MODE_INOUT, NDB_MGM_SIGNAL_LOG_MODE_INOUT,
blockNames, blockNames,
&reply); &reply);
#if 0
int result =
_mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::InOut, blocks);
if (result != 0) { if (result != 0) {
ndbout << _mgmtSrvr.getErrorText(result) << endl; ndbout_c("Execute LOG on node %d failed.", processId);
printError();
} }
#endif
} }
//***************************************************************************** //*****************************************************************************
...@@ -1401,17 +1394,7 @@ void ...@@ -1401,17 +1394,7 @@ void
CommandInterpreter::executeLogIn(int /* processId */, CommandInterpreter::executeLogIn(int /* processId */,
const char* parameters, bool /* all */) const char* parameters, bool /* all */)
{ {
Vector<const char*> blocks; ndbout << "Command LOGIN not implemented." << endl;
if (! parseBlockSpecification(parameters, blocks)) {
return;
}
#if 0
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::In, blocks);
if (result != 0) {
ndbout << _mgmtSrvr.getErrorText(result) << endl;
}
#endif
} }
//***************************************************************************** //*****************************************************************************
...@@ -1420,19 +1403,7 @@ void ...@@ -1420,19 +1403,7 @@ void
CommandInterpreter::executeLogOut(int /*processId*/, CommandInterpreter::executeLogOut(int /*processId*/,
const char* parameters, bool /*all*/) const char* parameters, bool /*all*/)
{ {
Vector<const char*> blocks; ndbout << "Command LOGOUT not implemented." << endl;
if (! parseBlockSpecification(parameters, blocks)) {
return;
}
#if 0
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Out,
blocks);
if (result != 0) {
ndbout << _mgmtSrvr.getErrorText(result) << endl;
}
#endif
} }
//***************************************************************************** //*****************************************************************************
...@@ -1441,57 +1412,45 @@ void ...@@ -1441,57 +1412,45 @@ void
CommandInterpreter::executeLogOff(int /*processId*/, CommandInterpreter::executeLogOff(int /*processId*/,
const char* parameters, bool /*all*/) const char* parameters, bool /*all*/)
{ {
Vector<const char*> blocks; ndbout << "Command LOGOFF not implemented." << endl;
if (! parseBlockSpecification(parameters, blocks)) {
return;
}
#if 0
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Off,
blocks);
if (result != 0) {
ndbout << _mgmtSrvr.getErrorText(result) << endl;
}
#endif
} }
//***************************************************************************** //*****************************************************************************
//***************************************************************************** //*****************************************************************************
void void
CommandInterpreter::executeTestOn(int /*processId*/, CommandInterpreter::executeTestOn(int processId,
const char* parameters, bool /*all*/) const char* parameters, bool /*all*/)
{ {
if (! emptyString(parameters)) { if (! emptyString(parameters)) {
ndbout << "No parameters expected to this command." << endl; ndbout << "No parameters expected to this command." << endl;
return; return;
} }
connect();
#if 0 struct ndb_mgm_reply reply;
int result = _mgmtSrvr.startSignalTracing(processId); int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &reply);
if (result != 0) { if (result != 0) {
ndbout << _mgmtSrvr.getErrorText(result) << endl; ndbout_c("Execute TESTON failed.");
printError();
} }
#endif
} }
//***************************************************************************** //*****************************************************************************
//***************************************************************************** //*****************************************************************************
void void
CommandInterpreter::executeTestOff(int /*processId*/, CommandInterpreter::executeTestOff(int processId,
const char* parameters, bool /*all*/) const char* parameters, bool /*all*/)
{ {
if (! emptyString(parameters)) { if (! emptyString(parameters)) {
ndbout << "No parameters expected to this command." << endl; ndbout << "No parameters expected to this command." << endl;
return; return;
} }
connect();
#if 0 struct ndb_mgm_reply reply;
int result = _mgmtSrvr.stopSignalTracing(processId); int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &reply);
if (result != 0) { if (result != 0) {
ndbout << _mgmtSrvr.getErrorText(result) << endl; ndbout_c("Execute TESTOFF failed.");
printError();
} }
#endif
} }
......
...@@ -1871,16 +1871,20 @@ bool Item_func_group_concat::add() ...@@ -1871,16 +1871,20 @@ bool Item_func_group_concat::add()
} }
null_value= FALSE; null_value= FALSE;
TREE_ELEMENT *el= 0; // Only for safety
if (tree_mode) if (tree_mode)
{ el= tree_insert(tree, table->record[0], 0, tree->custom_arg);
if (!tree_insert(tree, table->record[0], 0, tree->custom_arg)) /*
return 1; If the row is not a duplicate (el->count == 1)
} we can dump the row here in case of GROUP_CONCAT(DISTINCT...)
else instead of doing tree traverse later.
{ */
if (result.length() <= group_concat_max_len && !warning_for_row) if (result.length() <= group_concat_max_len &&
!warning_for_row &&
(!tree_mode || (el->count == 1 && distinct && !arg_count_order)))
dump_leaf_key(table->record[0], 1, this); dump_leaf_key(table->record[0], 1, this);
}
return 0; return 0;
} }
...@@ -1926,6 +1930,8 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -1926,6 +1930,8 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
thd->allow_sum_func= 1; thd->allow_sum_func= 1;
if (!(tmp_table_param= new TMP_TABLE_PARAM)) if (!(tmp_table_param= new TMP_TABLE_PARAM))
return 1; return 1;
/* We'll convert all blobs to varchar fields in the temporary table */
tmp_table_param->convert_blob_length= group_concat_max_len;
tables_list= tables; tables_list= tables;
fixed= 1; fixed= 1;
return 0; return 0;
...@@ -2023,8 +2029,6 @@ bool Item_func_group_concat::setup(THD *thd) ...@@ -2023,8 +2029,6 @@ bool Item_func_group_concat::setup(THD *thd)
} }
else else
{ {
compare_key= NULL;
if (distinct)
compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct; compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct;
} }
/* /*
...@@ -2068,6 +2072,12 @@ String* Item_func_group_concat::val_str(String* str) ...@@ -2068,6 +2072,12 @@ String* Item_func_group_concat::val_str(String* str)
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (null_value) if (null_value)
return 0; return 0;
if (count_cut_values && !warning_available)
{
warning_available= TRUE;
warning= push_warning(item_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CUT_VALUE_GROUP_CONCAT, NULL);
}
if (result.length()) if (result.length())
return &result; return &result;
if (tree_mode) if (tree_mode)
...@@ -2075,12 +2085,6 @@ String* Item_func_group_concat::val_str(String* str) ...@@ -2075,12 +2085,6 @@ String* Item_func_group_concat::val_str(String* str)
tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this, tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
left_root_right); left_root_right);
} }
if (count_cut_values && !warning_available)
{
warning_available= TRUE;
warning= push_warning(item_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CUT_VALUE_GROUP_CONCAT, NULL);
}
return &result; return &result;
} }
......
...@@ -521,7 +521,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result, ...@@ -521,7 +521,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result,
int mysql_handle_derived(LEX *lex); int mysql_handle_derived(LEX *lex);
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item ***copy_func, Field **from_field, Item ***copy_func, Field **from_field,
bool group,bool modify_item); bool group, bool modify_item, uint convert_blob_length);
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
List<create_field> &fields, List<create_field> &fields,
List<Key> &keys, uint &db_options, List<Key> &keys, uint &db_options,
......
...@@ -1250,10 +1250,12 @@ class TMP_TABLE_PARAM :public Sql_alloc ...@@ -1250,10 +1250,12 @@ class TMP_TABLE_PARAM :public Sql_alloc
uint group_parts,group_length,group_null_parts; uint group_parts,group_length,group_null_parts;
uint quick_group; uint quick_group;
bool using_indirect_summary_function; bool using_indirect_summary_function;
/* If >0 convert all blob fields to varchar(convert_blob_length) */
uint convert_blob_length;
TMP_TABLE_PARAM() TMP_TABLE_PARAM()
:copy_funcs_it(copy_funcs), copy_field(0), group_parts(0), :copy_funcs_it(copy_funcs), copy_field(0), group_parts(0),
group_length(0), group_null_parts(0) group_length(0), group_null_parts(0), convert_blob_length(0)
{} {}
~TMP_TABLE_PARAM() ~TMP_TABLE_PARAM()
{ {
......
...@@ -4583,21 +4583,28 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item) ...@@ -4583,21 +4583,28 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
the record in the original table. the record in the original table.
If modify_item is 0 then fill_record() will update If modify_item is 0 then fill_record() will update
the temporary table the temporary table
convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
RETURN RETURN
0 on error 0 on error
new_created field new_created field
*/ */
static Field* create_tmp_field_from_field(THD *thd,
Field* org_field, static Field* create_tmp_field_from_field(THD *thd, Field* org_field,
Item *item, Item *item, TABLE *table,
TABLE *table, bool modify_item,
bool modify_item) uint convert_blob_length)
{ {
Field *new_field; Field *new_field;
// The following should always be true if (convert_blob_length && org_field->flags & BLOB_FLAG)
if ((new_field= org_field->new_field(&thd->mem_root,table))) new_field= new Field_varstring(convert_blob_length, org_field->maybe_null(),
org_field->field_name, table,
org_field->charset());
else
new_field= org_field->new_field(&thd->mem_root, table);
if (new_field)
{ {
if (modify_item) if (modify_item)
((Item_field *)item)->result_field= new_field; ((Item_field *)item)->result_field= new_field;
...@@ -4628,16 +4635,16 @@ static Field* create_tmp_field_from_field(THD *thd, ...@@ -4628,16 +4635,16 @@ static Field* create_tmp_field_from_field(THD *thd,
the record in the original table. the record in the original table.
If modify_item is 0 then fill_record() will update If modify_item is 0 then fill_record() will update
the temporary table the temporary table
convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
RETURN RETURN
0 on error 0 on error
new_created field new_created field
*/ */
static Field* create_tmp_field_from_item(THD *thd, static Field* create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
Item *item, Item ***copy_func, bool modify_item,
TABLE *table, uint convert_blob_length)
Item ***copy_func,
bool modify_item)
{ {
bool maybe_null=item->maybe_null; bool maybe_null=item->maybe_null;
Field *new_field; Field *new_field;
...@@ -4654,13 +4661,18 @@ static Field* create_tmp_field_from_item(THD *thd, ...@@ -4654,13 +4661,18 @@ static Field* create_tmp_field_from_item(THD *thd,
break; break;
case STRING_RESULT: case STRING_RESULT:
if (item->max_length > 255) if (item->max_length > 255)
new_field= new Field_blob(item->max_length, maybe_null, {
if (convert_blob_length)
new_field= new Field_varstring(convert_blob_length, maybe_null,
item->name, table, item->name, table,
item->collation.collation); item->collation.collation);
else else
new_field= new Field_string(item->max_length, maybe_null, new_field= new Field_blob(item->max_length, maybe_null, item->name,
item->name, table, table, item->collation.collation);
item->collation.collation); }
else
new_field= new Field_string(item->max_length, maybe_null, item->name,
table, item->collation.collation);
break; break;
case ROW_RESULT: case ROW_RESULT:
default: default:
...@@ -4697,6 +4709,8 @@ static Field* create_tmp_field_from_item(THD *thd, ...@@ -4697,6 +4709,8 @@ static Field* create_tmp_field_from_item(THD *thd,
the record in the original table. the record in the original table.
If modify_item is 0 then fill_record() will update If modify_item is 0 then fill_record() will update
the temporary table the temporary table
convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
RETURN RETURN
0 on error 0 on error
...@@ -4705,7 +4719,7 @@ static Field* create_tmp_field_from_item(THD *thd, ...@@ -4705,7 +4719,7 @@ static Field* create_tmp_field_from_item(THD *thd,
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item ***copy_func, Field **from_field, Item ***copy_func, Field **from_field,
bool group, bool modify_item) bool group, bool modify_item, uint convert_blob_length)
{ {
switch (type) { switch (type) {
case Item::SUM_FUNC_ITEM: case Item::SUM_FUNC_ITEM:
...@@ -4740,8 +4754,15 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -4740,8 +4754,15 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
item->name,table,item->unsigned_flag); item->name,table,item->unsigned_flag);
case STRING_RESULT: case STRING_RESULT:
if (item_sum->max_length > 255) if (item_sum->max_length > 255)
return new Field_blob(item_sum->max_length,maybe_null, {
item->name,table,item->collation.collation); if (convert_blob_length)
return new Field_varstring(convert_blob_length, maybe_null,
item->name, table,
item->collation.collation);
else
return new Field_blob(item_sum->max_length, maybe_null, item->name,
table, item->collation.collation);
}
return new Field_string(item_sum->max_length,maybe_null, return new Field_string(item_sum->max_length,maybe_null,
item->name,table,item->collation.collation); item->name,table,item->collation.collation);
case ROW_RESULT: case ROW_RESULT:
...@@ -4758,8 +4779,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -4758,8 +4779,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case Item::DEFAULT_VALUE_ITEM: case Item::DEFAULT_VALUE_ITEM:
{ {
Item_field *field= (Item_field*) item; Item_field *field= (Item_field*) item;
return create_tmp_field_from_field(thd, (*from_field= field->field), return create_tmp_field_from_field(thd, (*from_field= field->field), item,
item, table, modify_item); table, modify_item, convert_blob_length);
} }
case Item::FUNC_ITEM: case Item::FUNC_ITEM:
case Item::COND_ITEM: case Item::COND_ITEM:
...@@ -4774,14 +4795,16 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -4774,14 +4795,16 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case Item::REF_ITEM: case Item::REF_ITEM:
case Item::NULL_ITEM: case Item::NULL_ITEM:
case Item::VARBIN_ITEM: case Item::VARBIN_ITEM:
return create_tmp_field_from_item(thd, item, table, return create_tmp_field_from_item(thd, item, table, copy_func, modify_item,
copy_func, modify_item); convert_blob_length);
case Item::TYPE_HOLDER: case Item::TYPE_HOLDER:
{ {
Field *example= ((Item_type_holder *)item)->example(); Field *example= ((Item_type_holder *)item)->example();
if (example) if (example)
return create_tmp_field_from_field(thd, example, item, table, 0); return create_tmp_field_from_field(thd, example, item, table, 0,
return create_tmp_field_from_item(thd, item, table, copy_func, 0); convert_blob_length);
return create_tmp_field_from_item(thd, item, table, copy_func, 0,
convert_blob_length);
} }
default: // Dosen't have to be stored default: // Dosen't have to be stored
return 0; return 0;
...@@ -4945,8 +4968,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -4945,8 +4968,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!arg->const_item()) if (!arg->const_item())
{ {
Field *new_field= Field *new_field=
create_tmp_field(thd, table,arg,arg->type(),&copy_func, create_tmp_field(thd, table, arg, arg->type(), &copy_func,
tmp_from_field, group != 0,not_all_columns); tmp_from_field, group != 0,not_all_columns,
param->convert_blob_length);
if (!new_field) if (!new_field)
goto err; // Should be OOM goto err; // Should be OOM
tmp_from_field++; tmp_from_field++;
...@@ -4982,9 +5006,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -4982,9 +5006,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
We here distinguish between UNION and multi-table-updates by the fact We here distinguish between UNION and multi-table-updates by the fact
that in the later case group is set to the row pointer. that in the later case group is set to the row pointer.
*/ */
Field *new_field=create_tmp_field(thd, table, item,type, &copy_func, Field *new_field= create_tmp_field(thd, table, item, type, &copy_func,
tmp_from_field, group != 0, tmp_from_field, group != 0,
not_all_columns || group !=0); not_all_columns || group !=0,
param->convert_blob_length);
if (!new_field) if (!new_field)
{ {
if (thd->is_fatal_error) if (thd->is_fatal_error)
......
...@@ -1378,7 +1378,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, ...@@ -1378,7 +1378,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
field=item->tmp_table_field(&tmp_table); field=item->tmp_table_field(&tmp_table);
else else
field=create_tmp_field(thd, &tmp_table, item, item->type(), field=create_tmp_field(thd, &tmp_table, item, item->type(),
(Item ***) 0, &tmp_field,0,0); (Item ***) 0, &tmp_field, 0, 0, 0);
if (!field || if (!field ||
!(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ? !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
((Item_field *)item)->field : ((Item_field *)item)->field :
......
...@@ -3870,16 +3870,12 @@ select_var_ident: '@' ident_or_text ...@@ -3870,16 +3870,12 @@ select_var_ident: '@' ident_or_text
into: into:
INTO OUTFILE TEXT_STRING_sys INTO OUTFILE TEXT_STRING_sys
{ {
LEX *lex=Lex; LEX *lex= Lex;
if (!lex->describe)
{
lex->uncacheable(UNCACHEABLE_SIDEEFFECT); lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
if (!(lex->exchange= new sql_exchange($3.str,0))) if (!(lex->exchange= new sql_exchange($3.str, 0)) ||
YYABORT; !(lex->result= new select_export(lex->exchange)))
if (!(lex->result= new select_export(lex->exchange)))
YYABORT; YYABORT;
} }
}
opt_field_term opt_line_term opt_field_term opt_line_term
| INTO DUMPFILE TEXT_STRING_sys | INTO DUMPFILE TEXT_STRING_sys
{ {
...@@ -4721,15 +4717,28 @@ field_term_list: ...@@ -4721,15 +4717,28 @@ field_term_list:
| field_term; | field_term;
field_term: field_term:
TERMINATED BY text_string { Lex->exchange->field_term= $3;} TERMINATED BY text_string
{
DBUG_ASSERT(Lex->exchange);
Lex->exchange->field_term= $3;
}
| OPTIONALLY ENCLOSED BY text_string | OPTIONALLY ENCLOSED BY text_string
{ {
LEX *lex=Lex; LEX *lex= Lex;
DBUG_ASSERT(lex->exchange);
lex->exchange->enclosed= $4; lex->exchange->enclosed= $4;
lex->exchange->opt_enclosed=1; lex->exchange->opt_enclosed= 1;
} }
| ENCLOSED BY text_string { Lex->exchange->enclosed= $3;} | ENCLOSED BY text_string
| ESCAPED BY text_string { Lex->exchange->escaped= $3;}; {
DBUG_ASSERT(Lex->exchange);
Lex->exchange->enclosed= $3;
}
| ESCAPED BY text_string
{
DBUG_ASSERT(Lex->exchange);
Lex->exchange->escaped= $3;
};
opt_line_term: opt_line_term:
/* empty */ /* empty */
...@@ -4740,13 +4749,24 @@ line_term_list: ...@@ -4740,13 +4749,24 @@ line_term_list:
| line_term; | line_term;
line_term: line_term:
TERMINATED BY text_string { Lex->exchange->line_term= $3;} TERMINATED BY text_string
| STARTING BY text_string { Lex->exchange->line_start= $3;}; {
DBUG_ASSERT(Lex->exchange);
Lex->exchange->line_term= $3;
}
| STARTING BY text_string
{
DBUG_ASSERT(Lex->exchange);
Lex->exchange->line_start= $3;
};
opt_ignore_lines: opt_ignore_lines:
/* empty */ /* empty */
| IGNORE_SYM NUM LINES | IGNORE_SYM NUM LINES
{ Lex->exchange->skip_lines=atol($2.str); }; {
DBUG_ASSERT(Lex->exchange);
Lex->exchange->skip_lines= atol($2.str);
};
/* Common definitions */ /* Common definitions */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment