Commit 7a9f4775 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

basic row Items (SCRUM)

parent 76ed2fc4
...@@ -241,7 +241,7 @@ struct rand_struct { ...@@ -241,7 +241,7 @@ struct rand_struct {
/* The following is for user defined functions */ /* The following is for user defined functions */
enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT}; enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};
typedef struct st_udf_args typedef struct st_udf_args
{ {
......
...@@ -255,7 +255,7 @@ ...@@ -255,7 +255,7 @@
#define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236 #define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236
#define ER_WRONG_FK_DEF 1237 #define ER_WRONG_FK_DEF 1237
#define ER_KEY_REF_DO_NOT_MATCH_TABLE_REF 1238 #define ER_KEY_REF_DO_NOT_MATCH_TABLE_REF 1238
#define ER_SUBSELECT_NO_1_COL 1239 #define ER_CARDINALITY_COL 1239
#define ER_SUBSELECT_NO_1_ROW 1240 #define ER_SUBSELECT_NO_1_ROW 1240
#define ER_UNKNOWN_STMT_HANDLER 1241 #define ER_UNKNOWN_STMT_HANDLER 1241
#define ER_CORRUPT_HELP_DB 1242 #define ER_CORRUPT_HELP_DB 1242
......
...@@ -43,7 +43,7 @@ sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \ ...@@ -43,7 +43,7 @@ sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \
hostname.cc init.cc \ hostname.cc init.cc \
item.cc item_buff.cc item_cmpfunc.cc item_create.cc \ item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \ item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
item_uniq.cc item_subselect.cc \ item_uniq.cc item_subselect.cc item_row.cc\
key.cc lock.cc log.cc log_event.cc mf_iocache.cc\ key.cc lock.cc log.cc log_event.cc mf_iocache.cc\
mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \ mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \
opt_sum.cc procedure.cc records.cc sql_acl.cc \ opt_sum.cc procedure.cc records.cc sql_acl.cc \
......
SELECT (1,2,3)=(1,2,3);
(1,2,3)=(1,2,3)
1
SELECT (2,2,3)=(1+1,2,3);
(2,2,3)=(1+1,2,3)
1
SELECT (1,2,3)=(1+1,2,3);
(1,2,3)=(1+1,2,3)
0
SELECT (1,2,3)<(1+1,2,3);
(1,2,3)<(1+1,2,3)
1
SELECT (1,2,3)>(1+1,2,3);
(1,2,3)>(1+1,2,3)
0
SELECT (1,2,3)<=(1+1,2,3);
(1,2,3)<=(1+1,2,3)
1
SELECT (1,2,3)>=(1+1,2,3);
(1,2,3)>=(1+1,2,3)
0
SELECT (1,2,3)<>(1+1,2,3);
(1,2,3)<>(1+1,2,3)
1
SELECT (1,2,(3,4,5))=(1,2,(3,4,5));
(1,2,(3,4,5))=(1,2,(3,4,5))
1
SELECT ('test',2,3.33)=('test',2,3.33);
('test',2,3.33)=('test',2,3.33)
1
SELECT ('test',2,3.33)=('test',2,3.33,4);
Cardinality error (more/less than 4 columns)
drop table if exists t1;
create table t1 ( a int, b int, c int);
insert into t1 values (1,2,3), (2,3,1), (3,2,1);
select * from t1 where (1,2,3)=(a,b,c);
a b c
1 2 3
select * from t1 where (0,2,3)=(a,b,c);
a b c
select * from t1 where (1,2,3)<(a,b,c);
a b c
2 3 1
3 2 1
drop table t1;
...@@ -178,10 +178,10 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -178,10 +178,10 @@ id select_type table type possible_keys key key_len ref rows Extra
3 SUBSELECT inscrit const PRIMARY PRIMARY 35 const 1 3 SUBSELECT inscrit const PRIMARY PRIMARY 35 const 1
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo,email FROM SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo,email FROM
inscrit WHERE pseudo='joce'); inscrit WHERE pseudo='joce');
Subselect returns more than 1 field Cardinality error (more/less than 1 columns)
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT * FROM inscrit WHERE SELECT pseudo FROM inscrit WHERE pseudo=(SELECT * FROM inscrit WHERE
pseudo='joce'); pseudo='joce');
Subselect returns more than 1 field Cardinality error (more/less than 1 columns)
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce'); SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce');
pseudo pseudo
joce joce
......
SELECT (1,2,3)=(1,2,3);
SELECT (2,2,3)=(1+1,2,3);
SELECT (1,2,3)=(1+1,2,3);
SELECT (1,2,3)<(1+1,2,3);
SELECT (1,2,3)>(1+1,2,3);
SELECT (1,2,3)<=(1+1,2,3);
SELECT (1,2,3)>=(1+1,2,3);
SELECT (1,2,3)<>(1+1,2,3);
SELECT (1,2,(3,4,5))=(1,2,(3,4,5));
SELECT ('test',2,3.33)=('test',2,3.33);
-- error 1239
SELECT ('test',2,3.33)=('test',2,3.33,4);
drop table if exists t1;
create table t1 ( a int, b int, c int);
insert into t1 values (1,2,3), (2,3,1), (3,2,1);
select * from t1 where (1,2,3)=(a,b,c);
select * from t1 where (0,2,3)=(a,b,c);
select * from t1 where (1,2,3)<(a,b,c);
drop table t1;
\ No newline at end of file
...@@ -46,7 +46,8 @@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ ...@@ -46,7 +46,8 @@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h item_uniq.h \ item_strfunc.h item_timefunc.h item_uniq.h \
item_create.h item_subselect.h mysql_priv.h \ item_create.h item_subselect.h item_row.h \
mysql_priv.h \
procedure.h sql_class.h sql_lex.h sql_list.h \ procedure.h sql_class.h sql_lex.h sql_list.h \
sql_manager.h sql_map.h sql_string.h unireg.h \ sql_manager.h sql_map.h sql_string.h unireg.h \
field.h handler.h \ field.h handler.h \
...@@ -61,7 +62,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ ...@@ -61,7 +62,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
mysqld_SOURCES = sql_lex.cc sql_handler.cc \ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \
item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
thr_malloc.cc item_create.cc item_subselect.cc\ thr_malloc.cc item_create.cc item_subselect.cc \
item_row.cc \
field.cc key.cc sql_class.cc sql_list.cc \ field.cc key.cc sql_class.cc sql_list.cc \
net_serv.cc net_pkg.cc lock.cc my_lock.c \ net_serv.cc net_pkg.cc lock.cc my_lock.c \
sql_string.cc sql_manager.cc sql_map.cc \ sql_string.cc sql_manager.cc sql_map.cc \
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#endif #endif
#include <m_ctype.h> #include <m_ctype.h>
#include "sql_sort.h" #include "sql_sort.h"
#include "assert.h"
#ifndef THREAD #ifndef THREAD
#define SKIP_DBUG_IN_FILESORT #define SKIP_DBUG_IN_FILESORT
...@@ -579,6 +580,10 @@ static void make_sortkey(register SORTPARAM *param, ...@@ -579,6 +580,10 @@ static void make_sortkey(register SORTPARAM *param,
change_double_for_sort(value,(byte*) to); change_double_for_sort(value,(byte*) to);
break; break;
} }
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
} }
if (sort_field->reverse) if (sort_field->reverse)
...@@ -965,6 +970,9 @@ sortlength(SORT_FIELD *sortorder, uint s_length) ...@@ -965,6 +970,9 @@ sortlength(SORT_FIELD *sortorder, uint s_length)
case REAL_RESULT: case REAL_RESULT:
sortorder->length=sizeof(double); sortorder->length=sizeof(double);
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
} }
if (sortorder->item->maybe_null) if (sortorder->item->maybe_null)
length++; // Place for NULL marker length++; // Place for NULL marker
......
...@@ -58,6 +58,16 @@ bool Item::check_loop(uint id) ...@@ -58,6 +58,16 @@ bool Item::check_loop(uint id)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
bool Item::check_cols(uint c)
{
if (c != 1)
{
my_error(ER_CARDINALITY_COL, MYF(0), 1);
return 1;
}
return 0;
}
void Item::set_name(const char *str,uint length) void Item::set_name(const char *str,uint length)
{ {
if (!length) if (!length)
...@@ -885,6 +895,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -885,6 +895,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
maybe_null= (*ref)->maybe_null; maybe_null= (*ref)->maybe_null;
decimals= (*ref)->decimals; decimals= (*ref)->decimals;
} }
if (ref && (*ref)->check_cols(1))
return 1;
return 0; return 0;
} }
...@@ -907,6 +919,8 @@ Item_result item_cmp_type(Item_result a,Item_result b) ...@@ -907,6 +919,8 @@ Item_result item_cmp_type(Item_result a,Item_result b)
return STRING_RESULT; return STRING_RESULT;
else if (a == INT_RESULT && b == INT_RESULT) else if (a == INT_RESULT && b == INT_RESULT)
return INT_RESULT; return INT_RESULT;
else if (a == ROW_RESULT || b == ROW_RESULT)
return ROW_RESULT;
else else
return REAL_RESULT; return REAL_RESULT;
} }
......
...@@ -34,7 +34,7 @@ class Item { ...@@ -34,7 +34,7 @@ class Item {
INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM, INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM,
COPY_STR_ITEM,FIELD_AVG_ITEM, DEFAULT_ITEM, COPY_STR_ITEM,FIELD_AVG_ITEM, DEFAULT_ITEM,
PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM, PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM,
SUBSELECT_ITEM}; SUBSELECT_ITEM, ROW_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
String str_value; /* used to store value */ String str_value; /* used to store value */
...@@ -87,10 +87,18 @@ class Item { ...@@ -87,10 +87,18 @@ class Item {
virtual bool is_null() { return 0; }; virtual bool is_null() { return 0; };
virtual CHARSET_INFO *thd_charset() const; virtual CHARSET_INFO *thd_charset() const;
virtual CHARSET_INFO *charset() const { return str_value.charset(); }; virtual CHARSET_INFO *charset() const { return str_value.charset(); };
virtual bool binary() const { return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; } virtual bool binary() const
{
return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0;
}
virtual void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); } virtual void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); }
virtual bool check_loop(uint id); virtual bool check_loop(uint id);
// Row emulation
virtual uint cols() { return 1; }
virtual Item* el(uint i) { return this; }
virtual bool check_cols(uint c);
}; };
...@@ -469,6 +477,7 @@ class Item_int_with_ref :public Item_int ...@@ -469,6 +477,7 @@ class Item_int_with_ref :public Item_int
#include "item_timefunc.h" #include "item_timefunc.h"
#include "item_uniq.h" #include "item_uniq.h"
#include "item_subselect.h" #include "item_subselect.h"
#include "item_row.h"
class Item_copy_string :public Item class Item_copy_string :public Item
{ {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include <m_ctype.h> #include <m_ctype.h>
#include "assert.h"
/* /*
Test functions Test functions
...@@ -83,7 +83,7 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -83,7 +83,7 @@ void Item_bool_func2::fix_length_and_dec()
{ {
if (convert_constant_item(field,&args[1])) if (convert_constant_item(field,&args[1]))
{ {
cmp_func= &Item_bool_func2::compare_int; // Works for all types. cmp_func= new Compare_func_int(this); // Works for all types.
return; return;
} }
} }
...@@ -95,88 +95,115 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -95,88 +95,115 @@ void Item_bool_func2::fix_length_and_dec()
{ {
if (convert_constant_item(field,&args[0])) if (convert_constant_item(field,&args[0]))
{ {
cmp_func= &Item_bool_func2::compare_int; // Works for all types. cmp_func= new Compare_func_int(this); // Works for all types.
return; return;
} }
} }
} }
set_cmp_func(item_cmp_type(args[0]->result_type(),args[1]->result_type())); set_cmp_func(args[0], args[1]);
} }
Compare_func* Compare_func::get_compare_func(Item_bool_func2 *owner,
void Item_bool_func2::set_cmp_func(Item_result type) Item *a, Item* b)
{ {
switch (type) { switch (item_cmp_type(a->result_type(), b->result_type()))
{
case STRING_RESULT: case STRING_RESULT:
cmp_func=&Item_bool_func2::compare_string; return new Compare_func_string(owner);
break;
case REAL_RESULT: case REAL_RESULT:
cmp_func=&Item_bool_func2::compare_real; return new Compare_func_real(owner);
break;
case INT_RESULT: case INT_RESULT:
cmp_func=&Item_bool_func2::compare_int; return new Compare_func_int(owner);
break; case ROW_RESULT:
return new Compare_func_row(owner, a, b);
} }
return 0;
} }
Compare_func_row::Compare_func_row(Item_bool_func2 *owner, Item *a, Item* b):
Compare_func(owner)
{
uint n= a->cols();
if (n != b->cols())
{
my_error(ER_CARDINALITY_COL, MYF(0), n);
cmp_func= 0;
return;
}
cmp_func= (Compare_func **) sql_alloc(sizeof(Compare_func*)*n);
for(uint i=0; i < n; i++)
cmp_func[i]= Compare_func::get_compare_func(owner, a->el(i), b->el(i));
}
int Item_bool_func2::compare_string() int Compare_func_string::compare(Item *a, Item *b)
{ {
String *res1,*res2; String *res1,*res2;
if ((res1=args[0]->val_str(&tmp_value1))) if ((res1= a->val_str(&owner->tmp_value1)))
{ {
if ((res2=args[1]->val_str(&tmp_value2))) if ((res2= b->val_str(&owner->tmp_value2)))
{ {
null_value=0; owner->null_value= 0;
return binary() ? stringcmp(res1,res2) : sortcmp(res1,res2); return owner->binary() ? stringcmp(res1,res2) : sortcmp(res1,res2);
} }
} }
null_value=1; owner->null_value= 1;
return -1; return -1;
} }
int Item_bool_func2::compare_real() int Compare_func_real::compare(Item *a, Item *b)
{ {
double val1=args[0]->val(); double val1= a->val();
if (!args[0]->null_value) if (!a->null_value)
{ {
double val2=args[1]->val(); double val2= b->val();
if (!args[1]->null_value) if (!b->null_value)
{ {
null_value=0; owner->null_value= 0;
if (val1 < val2) return -1; if (val1 < val2) return -1;
if (val1 == val2) return 0; if (val1 == val2) return 0;
return 1; return 1;
} }
} }
null_value=1; owner->null_value= 1;
return -1; return -1;
} }
int Item_bool_func2::compare_int() int Compare_func_int::compare(Item *a, Item *b)
{ {
longlong val1=args[0]->val_int(); longlong val1= a->val_int();
if (!args[0]->null_value) if (!a->null_value)
{ {
longlong val2=args[1]->val_int(); longlong val2= b->val_int();
if (!args[1]->null_value) if (!b->null_value)
{ {
null_value=0; owner->null_value= 0;
if (val1 < val2) return -1; if (val1 < val2) return -1;
if (val1 == val2) return 0; if (val1 == val2) return 0;
return 1; return 1;
} }
} }
null_value=1; owner->null_value= 1;
return -1; return -1;
} }
int Compare_func_row::compare(Item *a, Item *b)
{
int res= 0;
uint n= a->cols();
for(uint i= 0; i<n; i++)
{
if ((res= cmp_func[i]->compare(a->el(i), b->el(i))))
return res;
if (owner->null_value)
return -1;
}
return res;
}
longlong Item_func_eq::val_int() longlong Item_func_eq::val_int()
{ {
int value=(this->*cmp_func)(); int value= cmp_func->compare(args[0], args[1]);
return value == 0 ? 1 : 0; return value == 0 ? 1 : 0;
} }
...@@ -218,6 +245,11 @@ longlong Item_func_equal::val_int() ...@@ -218,6 +245,11 @@ longlong Item_func_equal::val_int()
return test(args[0]->null_value && args[1]->null_value); return test(args[0]->null_value && args[1]->null_value);
return test(val1 == val2); return test(val1 == val2);
} }
case ROW_RESULT:
{
my_error(ER_WRONG_USAGE, MYF(0), "row", "<=>");
return 0;
}
} }
return 0; // Impossible return 0; // Impossible
} }
...@@ -225,34 +257,34 @@ longlong Item_func_equal::val_int() ...@@ -225,34 +257,34 @@ longlong Item_func_equal::val_int()
longlong Item_func_ne::val_int() longlong Item_func_ne::val_int()
{ {
int value=(this->*cmp_func)(); int value= cmp_func->compare(args[0], args[1]);
return value != 0 && !null_value ? 1 : 0; return value != 0 && !null_value ? 1 : 0;
} }
longlong Item_func_ge::val_int() longlong Item_func_ge::val_int()
{ {
int value=(this->*cmp_func)(); int value= cmp_func->compare(args[0], args[1]);
return value >= 0 ? 1 : 0; return value >= 0 ? 1 : 0;
} }
longlong Item_func_gt::val_int() longlong Item_func_gt::val_int()
{ {
int value=(this->*cmp_func)(); int value= cmp_func->compare(args[0], args[1]);
return value > 0 ? 1 : 0; return value > 0 ? 1 : 0;
} }
longlong Item_func_le::val_int() longlong Item_func_le::val_int()
{ {
int value=(this->*cmp_func)(); int value= cmp_func->compare(args[0], args[1]);
return value <= 0 && !null_value ? 1 : 0; return value <= 0 && !null_value ? 1 : 0;
} }
longlong Item_func_lt::val_int() longlong Item_func_lt::val_int()
{ {
int value=(this->*cmp_func)(); int value= cmp_func->compare(args[0], args[1]);
return value < 0 && !null_value ? 1 : 0; return value < 0 && !null_value ? 1 : 0;
} }
...@@ -595,7 +627,7 @@ double ...@@ -595,7 +627,7 @@ double
Item_func_nullif::val() Item_func_nullif::val()
{ {
double value; double value;
if (!(this->*cmp_func)() || null_value) if (!cmp_func->compare(args[0], args[1]) || null_value)
{ {
null_value=1; null_value=1;
return 0.0; return 0.0;
...@@ -609,7 +641,7 @@ longlong ...@@ -609,7 +641,7 @@ longlong
Item_func_nullif::val_int() Item_func_nullif::val_int()
{ {
longlong value; longlong value;
if (!(this->*cmp_func)() || null_value) if (!cmp_func->compare(args[0], args[1]) || null_value)
{ {
null_value=1; null_value=1;
return 0; return 0;
...@@ -623,7 +655,7 @@ String * ...@@ -623,7 +655,7 @@ String *
Item_func_nullif::val_str(String *str) Item_func_nullif::val_str(String *str)
{ {
String *res; String *res;
if (!(this->*cmp_func)() || null_value) if (!cmp_func->compare(args[0], args[1]) || null_value)
{ {
null_value=1; null_value=1;
return 0; return 0;
...@@ -702,6 +734,11 @@ Item *Item_func_case::find_item(String *str) ...@@ -702,6 +734,11 @@ Item *Item_func_case::find_item(String *str)
} }
if (args[i]->val()==first_expr_real && !args[i]->null_value) if (args[i]->val()==first_expr_real && !args[i]->null_value)
return args[i+1]; return args[i+1];
break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
} }
// No, WHEN clauses all missed, return ELSE expression // No, WHEN clauses all missed, return ELSE expression
...@@ -764,8 +801,10 @@ double Item_func_case::val() ...@@ -764,8 +801,10 @@ double Item_func_case::val()
bool bool
Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
if (first_expr && first_expr->fix_fields(thd, tables, &first_expr) || if (first_expr && (first_expr->check_cols(1) ||
else_expr && else_expr->fix_fields(thd, tables, &else_expr)) first_expr->fix_fields(thd, tables, &first_expr)) ||
else_expr && (else_expr->check_cols(1) ||
else_expr->fix_fields(thd, tables, &else_expr)))
return 1; return 1;
if (Item_func::fix_fields(thd, tables, ref)) if (Item_func::fix_fields(thd, tables, ref))
return 1; return 1;
...@@ -1007,6 +1046,10 @@ void Item_func_in::fix_length_and_dec() ...@@ -1007,6 +1046,10 @@ void Item_func_in::fix_length_and_dec()
case REAL_RESULT: case REAL_RESULT:
array= new in_double(arg_count); array= new in_double(arg_count);
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
uint j=0; uint j=0;
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
...@@ -1033,6 +1076,10 @@ void Item_func_in::fix_length_and_dec() ...@@ -1033,6 +1076,10 @@ void Item_func_in::fix_length_and_dec()
case REAL_RESULT: case REAL_RESULT:
in_item= new cmp_item_real; in_item= new cmp_item_real;
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
} }
maybe_null= item->maybe_null; maybe_null= item->maybe_null;
...@@ -1141,7 +1188,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -1141,7 +1188,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
#endif #endif
item= *li.ref(); // new current item item= *li.ref(); // new current item
} }
if (item->fix_fields(thd, tables, li.ref())) if (item->check_cols(1) || item->fix_fields(thd, tables, li.ref()))
return 1; /* purecov: inspected */ return 1; /* purecov: inspected */
used_tables_cache|=item->used_tables(); used_tables_cache|=item->used_tables();
with_sum_func= with_sum_func || item->with_sum_func; with_sum_func= with_sum_func || item->with_sum_func;
...@@ -1390,7 +1437,9 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) ...@@ -1390,7 +1437,9 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
bool bool
Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
if (args[0]->fix_fields(thd, tables, args) || if (args[0]->check_cols(1) ||
args[1]->check_cols(1) ||
args[0]->fix_fields(thd, tables, args) ||
args[1]->fix_fields(thd,tables, args + 1)) args[1]->fix_fields(thd,tables, args + 1))
return 1; /* purecov: inspected */ return 1; /* purecov: inspected */
with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func; with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
......
...@@ -30,6 +30,61 @@ class Item_bool_func :public Item_int_func ...@@ -30,6 +30,61 @@ class Item_bool_func :public Item_int_func
void fix_length_and_dec() { decimals=0; max_length=1; } void fix_length_and_dec() { decimals=0; max_length=1; }
}; };
class Item_bool_func2;
class Compare_func
{
protected:
Item_bool_func2 *owner;
public:
static void *operator new(size_t size)
{
return (void*) sql_alloc((uint) size);
}
static void operator delete(void *ptr,size_t size) {}
Compare_func(Item_bool_func2 *o) { owner= o; }
virtual ~Compare_func() {};
virtual int compare(Item *, Item*)= 0;
static Compare_func* get_compare_func(Item_bool_func2 *owner,
Item* a, Item* b);
};
class Compare_func_string: public Compare_func
{
public:
Compare_func_string(Item_bool_func2 *owner): Compare_func(owner) {};
int compare(Item *, Item*);
};
class Compare_func_real: public Compare_func
{
public:
Compare_func_real(Item_bool_func2 *owner): Compare_func(owner) {};
int compare(Item *, Item*);
};
class Compare_func_int: public Compare_func
{
public:
Compare_func_int(Item_bool_func2 *owner): Compare_func(owner) {};
int compare(Item *, Item*);
};
class Compare_func_row: public Compare_func
{
Compare_func **cmp_func;
public:
Compare_func_row(Item_bool_func2 *owner, Item* a, Item* b);
~Compare_func_row()
{
if(cmp_func)
sql_element_free(cmp_func);
}
int compare(Item *, Item*);
};
class Item_bool_func2 :public Item_int_func class Item_bool_func2 :public Item_int_func
{ /* Bool with 2 string args */ { /* Bool with 2 string args */
protected: protected:
...@@ -37,18 +92,28 @@ class Item_bool_func2 :public Item_int_func ...@@ -37,18 +92,28 @@ class Item_bool_func2 :public Item_int_func
public: public:
Item_bool_func2(Item *a,Item *b) :Item_int_func(a,b) {} Item_bool_func2(Item *a,Item *b) :Item_int_func(a,b) {}
void fix_length_and_dec(); void fix_length_and_dec();
void set_cmp_func(Item_result type); Compare_func *cmp_func;
int (Item_bool_func2::*cmp_func)(); void set_cmp_func(Item *a, Item *b)
int compare_string(); /* compare arg[0] & arg[1] */ {
int compare_real(); /* compare arg[0] & arg[1] */ cmp_func= Compare_func::get_compare_func(this, args[0], args[1]);
int compare_int(); /* compare arg[0] & arg[1] */ }
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()); }
friend class Compare_func_string;
}; };
class Item_bool_rowready_func2 :public Item_bool_func2
{
public:
Item_bool_rowready_func2(Item *a,Item *b) :Item_bool_func2(a,b)
{
allowed_arg_cols= a->cols();
}
};
class Item_func_not :public Item_bool_func class Item_func_not :public Item_bool_func
{ {
...@@ -58,10 +123,10 @@ class Item_func_not :public Item_bool_func ...@@ -58,10 +123,10 @@ class Item_func_not :public Item_bool_func
const char *func_name() const { return "not"; } const char *func_name() const { return "not"; }
}; };
class Item_func_eq :public Item_bool_func2 class Item_func_eq :public Item_bool_rowready_func2
{ {
public: public:
Item_func_eq(Item *a,Item *b) :Item_bool_func2(a,b) { }; Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) { };
longlong val_int(); longlong val_int();
enum Functype functype() const { return EQ_FUNC; } enum Functype functype() const { return EQ_FUNC; }
enum Functype rev_functype() const { return EQ_FUNC; } enum Functype rev_functype() const { return EQ_FUNC; }
...@@ -83,10 +148,10 @@ class Item_func_equal :public Item_bool_func2 ...@@ -83,10 +148,10 @@ class Item_func_equal :public Item_bool_func2
}; };
class Item_func_ge :public Item_bool_func2 class Item_func_ge :public Item_bool_rowready_func2
{ {
public: public:
Item_func_ge(Item *a,Item *b) :Item_bool_func2(a,b) { }; Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) { };
longlong val_int(); longlong val_int();
enum Functype functype() const { return GE_FUNC; } enum Functype functype() const { return GE_FUNC; }
enum Functype rev_functype() const { return LE_FUNC; } enum Functype rev_functype() const { return LE_FUNC; }
...@@ -95,10 +160,10 @@ class Item_func_ge :public Item_bool_func2 ...@@ -95,10 +160,10 @@ class Item_func_ge :public Item_bool_func2
}; };
class Item_func_gt :public Item_bool_func2 class Item_func_gt :public Item_bool_rowready_func2
{ {
public: public:
Item_func_gt(Item *a,Item *b) :Item_bool_func2(a,b) { }; Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) { };
longlong val_int(); longlong val_int();
enum Functype functype() const { return GT_FUNC; } enum Functype functype() const { return GT_FUNC; }
enum Functype rev_functype() const { return LT_FUNC; } enum Functype rev_functype() const { return LT_FUNC; }
...@@ -107,10 +172,10 @@ class Item_func_gt :public Item_bool_func2 ...@@ -107,10 +172,10 @@ class Item_func_gt :public Item_bool_func2
}; };
class Item_func_le :public Item_bool_func2 class Item_func_le :public Item_bool_rowready_func2
{ {
public: public:
Item_func_le(Item *a,Item *b) :Item_bool_func2(a,b) { }; Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) { };
longlong val_int(); longlong val_int();
enum Functype functype() const { return LE_FUNC; } enum Functype functype() const { return LE_FUNC; }
enum Functype rev_functype() const { return GE_FUNC; } enum Functype rev_functype() const { return GE_FUNC; }
...@@ -119,10 +184,10 @@ class Item_func_le :public Item_bool_func2 ...@@ -119,10 +184,10 @@ class Item_func_le :public Item_bool_func2
}; };
class Item_func_lt :public Item_bool_func2 class Item_func_lt :public Item_bool_rowready_func2
{ {
public: public:
Item_func_lt(Item *a,Item *b) :Item_bool_func2(a,b) { } Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) { }
longlong val_int(); longlong val_int();
enum Functype functype() const { return LT_FUNC; } enum Functype functype() const { return LT_FUNC; }
enum Functype rev_functype() const { return GT_FUNC; } enum Functype rev_functype() const { return GT_FUNC; }
...@@ -131,10 +196,10 @@ class Item_func_lt :public Item_bool_func2 ...@@ -131,10 +196,10 @@ class Item_func_lt :public Item_bool_func2
}; };
class Item_func_ne :public Item_bool_func2 class Item_func_ne :public Item_bool_rowready_func2
{ {
public: public:
Item_func_ne(Item *a,Item *b) :Item_bool_func2(a,b) { } Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) { }
longlong val_int(); longlong val_int();
enum Functype functype() const { return NE_FUNC; } enum Functype functype() const { return NE_FUNC; }
cond_result eq_cmp_result() const { return COND_FALSE; } cond_result eq_cmp_result() const { return COND_FALSE; }
...@@ -179,7 +244,8 @@ class Item_func_interval :public Item_int_func ...@@ -179,7 +244,8 @@ class Item_func_interval :public Item_int_func
longlong val_int(); longlong val_int();
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref) bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
{ {
return (item->fix_fields(thd, tlist, &item) || return (item->check_cols(1) ||
item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref)); Item_func::fix_fields(thd, tlist, ref));
} }
void fix_length_and_dec(); void fix_length_and_dec();
...@@ -414,7 +480,8 @@ class Item_func_in :public Item_int_func ...@@ -414,7 +480,8 @@ class Item_func_in :public Item_int_func
longlong val_int(); longlong val_int();
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref) bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
{ {
return (item->fix_fields(thd, tlist, &item) || return (item->check_cols(1) ||
item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref)); Item_func::fix_fields(thd, tlist, ref));
} }
void fix_length_and_dec(); void fix_length_and_dec();
......
...@@ -39,7 +39,8 @@ eval_const_cond(COND *cond) ...@@ -39,7 +39,8 @@ eval_const_cond(COND *cond)
} }
Item_func::Item_func(List<Item> &list) Item_func::Item_func(List<Item> &list):
allowed_arg_cols(1)
{ {
arg_count=list.elements; arg_count=list.elements;
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
...@@ -111,7 +112,8 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -111,7 +112,8 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
set_charset((*args)->charset()); set_charset((*args)->charset());
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
{ {
if ((*arg)->fix_fields(thd, tables, arg)) if ((*arg)->check_cols(allowed_arg_cols) ||
(*arg)->fix_fields(thd, tables, arg))
return 1; /* purecov: inspected */ return 1; /* purecov: inspected */
if ((*arg)->maybe_null) if ((*arg)->maybe_null)
maybe_null=1; maybe_null=1;
...@@ -248,6 +250,10 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) ...@@ -248,6 +250,10 @@ Field *Item_func::tmp_table_field(TABLE *t_arg)
else else
res= new Field_string(max_length, maybe_null, name, t_arg, charset()); res= new Field_string(max_length, maybe_null, name, t_arg, charset());
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
return res; return res;
} }
...@@ -869,6 +875,11 @@ String *Item_func_min_max::val_str(String *str) ...@@ -869,6 +875,11 @@ String *Item_func_min_max::val_str(String *str)
} }
return res; return res;
} }
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
} }
return 0; // Keep compiler happy return 0; // Keep compiler happy
} }
...@@ -1276,7 +1287,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, ...@@ -1276,7 +1287,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
arg != arg_end ; arg != arg_end ;
arg++,i++) arg++,i++)
{ {
if ((*arg)->fix_fields(thd, tables, arg)) if ((*arg)->check_cols(1) || (*arg)->fix_fields(thd, tables, arg))
return 1; return 1;
if ((*arg)->binary()) if ((*arg)->binary())
func->set_charset(my_charset_bin); func->set_charset(my_charset_bin);
...@@ -1405,6 +1416,10 @@ bool udf_handler::get_arguments() ...@@ -1405,6 +1416,10 @@ bool udf_handler::get_arguments()
to+= ALIGN_SIZE(sizeof(double)); to+= ALIGN_SIZE(sizeof(double));
} }
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
;
} }
} }
return 0; return 0;
...@@ -1857,6 +1872,10 @@ longlong Item_func_benchmark::val_int() ...@@ -1857,6 +1872,10 @@ longlong Item_func_benchmark::val_int()
case STRING_RESULT: case STRING_RESULT:
(void) args[0]->val_str(&tmp); (void) args[0]->val_str(&tmp);
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
} }
} }
return 0; return 0;
...@@ -1983,11 +2002,17 @@ Item_func_set_user_var::update() ...@@ -1983,11 +2002,17 @@ Item_func_set_user_var::update()
(void) val_int(); (void) val_int();
break; break;
case STRING_RESULT: case STRING_RESULT:
{
char buffer[MAX_FIELD_WIDTH]; char buffer[MAX_FIELD_WIDTH];
String tmp(buffer,sizeof(buffer),default_charset_info); String tmp(buffer,sizeof(buffer),default_charset_info);
(void) val_str(&tmp); (void) val_str(&tmp);
break; break;
} }
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
}
return current_thd->fatal_error; return current_thd->fatal_error;
} }
...@@ -2062,6 +2087,10 @@ Item_func_get_user_var::val_str(String *str) ...@@ -2062,6 +2087,10 @@ Item_func_get_user_var::val_str(String *str)
return NULL; return NULL;
} }
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
return str; return str;
} }
...@@ -2079,6 +2108,10 @@ double Item_func_get_user_var::val() ...@@ -2079,6 +2108,10 @@ double Item_func_get_user_var::val()
return (double) *(longlong*) entry->value; return (double) *(longlong*) entry->value;
case STRING_RESULT: case STRING_RESULT:
return atof(entry->value); // This is null terminated return atof(entry->value); // This is null terminated
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
} }
return 0.0; // Impossible return 0.0; // Impossible
} }
...@@ -2096,6 +2129,10 @@ longlong Item_func_get_user_var::val_int() ...@@ -2096,6 +2129,10 @@ longlong Item_func_get_user_var::val_int()
return *(longlong*) entry->value; return *(longlong*) entry->value;
case STRING_RESULT: case STRING_RESULT:
return strtoull(entry->value,NULL,10); // String is null terminated return strtoull(entry->value,NULL,10); // String is null terminated
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
} }
return LL(0); // Impossible return LL(0); // Impossible
} }
...@@ -2256,7 +2293,7 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) ...@@ -2256,7 +2293,7 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
while ((item=li++)) while ((item=li++))
{ {
if (item->fix_fields(thd, tlist, li.ref())) if (item->check_cols(1) || item->fix_fields(thd, tlist, li.ref()))
return 1; return 1;
if (item->type() == Item::REF_ITEM) if (item->type() == Item::REF_ITEM)
li.replace(item= *((Item_ref *)item)->ref); li.replace(item= *((Item_ref *)item)->ref);
......
...@@ -32,6 +32,7 @@ class Item_func :public Item_result_field ...@@ -32,6 +32,7 @@ class Item_func :public Item_result_field
{ {
protected: protected:
Item **args,*tmp_arg[2]; Item **args,*tmp_arg[2];
uint allowed_arg_cols;
public: public:
uint arg_count; uint arg_count;
table_map used_tables_cache; table_map used_tables_cache;
...@@ -49,25 +50,27 @@ class Item_func :public Item_result_field ...@@ -49,25 +50,27 @@ class Item_func :public Item_result_field
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL }; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL };
enum Type type() const { return FUNC_ITEM; } enum Type type() const { return FUNC_ITEM; }
virtual enum Functype functype() const { return UNKNOWN_FUNC; } virtual enum Functype functype() const { return UNKNOWN_FUNC; }
Item_func(void) Item_func(void):
allowed_arg_cols(1), arg_count(0)
{ {
arg_count=0; with_sum_func=0; with_sum_func=0;
} }
Item_func(Item *a) Item_func(Item *a):
allowed_arg_cols(1), arg_count(1)
{ {
arg_count=1;
args=tmp_arg; args=tmp_arg;
args[0]=a; args[0]=a;
with_sum_func=a->with_sum_func; with_sum_func=a->with_sum_func;
} }
Item_func(Item *a,Item *b) Item_func(Item *a,Item *b):
allowed_arg_cols(1), arg_count(2)
{ {
arg_count=2;
args=tmp_arg; args=tmp_arg;
args[0]=a; args[1]=b; args[0]=a; args[1]=b;
with_sum_func=a->with_sum_func || b->with_sum_func; with_sum_func=a->with_sum_func || b->with_sum_func;
} }
Item_func(Item *a,Item *b,Item *c) Item_func(Item *a,Item *b,Item *c):
allowed_arg_cols(1)
{ {
arg_count=0; arg_count=0;
if ((args=(Item**) sql_alloc(sizeof(Item*)*3))) if ((args=(Item**) sql_alloc(sizeof(Item*)*3)))
...@@ -77,7 +80,8 @@ class Item_func :public Item_result_field ...@@ -77,7 +80,8 @@ class Item_func :public Item_result_field
with_sum_func=a->with_sum_func || b->with_sum_func || c->with_sum_func; with_sum_func=a->with_sum_func || b->with_sum_func || c->with_sum_func;
} }
} }
Item_func(Item *a,Item *b,Item *c,Item *d) Item_func(Item *a,Item *b,Item *c,Item *d):
allowed_arg_cols(1)
{ {
arg_count=0; arg_count=0;
if ((args=(Item**) sql_alloc(sizeof(Item*)*4))) if ((args=(Item**) sql_alloc(sizeof(Item*)*4)))
...@@ -88,7 +92,8 @@ class Item_func :public Item_result_field ...@@ -88,7 +92,8 @@ class Item_func :public Item_result_field
d->with_sum_func; d->with_sum_func;
} }
} }
Item_func(Item *a,Item *b,Item *c,Item *d,Item* e) Item_func(Item *a,Item *b,Item *c,Item *d,Item* e):
allowed_arg_cols(1)
{ {
arg_count=5; arg_count=5;
if ((args=(Item**) sql_alloc(sizeof(Item*)*5))) if ((args=(Item**) sql_alloc(sizeof(Item*)*5)))
...@@ -590,7 +595,8 @@ class Item_func_field :public Item_int_func ...@@ -590,7 +595,8 @@ class Item_func_field :public Item_int_func
longlong val_int(); longlong val_int();
bool fix_fields(THD *thd,struct st_table_list *tlist, Item **ref) bool fix_fields(THD *thd,struct st_table_list *tlist, Item **ref)
{ {
return (item->fix_fields(thd, tlist, &item) || return (item->check_cols(1) ||
item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref)); Item_func::fix_fields(thd, tlist, ref));
} }
void update_used_tables() void update_used_tables()
......
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
#include "assert.h"
Item_row::Item_row(List<Item> &arg):
Item(), array_holder(1)
{
if ((arg_count= arg.elements))
items= (Item**) sql_alloc(sizeof(Item*)*arg_count);
else
items= 0;
List_iterator<Item> li(arg);
uint i= 0;
Item *item;
while ((item= li++))
{
items[i]= item;
i++;
}
}
void Item_row::illegal_method_call(const char *method)
{
DBUG_ENTER("Item_row::illegal_method_call");
DBUG_PRINT("error", ("!!! %s method was called for row item", method));
DBUG_ASSERT(0);
my_error(ER_CARDINALITY_COL, MYF(0), arg_count);
DBUG_VOID_RETURN;
}
bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref)
{
tables= 0;
for (uint i= 0; i < arg_count; i++)
{
if (items[i]->fix_fields(thd, tabl, items+i))
return 1;
tables |= items[i]->used_tables();
}
return 0;
}
bool Item_row::check_cols(uint c)
{
if (c != arg_count)
{
my_error(ER_CARDINALITY_COL, MYF(0), arg_count);
return 1;
}
return 0;
}
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
class Item_row: public Item
{
bool array_holder;
table_map tables;
uint arg_count;
Item **items;
public:
Item_row(List<Item> &);
Item_row(Item_row *item):
Item(), array_holder(0), tables(item->tables), arg_count(item->arg_count),
items(item->items)
{}
~Item_row()
{
if(array_holder && items)
sql_element_free(items);
}
enum Type type() const { return ROW_ITEM; };
void illegal_method_call(const char *);
bool is_null() { return null_value; }
void make_field(Send_field *)
{
illegal_method_call((const char*)"make_field");
};
double val()
{
illegal_method_call((const char*)"val");
return 0;
};
longlong val_int()
{
illegal_method_call((const char*)"val_int");
return 0;
};
String *val_str(String *)
{
illegal_method_call((const char*)"val_str");
return 0;
};
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
table_map used_tables() const { return tables; };
enum Item_result result_type() const { return ROW_RESULT; }
virtual uint cols() { return arg_count; }
virtual Item* el(uint i) { return items[i]; }
virtual bool check_cols(uint c);
};
...@@ -2059,7 +2059,7 @@ bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables, I ...@@ -2059,7 +2059,7 @@ bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables, I
if (thd && check_stack_overrun(thd,buff)) if (thd && check_stack_overrun(thd,buff))
return 0; // Fatal error if flag is set! return 0; // Fatal error if flag is set!
if (args[0]->fix_fields(thd, tables, args)) if (args[0]->check_cols(1) || args[0]->fix_fields(thd, tables, args))
return 1; return 1;
maybe_null=args[0]->maybe_null; maybe_null=args[0]->maybe_null;
const_item_cache=args[0]->const_item(); const_item_cache=args[0]->const_item();
...@@ -2091,7 +2091,7 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, ...@@ -2091,7 +2091,7 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables,
if (thd && check_stack_overrun(thd,buff)) if (thd && check_stack_overrun(thd,buff))
return 0; // Fatal error if flag is set! return 0; // Fatal error if flag is set!
if (args[0]->fix_fields(thd, tables, args)) if (args[0]->check_cols(1) || args[0]->fix_fields(thd, tables, args))
return 1; return 1;
maybe_null=args[0]->maybe_null; maybe_null=args[0]->maybe_null;
set_charset(set_collation); set_charset(set_collation);
......
...@@ -101,8 +101,9 @@ class Item_func_concat_ws :public Item_str_func ...@@ -101,8 +101,9 @@ class Item_func_concat_ws :public Item_str_func
void update_used_tables(); void update_used_tables();
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
{ {
return (separator->fix_fields(thd, tlist, &separator) return (separator->check_cols(1) ||
|| Item_func::fix_fields(thd, tlist, ref)); separator->fix_fields(thd, tlist, &separator) ||
Item_func::fix_fields(thd, tlist, ref));
} }
const char *func_name() const { return "concat_ws"; } const char *func_name() const { return "concat_ws"; }
bool check_loop(uint id) bool check_loop(uint id)
...@@ -362,7 +363,8 @@ class Item_func_elt :public Item_str_func ...@@ -362,7 +363,8 @@ class Item_func_elt :public Item_str_func
String *val_str(String *str); String *val_str(String *str);
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
{ {
return (item->fix_fields(thd, tlist, &item) || return (item->check_cols(1) ||
item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref)); Item_func::fix_fields(thd, tlist, ref));
} }
void fix_length_and_dec(); void fix_length_and_dec();
...@@ -389,7 +391,8 @@ class Item_func_make_set :public Item_str_func ...@@ -389,7 +391,8 @@ class Item_func_make_set :public Item_str_func
String *val_str(String *str); String *val_str(String *str);
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
{ {
return (item->fix_fields(thd, tlist, &item) || return (item->check_cols(1) ||
item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref)); Item_func::fix_fields(thd, tlist, ref));
} }
void fix_length_and_dec(); void fix_length_and_dec();
......
...@@ -87,7 +87,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -87,7 +87,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
// Is it one field subselect? // Is it one field subselect?
if (engine->cols() > max_columns) if (engine->cols() > max_columns)
{ {
my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); my_error(ER_CARDINALITY_COL, MYF(0), 1);
return 1; return 1;
} }
fix_length_and_dec(); fix_length_and_dec();
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#endif #endif
#include "mysql_priv.h" #include "mysql_priv.h"
#include "assert.h"
Item_sum::Item_sum(List<Item> &list) Item_sum::Item_sum(List<Item> &list)
{ {
...@@ -124,7 +124,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -124,7 +124,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
maybe_null=0; maybe_null=0;
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{ {
if (args[i]->fix_fields(thd, tables, args + i)) if (args[i]->check_cols(1) || args[i]->fix_fields(thd, tables, args + i))
return 1; return 1;
if (decimals < args[i]->decimals) if (decimals < args[i]->decimals)
decimals=args[i]->decimals; decimals=args[i]->decimals;
...@@ -149,7 +149,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -149,7 +149,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 1; return 1;
} }
thd->allow_sum_func=0; // No included group funcs thd->allow_sum_func=0; // No included group funcs
if (item->fix_fields(thd, tables, args)) if (item->check_cols(1) || item->fix_fields(thd, tables, args))
return 1; return 1;
hybrid_type=item->result_type(); hybrid_type=item->result_type();
if (hybrid_type == INT_RESULT) if (hybrid_type == INT_RESULT)
...@@ -336,6 +336,10 @@ double Item_sum_hybrid::val() ...@@ -336,6 +336,10 @@ double Item_sum_hybrid::val()
return (double) sum_int; return (double) sum_int;
case REAL_RESULT: case REAL_RESULT:
return sum; return sum;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
} }
return 0; // Keep compiler happy return 0; // Keep compiler happy
} }
...@@ -367,6 +371,10 @@ Item_sum_hybrid::val_str(String *str) ...@@ -367,6 +371,10 @@ Item_sum_hybrid::val_str(String *str)
else else
str->set((longlong) sum_int,thd_charset()); str->set((longlong) sum_int,thd_charset());
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
return str; // Keep compiler happy return str; // Keep compiler happy
} }
...@@ -409,6 +417,10 @@ bool Item_sum_min::add() ...@@ -409,6 +417,10 @@ bool Item_sum_min::add()
} }
} }
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
return 0; return 0;
} }
...@@ -452,6 +464,11 @@ bool Item_sum_max::add() ...@@ -452,6 +464,11 @@ bool Item_sum_max::add()
} }
} }
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
return 0; return 0;
} }
......
/* v/*
Modifikoval Petr -Bnajdr, snajdr@pvt.net, snajdr@cpress.cz v.0.01 -A Modifikoval Petr -Bnajdr, snajdr@pvt.net, snajdr@cpress.cz v.0.01 -A
ISO LATIN-8852-2 ISO LATIN-8852-2
Dal-B verze Jan Pazdziora, adelton@fi.muni.cz-A Dal-B verze Jan Pazdziora, adelton@fi.muni.cz-A
...@@ -249,7 +249,7 @@ ...@@ -249,7 +249,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -243,7 +243,7 @@ ...@@ -243,7 +243,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -251,7 +251,7 @@ ...@@ -251,7 +251,7 @@
"Kreeg fatale fout %d: '%-.128s' van master tijdens lezen van data uit binaire log", "Kreeg fatale fout %d: '%-.128s' van master tijdens lezen van data uit binaire log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -245,7 +245,7 @@ ...@@ -245,7 +245,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -243,7 +243,7 @@ ...@@ -243,7 +243,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect return more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect return more than 1 record", "Subselect return more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -243,7 +243,7 @@ ...@@ -243,7 +243,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
" ", " (/ %d )",
" ", " ",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -241,7 +241,7 @@ ...@@ -241,7 +241,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"Subselect returns more than 1 field", "Cardinality error (more/less than %d columns)",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
......
...@@ -245,8 +245,8 @@ ...@@ -245,8 +245,8 @@
"Got fatal error %d: '%-.128s' from master when reading data from binary log", "Got fatal error %d: '%-.128s' from master when reading data from binary log",
"Wrong foreign key definition for '%-.64s': %s", "Wrong foreign key definition for '%-.64s': %s",
"Key reference and table reference doesn't match", "Key reference and table reference doesn't match",
"i i i 1 ", "Cardinality error (¦/ Φ %d æ)",
"i i i 1 ", " ¦ i 1 ",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
"i i", "̦ Ц",
...@@ -2027,7 +2027,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields, ...@@ -2027,7 +2027,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
thd->used_tables|=item->used_tables(); thd->used_tables|=item->used_tables();
} }
} }
DBUG_RETURN(test(thd->fatal_error)); DBUG_RETURN(test(thd->fatal_error || thd->net.report_error));
} }
...@@ -2239,7 +2239,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -2239,7 +2239,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
table->on_expr=and_conds(table->on_expr,cond_and); table->on_expr=and_conds(table->on_expr,cond_and);
} }
} }
DBUG_RETURN(test(thd->fatal_error)); DBUG_RETURN(test(thd->fatal_error || thd->net.report_error));
} }
......
...@@ -191,6 +191,10 @@ static int find_keyword(LEX *lex, uint len, bool function) ...@@ -191,6 +191,10 @@ static int find_keyword(LEX *lex, uint len, bool function)
return (udf->type == UDFTYPE_FUNCTION) ? UDF_FLOAT_FUNC : UDA_FLOAT_SUM; return (udf->type == UDFTYPE_FUNCTION) ? UDF_FLOAT_FUNC : UDA_FLOAT_SUM;
case INT_RESULT: case INT_RESULT:
return (udf->type == UDFTYPE_FUNCTION) ? UDF_INT_FUNC : UDA_INT_SUM; return (udf->type == UDFTYPE_FUNCTION) ? UDF_INT_FUNC : UDA_INT_SUM;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
} }
} }
#endif #endif
......
...@@ -3317,8 +3317,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father, ...@@ -3317,8 +3317,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
if ((tmp2=new COND_CMP(and_father,func))) if ((tmp2=new COND_CMP(and_father,func)))
save_list->push_back(tmp2); save_list->push_back(tmp2);
} }
func->set_cmp_func(item_cmp_type(func->arguments()[0]->result_type(), func->set_cmp_func(func->arguments()[0],func->arguments()[1]);
func->arguments()[1]->result_type()));
} }
} }
else if (left_item->eq(field,0) && right_item != value) else if (left_item->eq(field,0) && right_item != value)
...@@ -3338,8 +3337,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father, ...@@ -3338,8 +3337,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
if ((tmp2=new COND_CMP(and_father,func))) if ((tmp2=new COND_CMP(and_father,func)))
save_list->push_back(tmp2); save_list->push_back(tmp2);
} }
func->set_cmp_func(item_cmp_type(func->arguments()[0]->result_type(), func->set_cmp_func(func->arguments()[0], func->arguments()[1]);
func->arguments()[1]->result_type()));
} }
} }
} }
...@@ -3679,6 +3677,10 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -3679,6 +3677,10 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
item->name,table,item->charset()); item->name,table,item->charset());
return new Field_string(item_sum->max_length,maybe_null, return new Field_string(item_sum->max_length,maybe_null,
item->name,table,item->charset()); item->name,table,item->charset());
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
} }
} }
thd->fatal_error=1; thd->fatal_error=1;
...@@ -3735,6 +3737,10 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -3735,6 +3737,10 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
new_field= new Field_string(item->max_length,maybe_null, new_field= new Field_string(item->max_length,maybe_null,
item->name,table,item->str_value.charset()); item->name,table,item->str_value.charset());
break; break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
} }
if (copy_func) if (copy_func)
*((*copy_func)++) = (Item_result_field*) item; // Save for copy_funcs *((*copy_func)++) = (Item_result_field*) item; // Save for copy_funcs
......
...@@ -1873,6 +1873,11 @@ simple_expr: ...@@ -1873,6 +1873,11 @@ simple_expr:
| NOT expr %prec NEG { $$= new Item_func_not($2); } | NOT expr %prec NEG { $$= new Item_func_not($2); }
| '!' expr %prec NEG { $$= new Item_func_not($2); } | '!' expr %prec NEG { $$= new Item_func_not($2); }
| '(' expr ')' { $$= $2; } | '(' expr ')' { $$= $2; }
| '(' expr ',' expr_list ')'
{
$4->push_front($2);
$$= new Item_row(*$4);
}
| EXISTS exists_subselect { $$= $2; } | EXISTS exists_subselect { $$= $2; }
| singleval_subselect { $$= $1; } | singleval_subselect { $$= $1; }
| '{' ident expr '}' { $$= $3; } | '{' ident expr '}' { $$= $3; }
......
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