Commit dad54b7d authored by bk@mysql.r18.ru's avatar bk@mysql.r18.ru

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

into mysql.r18.ru:/usr/home/bk/mysql-4.1
parents 1e731c9a 5788c90d
...@@ -153,8 +153,8 @@ then ...@@ -153,8 +153,8 @@ then
then then
i_u="$i_u i_u="$i_u
INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
INSERT INTO user (host,user) values ('$hostname','');" INSERT INTO user (host,user) values ('$hostname','');
INSERT INTO user (host,user) values ('localhost',''); INSERT INTO user (host,user) values ('localhost','');"
else else
i_u="INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);" i_u="INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);"
fi fi
......
...@@ -183,44 +183,61 @@ CHARSET_INFO * Item::default_charset() const ...@@ -183,44 +183,61 @@ CHARSET_INFO * Item::default_charset() const
return current_thd->variables.collation_connection; return current_thd->variables.collation_connection;
} }
bool Item::set_charset(CHARSET_INFO *cs1, Derivation co1, bool DTCollation::aggregate(DTCollation &dt)
CHARSET_INFO *cs2, Derivation co2)
{ {
if (cs1 == &my_charset_bin || cs2 == &my_charset_bin) if (collation == &my_charset_bin || dt.collation == &my_charset_bin)
{ {
set_charset(&my_charset_bin, DERIVATION_NONE); collation= &my_charset_bin;
derivation= derivation > dt.derivation ? derivation : dt.derivation;
return 0; return 0;
} }
if (!my_charset_same(cs1,cs2)) if (!my_charset_same(collation, dt.collation))
return 1; {
/*
if (co1 < co2) We do allow to use binary strings (like BLOBS)
together with character strings.
Binaries have more precedance
*/
if ((derivation <= dt.derivation) && (collation == &my_charset_bin))
{ {
set_charset(cs1, co1); // Do nothing
} }
else if (co2 < co1) else if ((dt.derivation <= derivation) && (dt.collation==&my_charset_bin))
{ {
set_charset(cs2, co2); set(dt);
} }
else // co2 == co1 else
{ {
if (cs1 != cs2) set(0, DERIVATION_NONE);
return 1;
}
}
else if (derivation < dt.derivation)
{ {
if (co1 == DERIVATION_EXPLICIT) // Do nothing
}
else if (dt.derivation < derivation)
{ {
return 1; set(dt);
}
else
{
if (collation == dt.collation)
{
// Do nothing
} }
else else
{ {
CHARSET_INFO *bin= get_charset_by_csname(cs1->csname, MY_CS_BINSORT,MYF(0)); if (derivation == DERIVATION_EXPLICIT)
if (!bin) {
set(0, DERIVATION_NONE);
return 1; return 1;
set_charset(bin, DERIVATION_NONE);
} }
CHARSET_INFO *bin= get_charset_by_csname(collation->csname,
MY_CS_BINSORT,MYF(0));
set(bin, DERIVATION_NONE);
} }
else
set_charset(cs2, co2);
} }
return 0; return 0;
} }
......
...@@ -52,10 +52,10 @@ public: ...@@ -52,10 +52,10 @@ public:
collation= collation_arg; collation= collation_arg;
derivation= derivation_arg; derivation= derivation_arg;
} }
void set(DTCollation *dt) void set(DTCollation &dt)
{ {
collation= dt->collation; collation= dt.collation;
derivation= dt->derivation; derivation= dt.derivation;
} }
void set(CHARSET_INFO *collation_arg, Derivation derivation_arg) void set(CHARSET_INFO *collation_arg, Derivation derivation_arg)
{ {
...@@ -66,7 +66,9 @@ public: ...@@ -66,7 +66,9 @@ public:
{ collation= collation_arg; } { collation= collation_arg; }
void set(Derivation derivation_arg) void set(Derivation derivation_arg)
{ derivation= derivation_arg; } { derivation= derivation_arg; }
bool aggregate(DTCollation *dt); bool aggregate(DTCollation &dt);
bool set(DTCollation &dt1, DTCollation &dt2)
{ set(dt1); return aggregate(dt2); }
const char *derivation_name() const const char *derivation_name() const
{ {
switch(derivation) switch(derivation)
...@@ -183,8 +185,6 @@ public: ...@@ -183,8 +185,6 @@ public:
collation.collation= collation_arg->collation; collation.collation= collation_arg->collation;
collation.derivation= collation_arg->derivation; collation.derivation= collation_arg->derivation;
} }
bool set_charset(CHARSET_INFO *cs1, Derivation dv1,
CHARSET_INFO *cs2, Derivation dv2);
bool binary() const bool binary() const
{ return charset()->state & MY_CS_BINSORT ? 1 : 0 ; } { return charset()->state & MY_CS_BINSORT ? 1 : 0 ; }
......
...@@ -96,72 +96,26 @@ static bool convert_constant_item(Field *field, Item **item) ...@@ -96,72 +96,26 @@ static bool convert_constant_item(Field *field, Item **item)
return 0; return 0;
} }
bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, Derivation co1,
CHARSET_INFO *cs2, Derivation co2)
{
if (cs1 == &my_charset_bin || cs2 == &my_charset_bin)
{
cmp_charset= &my_charset_bin;
//coercibility= co1 > co2 ? co1 : co2;
return 0;
}
if (!my_charset_same(cs1, cs2)) bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables,
{ Item ** ref)
/* {
We do allow to use BLOBS together with character strings if (Item_int_func::fix_fields(thd, tables, ref))
BLOBS have more precedance
*/
if ((co1 <= co2) && (cs1==&my_charset_bin))
{
cmp_charset= cs1;
//coercibility= co1;
}
else if ((co2 <= co1) && (cs2==&my_charset_bin))
{
cmp_charset= cs2;
//coercibility= co2;
}
else
{
cmp_charset= 0;
//coercibility= DERIVATION_NOCOLL;
return 1; return 1;
}
}
else if (co1 < co2)
{
cmp_charset= cs1;
//coercibility= co1;
}
else if (co2 < co1)
{
cmp_charset= cs2;
//coercibility= co1;
}
else
{
if (cs1 == cs2)
{
cmp_charset= cs1;
//coercibility= co1;
}
else
{
//coercibility= DERIVATION_NOCOLL;
cmp_charset= 0;
return (co1 == DERIVATION_EXPLICIT) ? 1 : 0;
}
}
return 0; return 0;
} }
bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, void Item_bool_func2::fix_length_and_dec()
Item ** ref)
{ {
if (Item_int_func::fix_fields(thd, tables, ref)) max_length= 1; // Function returns 0 or 1
return 1;
/*
As some compare functions are generated after sql_yacc,
we have to check for out of memory conditions here
*/
if (!args[0] || !args[1])
return;
/* /*
We allow to convert to Unicode character sets in some cases. We allow to convert to Unicode character sets in some cases.
...@@ -209,34 +163,11 @@ bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, ...@@ -209,34 +163,11 @@ bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables,
else else
{ {
conv= new Item_func_conv_charset(args[weak],args[strong]->charset()); conv= new Item_func_conv_charset(args[weak],args[strong]->charset());
//conv->coercibility= args[weak]->derivation(); conv->collation.set(args[weak]->derivation());
} }
args[weak]= conv ? conv : args[weak]; args[weak]= conv ? conv : args[weak];
set_cmp_charset(args[0]->charset(), args[0]->derivation(),
args[1]->charset(), args[1]->derivation());
} }
} }
if (!cmp_charset)
{
/* set_cmp_charset() failed */
my_coll_agg_error(args[0]->collation, args[1]->collation, func_name());
return 1;
}
return 0;
}
void Item_bool_func2::fix_length_and_dec()
{
max_length= 1; // Function returns 0 or 1
/*
As some compare functions are generated after sql_yacc,
we have to check for out of memory conditions here
*/
if (!args[0] || !args[1])
return;
// Make a special case of compare with fields to get nicer DATE comparisons // Make a special case of compare with fields to get nicer DATE comparisons
if (args[0]->type() == FIELD_ITEM) if (args[0]->type() == FIELD_ITEM)
...@@ -248,7 +179,8 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -248,7 +179,8 @@ void Item_bool_func2::fix_length_and_dec()
{ {
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types. INT_RESULT); // Works for all types.
cmp_charset= &my_charset_bin; // For test in fix_fields cmp_collation.set(&my_charset_bin,
DERIVATION_NONE); // For test in fix_fields
return; return;
} }
} }
...@@ -262,7 +194,8 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -262,7 +194,8 @@ void Item_bool_func2::fix_length_and_dec()
{ {
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types. INT_RESULT); // Works for all types.
cmp_charset= &my_charset_bin; // For test in fix_fields cmp_collation.set(&my_charset_bin,
DERIVATION_NONE); // For test in fix_fields
return; return;
} }
} }
...@@ -272,8 +205,12 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -272,8 +205,12 @@ void Item_bool_func2::fix_length_and_dec()
We must set cmp_charset here as we may be called from for an automatic We must set cmp_charset here as we may be called from for an automatic
generated item, like in natural join generated item, like in natural join
*/ */
set_cmp_charset(args[0]->charset(), args[0]->derivation(), if (cmp_collation.set(args[0]->collation, args[1]->collation))
args[1]->charset(), args[1]->derivation()); {
/* set_cmp_charset() failed */
my_coll_agg_error(args[0]->collation, args[1]->collation, func_name());
return;
}
} }
...@@ -315,7 +252,7 @@ int Arg_comparator::compare_string() ...@@ -315,7 +252,7 @@ int Arg_comparator::compare_string()
if ((res2= (*b)->val_str(&owner->tmp_value2))) if ((res2= (*b)->val_str(&owner->tmp_value2)))
{ {
owner->null_value= 0; owner->null_value= 0;
return sortcmp(res1,res2,owner->cmp_charset); return sortcmp(res1,res2,owner->cmp_collation.collation);
} }
} }
owner->null_value= 1; owner->null_value= 1;
...@@ -329,7 +266,7 @@ int Arg_comparator::compare_e_string() ...@@ -329,7 +266,7 @@ int Arg_comparator::compare_e_string()
res2= (*b)->val_str(&owner->tmp_value2); res2= (*b)->val_str(&owner->tmp_value2);
if (!res1 || !res2) if (!res1 || !res2)
return test(res1 == res2); return test(res1 == res2);
return test(sortcmp(res1, res2, owner->cmp_charset) == 0); return test(sortcmp(res1, res2, owner->cmp_collation.collation) == 0);
} }
...@@ -558,7 +495,7 @@ longlong Item_func_strcmp::val_int() ...@@ -558,7 +495,7 @@ longlong Item_func_strcmp::val_int()
null_value=1; null_value=1;
return 0; return 0;
} }
int value= sortcmp(a,b,cmp_charset); int value= sortcmp(a,b,cmp_collation.collation);
null_value=0; null_value=0;
return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1); return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
} }
...@@ -750,8 +687,7 @@ Item_func_ifnull::fix_length_and_dec() ...@@ -750,8 +687,7 @@ Item_func_ifnull::fix_length_and_dec()
args[1]->result_type())) != args[1]->result_type())) !=
REAL_RESULT) REAL_RESULT)
decimals= 0; decimals= 0;
if (set_charset(args[0]->charset(),args[0]->derivation(), if (collation.set(args[0]->collation,args[1]->collation))
args[1]->charset(),args[1]->derivation()))
my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); my_coll_agg_error(args[0]->collation, args[1]->collation, func_name());
} }
...@@ -828,8 +764,7 @@ Item_func_if::fix_length_and_dec() ...@@ -828,8 +764,7 @@ Item_func_if::fix_length_and_dec()
else if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT) else if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT)
{ {
cached_result_type = STRING_RESULT; cached_result_type = STRING_RESULT;
if (set_charset(args[1]->charset(), args[1]->derivation(), if (collation.set(args[1]->collation, args[2]->collation))
args[2]->charset(), args[2]->derivation()))
{ {
my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); my_coll_agg_error(args[0]->collation, args[1]->collation, func_name());
return; return;
...@@ -1944,7 +1879,7 @@ longlong Item_func_like::val_int() ...@@ -1944,7 +1879,7 @@ longlong Item_func_like::val_int()
null_value=0; null_value=0;
if (canDoTurboBM) if (canDoTurboBM)
return turboBM_matches(res->ptr(), res->length()) ? 1 : 0; return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
return my_wildcmp(cmp_charset, return my_wildcmp(cmp_collation.collation,
res->ptr(),res->ptr()+res->length(), res->ptr(),res->ptr()+res->length(),
res2->ptr(),res2->ptr()+res2->length(), res2->ptr(),res2->ptr()+res2->length(),
escape,wild_one,wild_many) ? 0 : 1; escape,wild_one,wild_many) ? 0 : 1;
...@@ -2148,7 +2083,7 @@ void Item_func_like::turboBM_compute_suffixes(int *suff) ...@@ -2148,7 +2083,7 @@ void Item_func_like::turboBM_compute_suffixes(int *suff)
*splm1 = pattern_len; *splm1 = pattern_len;
if (cmp_charset == &my_charset_bin) if (cmp_collation.collation == &my_charset_bin)
{ {
int i; int i;
for (i = pattern_len - 2; i >= 0; i--) for (i = pattern_len - 2; i >= 0; i--)
...@@ -2251,7 +2186,7 @@ void Item_func_like::turboBM_compute_bad_character_shifts() ...@@ -2251,7 +2186,7 @@ void Item_func_like::turboBM_compute_bad_character_shifts()
for (i = bmBc; i < end; i++) for (i = bmBc; i < end; i++)
*i = pattern_len; *i = pattern_len;
if (cmp_charset == &my_charset_bin) if (cmp_collation.collation == &my_charset_bin)
{ {
for (j = 0; j < plm1; j++) for (j = 0; j < plm1; j++)
bmBc[(uint) (uchar) pattern[j]] = plm1 - j; bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
...@@ -2282,7 +2217,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const ...@@ -2282,7 +2217,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
const int tlmpl= text_len - pattern_len; const int tlmpl= text_len - pattern_len;
/* Searching */ /* Searching */
if (cmp_charset == &my_charset_bin) if (cmp_collation.collation == &my_charset_bin)
{ {
while (j <= tlmpl) while (j <= tlmpl)
{ {
......
...@@ -112,25 +112,25 @@ class Item_bool_func2 :public Item_int_func ...@@ -112,25 +112,25 @@ class Item_bool_func2 :public Item_int_func
protected: protected:
Arg_comparator cmp; Arg_comparator cmp;
String tmp_value1,tmp_value2; String tmp_value1,tmp_value2;
CHARSET_INFO *cmp_charset; DTCollation cmp_collation;
public: public:
Item_bool_func2(Item *a,Item *b): Item_bool_func2(Item *a,Item *b):
Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), cmp_charset(0) {} Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1)
{ cmp_collation.set(0,DERIVATION_NONE);}
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref); bool fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref);
void fix_length_and_dec(); void fix_length_and_dec();
void set_cmp_func() void set_cmp_func()
{ {
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1); cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
} }
bool set_cmp_charset(CHARSET_INFO *cs1, Derivation co1,
CHARSET_INFO *cs2, Derivation co2);
optimize_type select_optimize() const { return OPTIMIZE_OP; } optimize_type select_optimize() const { return OPTIMIZE_OP; }
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; } virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
void print(String *str) { Item_func::print_op(str); } void print(String *str) { Item_func::print_op(str); }
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); } bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
virtual bool binary() const { return test(cmp_charset->state & MY_CS_BINSORT); } virtual bool binary() const
{ return test(cmp_collation.collation->state & MY_CS_BINSORT); }
static Item_bool_func2* eq_creator(Item *a, Item *b); static Item_bool_func2* eq_creator(Item *a, Item *b);
static Item_bool_func2* ne_creator(Item *a, Item *b); static Item_bool_func2* ne_creator(Item *a, Item *b);
......
...@@ -867,9 +867,8 @@ void Item_func_min_max::fix_length_and_dec() ...@@ -867,9 +867,8 @@ void Item_func_min_max::fix_length_and_dec()
maybe_null=0; maybe_null=0;
cmp_type=item_cmp_type(cmp_type,args[i]->result_type()); cmp_type=item_cmp_type(cmp_type,args[i]->result_type());
if (i==0) if (i==0)
set_charset(*args[i]); collation.set(args[0]->collation);
else if (set_charset(charset(), derivation(), if (collation.aggregate(args[i]->collation))
args[i]->charset(), args[i]->derivation()))
{ {
my_coll_agg_error(collation, args[i]->collation, func_name()); my_coll_agg_error(collation, args[i]->collation, func_name());
break; break;
......
...@@ -324,12 +324,11 @@ void Item_func_concat::fix_length_and_dec() ...@@ -324,12 +324,11 @@ void Item_func_concat::fix_length_and_dec()
bool first_coll= 1; bool first_coll= 1;
max_length=0; max_length=0;
set_charset(*args[0]); collation.set(args[0]->collation);
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{ {
max_length+=args[i]->max_length; max_length+=args[i]->max_length;
if (set_charset(charset(), derivation(), if (collation.aggregate(args[i]->collation))
args[i]->charset(), args[i]->derivation()))
{ {
my_coll_agg_error(collation, args[i]->collation, func_name()); my_coll_agg_error(collation, args[i]->collation, func_name());
break; break;
...@@ -627,13 +626,12 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array, ...@@ -627,13 +626,12 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array,
void Item_func_concat_ws::fix_length_and_dec() void Item_func_concat_ws::fix_length_and_dec()
{ {
set_charset(*separator); collation.set(separator->collation);
max_length=separator->max_length*(arg_count-1); max_length=separator->max_length*(arg_count-1);
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{ {
max_length+=args[i]->max_length; max_length+=args[i]->max_length;
if (set_charset(charset(), derivation(), if (collation.aggregate(args[i]->collation))
args[i]->charset(), args[i]->derivation()))
{ {
my_coll_agg_error(collation, args[i]->collation, func_name()); my_coll_agg_error(collation, args[i]->collation, func_name());
break; break;
...@@ -828,12 +826,11 @@ void Item_func_replace::fix_length_and_dec() ...@@ -828,12 +826,11 @@ void Item_func_replace::fix_length_and_dec()
max_length=MAX_BLOB_WIDTH; max_length=MAX_BLOB_WIDTH;
maybe_null=1; maybe_null=1;
} }
set_charset(*args[0]);
collation.set(args[0]->collation);
for (i=1; i<3; i++) for (i=1; i<3; i++)
{ {
if (set_charset(charset(), derivation(), if (collation.aggregate(args[i]->collation))
args[i]->charset(), args[i]->derivation()))
{ {
my_coll_agg_error(collation, args[i]->collation, func_name()); my_coll_agg_error(collation, args[i]->collation, func_name());
break; break;
...@@ -875,10 +872,10 @@ null: ...@@ -875,10 +872,10 @@ null:
void Item_func_insert::fix_length_and_dec() void Item_func_insert::fix_length_and_dec()
{ {
if (set_charset(args[0]->charset(), args[0]->derivation(), if (collation.set(args[0]->collation, args[3]->collation))
args[3]->charset(), args[3]->derivation()))
{ {
my_coll_agg_error(args[0]->collation, args[3]->collation, func_name()); my_coll_agg_error(args[0]->collation, args[3]->collation, func_name());
return;
} }
max_length=args[0]->max_length+args[3]->max_length; max_length=args[0]->max_length+args[3]->max_length;
if (max_length > MAX_BLOB_WIDTH) if (max_length > MAX_BLOB_WIDTH)
...@@ -1316,13 +1313,12 @@ void Item_func_trim::fix_length_and_dec() ...@@ -1316,13 +1313,12 @@ void Item_func_trim::fix_length_and_dec()
max_length= args[0]->max_length; max_length= args[0]->max_length;
if (arg_count == 1) if (arg_count == 1)
{ {
set_charset(*args[0]); collation.set(args[0]->collation);
remove.set_charset(charset()); remove.set_charset(charset());
remove.set_ascii(" ",1); remove.set_ascii(" ",1);
} }
else else
if (set_charset(args[1]->charset(), args[1]->derivation(), if (collation.set(args[1]->collation, args[0]->collation))
args[0]->charset(), args[0]->derivation()))
{ {
my_coll_agg_error(args[1]->collation, args[0]->collation, func_name()); my_coll_agg_error(args[1]->collation, args[0]->collation, func_name());
} }
...@@ -1668,11 +1664,10 @@ void Item_func_elt::fix_length_and_dec() ...@@ -1668,11 +1664,10 @@ void Item_func_elt::fix_length_and_dec()
set_if_bigger(max_length,args[i]->max_length); set_if_bigger(max_length,args[i]->max_length);
set_if_bigger(decimals,args[i]->decimals); set_if_bigger(decimals,args[i]->decimals);
if (i == 0) if (i == 0)
set_charset(*args[0]); collation.set(args[0]->collation);
else else
{ {
if (set_charset(charset(), derivation(), if (collation.aggregate(args[i]->collation))
args[i]->charset(), args[i]->derivation()))
{ {
my_coll_agg_error(collation, args[i]->collation, func_name()); my_coll_agg_error(collation, args[i]->collation, func_name());
break; break;
...@@ -1770,12 +1765,11 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array, ...@@ -1770,12 +1765,11 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array,
void Item_func_make_set::fix_length_and_dec() void Item_func_make_set::fix_length_and_dec()
{ {
max_length=arg_count-1; max_length=arg_count-1;
set_charset(*args[0]); collation.set(args[0]->collation);
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{ {
max_length+=args[i]->max_length; max_length+=args[i]->max_length;
if (set_charset(charset(), derivation(), if (collation.aggregate(args[i]->collation))
args[i]->charset(), args[i]->derivation()))
{ {
my_coll_agg_error(collation, args[i]->collation, func_name()); my_coll_agg_error(collation, args[i]->collation, func_name());
break; break;
...@@ -1963,10 +1957,10 @@ err: ...@@ -1963,10 +1957,10 @@ err:
void Item_func_rpad::fix_length_and_dec() void Item_func_rpad::fix_length_and_dec()
{ {
if (set_charset(args[0]->charset(), args[0]->derivation(), if (collation.set(args[0]->collation, args[2]->collation))
args[2]->charset(), args[2]->derivation()))
{ {
my_coll_agg_error(args[0]->collation, args[2]->collation, func_name()); my_coll_agg_error(args[0]->collation, args[2]->collation, func_name());
return;
} }
if (args[1]->const_item()) if (args[1]->const_item())
...@@ -2029,10 +2023,10 @@ String *Item_func_rpad::val_str(String *str) ...@@ -2029,10 +2023,10 @@ String *Item_func_rpad::val_str(String *str)
void Item_func_lpad::fix_length_and_dec() void Item_func_lpad::fix_length_and_dec()
{ {
if (set_charset(args[0]->charset(), args[0]->derivation(), if (collation.set(args[0]->collation, args[2]->collation))
args[2]->charset(), args[2]->derivation()))
{ {
my_coll_agg_error(args[0]->collation, args[2]->collation, func_name()); my_coll_agg_error(args[0]->collation, args[2]->collation, func_name());
return;
} }
if (args[1]->const_item()) if (args[1]->const_item())
...@@ -2152,9 +2146,8 @@ String *Item_func_conv_charset::val_str(String *str) ...@@ -2152,9 +2146,8 @@ String *Item_func_conv_charset::val_str(String *str)
void Item_func_conv_charset::fix_length_and_dec() void Item_func_conv_charset::fix_length_and_dec()
{ {
set_charset(conv_charset);
max_length = args[0]->max_length*conv_charset->mbmaxlen;
set_charset(conv_charset, DERIVATION_IMPLICIT); set_charset(conv_charset, DERIVATION_IMPLICIT);
max_length = args[0]->max_length*conv_charset->mbmaxlen;
} }
...@@ -2449,11 +2442,10 @@ void Item_func_export_set::fix_length_and_dec() ...@@ -2449,11 +2442,10 @@ void Item_func_export_set::fix_length_and_dec()
uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
max_length=length*64+sep_length*63; max_length=length*64+sep_length*63;
set_charset(*args[1]); collation.set(args[1]->collation);
for (i=2 ; i < 4 && i < arg_count ; i++) for (i=2 ; i < 4 && i < arg_count ; i++)
{ {
if (set_charset(charset(), derivation(), if (collation.aggregate(args[i]->collation))
args[i]->charset(), args[i]->derivation()))
{ {
my_coll_agg_error(collation, args[i]->collation, func_name()); my_coll_agg_error(collation, args[i]->collation, func_name());
break; break;
......
...@@ -7327,6 +7327,136 @@ static void test_free_store_result() ...@@ -7327,6 +7327,136 @@ static void test_free_store_result()
mysql_stmt_close(stmt); mysql_stmt_close(stmt);
} }
/********************************************************
To test SQLmode
*********************************************************/
static void test_sqlmode()
{
MYSQL_STMT *stmt;
MYSQL_BIND bind[2];
char c1[5], c2[5];
int rc;
myheader("test_sqlmode");
rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_piping");
myquery(rc);
rc = mysql_commit(mysql);
myquery(rc);
rc = mysql_query(mysql,"CREATE TABLE test_piping(name varchar(10))");
myquery(rc);
/* PIPES_AS_CONCAT */
strcpy(query,"SET SQL_MODE=\"PIPES_AS_CONCAT\"");
fprintf(stdout,"\n With %s", query);
rc = mysql_query(mysql,query);
myquery(rc);
strcpy(query, "INSERT INTO test_piping VALUES(?||?)");
fprintf(stdout,"\n query: %s", query);
stmt = mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt);
fprintf(stdout,"\n total parameters: %ld", mysql_param_count(stmt));
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].buffer= (char *)c1;
bind[0].buffer_length= 2;
bind[0].is_null= 0;
bind[0].length= 0;
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (char *)c2;
bind[1].buffer_length= 3;
bind[1].is_null= 0;
bind[1].length= 0;
rc = mysql_bind_param(stmt, bind);
mystmt(stmt,rc);
strcpy(c1,"My"); strcpy(c2, "SQL");
rc = mysql_execute(stmt);
mystmt(stmt,rc);
mysql_stmt_close(stmt);
verify_col_data("test_piping","name","MySQL");
rc = mysql_query(mysql,"DELETE FROM test_piping");
myquery(rc);
strcpy(query, "SELECT connection_id ()");
fprintf(stdout,"\n query: %s", query);
stmt = mysql_prepare(mysql, query, 70);
mystmt_init_r(stmt);
/* ANSI */
strcpy(query,"SET SQL_MODE=\"ANSI\"");
fprintf(stdout,"\n With %s", query);
rc = mysql_query(mysql,query);
myquery(rc);
strcpy(query, "INSERT INTO test_piping VALUES(?||?)");
fprintf(stdout,"\n query: %s", query);
stmt = mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt);
fprintf(stdout,"\n total parameters: %ld", mysql_param_count(stmt));
rc = mysql_bind_param(stmt, bind);
mystmt(stmt,rc);
strcpy(c1,"My"); strcpy(c2, "SQL");
rc = mysql_execute(stmt);
mystmt(stmt,rc);
mysql_stmt_close(stmt);
verify_col_data("test_piping","name","MySQL");
/* ANSI mode spaces ... */
strcpy(query, "SELECT connection_id ()");
fprintf(stdout,"\n query: %s", query);
stmt = mysql_prepare(mysql, query, 70);
mystmt_init(stmt);
rc = mysql_execute(stmt);
mystmt(stmt,rc);
rc = mysql_fetch(stmt);
mystmt(stmt,rc);
rc = mysql_fetch(stmt);
myassert(rc == MYSQL_NO_DATA);
fprintf(stdout,"\n returned 1 row\n");
mysql_stmt_close(stmt);
/* IGNORE SPACE MODE */
strcpy(query,"SET SQL_MODE=\"IGNORE_SPACE\"");
fprintf(stdout,"\n With %s", query);
rc = mysql_query(mysql,query);
myquery(rc);
strcpy(query, "SELECT connection_id ()");
fprintf(stdout,"\n query: %s", query);
stmt = mysql_prepare(mysql, query, 70);
mystmt_init(stmt);
rc = mysql_execute(stmt);
mystmt(stmt,rc);
rc = mysql_fetch(stmt);
mystmt(stmt,rc);
rc = mysql_fetch(stmt);
myassert(rc == MYSQL_NO_DATA);
fprintf(stdout,"\n returned 1 row");
mysql_stmt_close(stmt);
}
/* /*
Read and parse arguments and MySQL options from my.cnf Read and parse arguments and MySQL options from my.cnf
*/ */
...@@ -7467,10 +7597,6 @@ int main(int argc, char **argv) ...@@ -7467,10 +7597,6 @@ int main(int argc, char **argv)
start_time= time((time_t *)0); start_time= time((time_t *)0);
client_query(); /* simple client query test */ client_query(); /* simple client query test */
test_mem_overun();
test_list_fields();
test_fetch_offset(); /* to test mysql_fetch_column with offset */
test_fetch_column(); /* to test mysql_fetch_column */
#if NOT_YET_WORKING #if NOT_YET_WORKING
/* Used for internal new development debugging */ /* Used for internal new development debugging */
test_drop_temp(); /* to test DROP TEMPORARY TABLE Access checks */ test_drop_temp(); /* to test DROP TEMPORARY TABLE Access checks */
...@@ -7572,6 +7698,11 @@ int main(int argc, char **argv) ...@@ -7572,6 +7698,11 @@ int main(int argc, char **argv)
test_free_result(); /* test mysql_stmt_free_result() */ test_free_result(); /* test mysql_stmt_free_result() */
test_free_store_result(); /* test to make sure stmt results are cleared test_free_store_result(); /* test to make sure stmt results are cleared
during stmt_free_result() */ during stmt_free_result() */
test_mem_overun(); /* memory ovverun bug */
test_list_fields(); /* list_fields test */
test_fetch_offset(); /* to test mysql_fetch_column with offset */
test_fetch_column(); /* to test mysql_fetch_column */
test_sqlmode(); /* test for SQL_MODE */
end_time= time((time_t *)0); end_time= time((time_t *)0);
total_time+= difftime(end_time, start_time); total_time+= difftime(end_time, start_time);
......
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