Commit b79170b7 authored by unknown's avatar unknown

New CAST syntax

Cleanup of multi-table-delete in sql_yacc.yy
Changed syntax of MAXIMUM QUERIES PER HOUR to MAX_QUERIES_PER_HOUR to
not get too many reserved words.


Docs/manual.texi:
  Updated information about CAST
mysql-test/r/bigint.result:
  New CAST syntax
mysql-test/r/create.result:
  New CAST syntax
mysql-test/r/variables.result:
  Fix after merge with 3.23
mysql-test/t/bigint.test:
  New CAST syntax
mysql-test/t/create.test:
  New CAST syntax
sql/item_create.cc:
  New CAST syntax
sql/item_func.h:
  New CAST syntax
sql/item_timefunc.cc:
  New CAST syntax
sql/item_timefunc.h:
  New CAST syntax
sql/lex.h:
  Changed syntax to MAX_QUERIES_PER_HOUR to not get too many reserved words.
sql/mysql_priv.h:
  Cleanup multi-delete
sql/sql_parse.cc:
  Cleanup multi-delete
sql/sql_yacc.yy:
  Cleanup multi-delete.
  New CAST syntax.
  Removed some restricted words.
parent 301cdf9f
...@@ -22119,10 +22119,10 @@ is @code{localhost}. ...@@ -22119,10 +22119,10 @@ is @code{localhost}.
Lock all tables before starting the dump. The tables are locked with Lock all tables before starting the dump. The tables are locked with
@code{READ LOCAL} to allow concurrent inserts in the case of @code{MyISAM} @code{READ LOCAL} to allow concurrent inserts in the case of @code{MyISAM}
tables. tables.
@item -K, --no-disable-keys. @item -K, --disable-keys
@code{/*!40000 ALTER TABLE tb_name DISABLE KEYS */;} and @code{/*!40000 ALTER TABLE tb_name DISABLE KEYS */;} and
@code{/*!40000 ALTER TABLE tb_name ENABLE KEYS */;} @code{/*!40000 ALTER TABLE tb_name ENABLE KEYS */;}
will not be put in the output. will be put in the output.
@item -n, --no-create-db @item -n, --no-create-db
@code{CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;} will not be put in the @code{CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;} will not be put in the
output. The above line will be added otherwise, if --databases or output. The above line will be added otherwise, if --databases or
...@@ -29434,6 +29434,7 @@ mysql> select MOD(29,9); ...@@ -29434,6 +29434,7 @@ mysql> select MOD(29,9);
* String functions:: String functions * String functions:: String functions
* Numeric Functions:: Numeric Functions * Numeric Functions:: Numeric Functions
* Date and time functions:: Date and time functions * Date and time functions:: Date and time functions
* Cast Functions::
* Other Functions:: Other Functions * Other Functions:: Other Functions
* Group by functions:: Functions for Use with @code{GROUP BY} Clauses * Group by functions:: Functions for Use with @code{GROUP BY} Clauses
@end menu @end menu
...@@ -30662,6 +30663,8 @@ mysql> select BINARY "a" = "A"; ...@@ -30662,6 +30663,8 @@ mysql> select BINARY "a" = "A";
-> 0 -> 0
@end example @end example
@code{BINARY string} is a shorthand for @code{CAST(string AS BINARY)}.
@xref{Cast Functions}.
@code{BINARY} was introduced in MySQL Version 3.23.0. @code{BINARY} was introduced in MySQL Version 3.23.0.
Note that in some context MySQL will not be able to use the Note that in some context MySQL will not be able to use the
...@@ -30685,7 +30688,6 @@ make string comparison even more flexible. ...@@ -30685,7 +30688,6 @@ make string comparison even more flexible.
@menu @menu
* Arithmetic functions:: Arithmetic Operations * Arithmetic functions:: Arithmetic Operations
* Mathematical functions:: Mathematical Functions * Mathematical functions:: Mathematical Functions
* Numerical casts::
@end menu @end menu
...@@ -30754,7 +30756,7 @@ in a context where its result is converted to an integer! ...@@ -30754,7 +30756,7 @@ in a context where its result is converted to an integer!
@end table @end table
@node Mathematical functions, Numerical casts, Arithmetic functions, Numeric Functions @node Mathematical functions, , Arithmetic functions, Numeric Functions
@subsubsection Mathematical Functions @subsubsection Mathematical Functions
All mathematical functions return @code{NULL} in case of an error. All mathematical functions return @code{NULL} in case of an error.
...@@ -31151,37 +31153,7 @@ The above happens because 10.28 is actually stored as something like ...@@ -31151,37 +31153,7 @@ The above happens because 10.28 is actually stored as something like
10.2799999999999999. 10.2799999999999999.
@end table @end table
@node Numerical casts, , Mathematical functions, Numeric Functions @node Date and time functions, Cast Functions, Numeric Functions, Functions
@subsubsection Casting numbers to signed / unsigned
@cindex casts, SIGNED
@cindex casts, UNSIGNED
To cast a string to a numeric value, you don't have to do anything; Just
use the string value as it would be a number:
@example
mysql> select 1+'1';
-> 2
@end example
MySQL support arithmetic with both signed and unsigned 64 bit values.
If you are using an numerical operations (like @code{+}) and one of the
operands are @code{unsigned}, then the result will be unsigned. You can
override this by using the @code{SIGNED} and @code{UNSIGNED} cast
operators, which will cast the operation to signed respective unsigned
64 bit integer.
@example
mysql> select UNSIGNED 1-2;
-> 18446744073709551615
mysql select SIGNED (UNSIGNED 1-2);
-> -1
@end example
@code{SIGNED} and @code{UNSIGNED} where added in MySQL 4.0.2.
@node Date and time functions, Other Functions, Numeric Functions, Functions
@subsection Date and Time Functions @subsection Date and Time Functions
@findex date and time functions @findex date and time functions
...@@ -31678,8 +31650,8 @@ will return the internal timestamp value directly, with no implicit ...@@ -31678,8 +31650,8 @@ will return the internal timestamp value directly, with no implicit
If you give @code{UNIX_TIMESTAMP()} a wrong or out-of-range date, it will If you give @code{UNIX_TIMESTAMP()} a wrong or out-of-range date, it will
return 0. return 0.
If you want to subtract @code{UNIX_TIMESTAMP()} columns, If you want to subtract @code{UNIX_TIMESTAMP()} columns, you may want to
@xref{Numerical casts}. cast the result to signed integers. @xref{Cast Functions}.
@findex FROM_UNIXTIME() @findex FROM_UNIXTIME()
@item FROM_UNIXTIME(unix_timestamp) @item FROM_UNIXTIME(unix_timestamp)
...@@ -31731,8 +31703,74 @@ mysql> select TIME_TO_SEC('00:39:38'); ...@@ -31731,8 +31703,74 @@ mysql> select TIME_TO_SEC('00:39:38');
@end example @end example
@end table @end table
@node Cast Functions, Other Functions, Date and time functions, Functions
@subsection Cast Functions
The syntax of the @code{CAST} function is:
@findex CAST
@findex CONVERT
@example
CAST(expression AS type)
or
CONVERT(expression,type)
@end example
Where type is one of:
@itemize @bullet
@item
@code{BINARY}
@item
@code{DATE}
@item
@code{DATETIME}
@item
@code{SIGNED @{INTEGER@}}
@item
@code{TIME}
@item
@code{UNSIGNED @{INTEGER@}}
@end itemize
@code{CAST()} is ANSI SQL99 syntax and @code{CONVERT()} is ODBC syntax.
The cast function is mainly useful when you want to create a column with
a specific type in a @code{CREATE ... SELECT}:
@example
CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE);
@end example
@code{CAST(string AS BINARY} is the same thing as @code{BINARY string}.
To cast a string to a numeric value, you don't normally have to do
anything; Just use the string value as it would be a number:
@example
mysql> select 1+'1';
-> 2
@end example
MySQL supports arithmetic with both signed and unsigned 64 bit values.
If you are using an numerical operations (like @code{+}) and one of the
operands are @code{unsigned}, then the result will be unsigned. You can
override this by using the @code{SIGNED} and @code{UNSIGNED} cast
operators, which will cast the operation to signed respective unsigned
64 bit integer.
@example
mysql> select CAST(1-2 AS UNSIGNED)
-> 18446744073709551615
mysql select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED);
-> -1
@end example
The @code{CAST()} and @code{CONVERT()} function was added in MySQL 4.0.2.
@node Other Functions, Group by functions, Date and time functions, Functions @node Other Functions, Group by functions, Cast Functions, Functions
@subsection Other Functions @subsection Other Functions
@menu @menu
...@@ -47951,7 +47989,7 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. ...@@ -47951,7 +47989,7 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@itemize @bullet @itemize @bullet
@item @item
Added cast functions @code{SIGNED} and @code{UNSIGNED}. Added @code{CAST()} and @code{CONVERT()} functions.
@item @item
Changed order of how keys are created in tables. Changed order of how keys are created in tables.
@item @item
...@@ -55,12 +55,12 @@ select min(big),max(big),max(big)-1 from t1 group by a; ...@@ -55,12 +55,12 @@ select min(big),max(big),max(big)-1 from t1 group by a;
min(big) max(big) max(big)-1 min(big) max(big) max(big)-1
-1 9223372036854775807 9223372036854775806 -1 9223372036854775807 9223372036854775806
drop table t1; drop table t1;
select UNSIGNED 1-2; select CAST(1-2 AS UNSIGNED);
UNSIGNED 1-2 CAST(1-2 AS UNSIGNED)
18446744073709551615 18446744073709551615
select SIGNED (UNSIGNED 1-2); select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
SIGNED (UNSIGNED 1-2) CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
-1 -1
select UNSIGNED '-1'; select CONVERT('-1',UNSIGNED);
UNSIGNED '-1' CONVERT('-1',UNSIGNED)
18446744073709551615 18446744073709551615
...@@ -87,7 +87,7 @@ d bigint(17) 0 ...@@ -87,7 +87,7 @@ d bigint(17) 0
e double(18,1) 0.0 e double(18,1) 0.0
f bigint(17) 0 f bigint(17) 0
drop table t2; drop table t2;
create table t2 select DATE "2001-12-29" as d, TIME "20:45:11" as t, DATETIME "2001-12-29 20:45:11" as dt; create table t2 select CAST("2001-12-29" AS DATE) as d, CAST("20:45:11" AS TIME) as t, CAST("2001-12-29 20:45:11" AS DATETIME) as dt;
describe t2; describe t2;
Field Type Null Key Default Extra Field Type Null Key Default Extra
d date 0000-00-00 d date 0000-00-00
......
drop table if exists t1;
set @`test`=1,@TEST=3,@select=2,@t5=1.23456; set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
select @test,@`select`,@TEST,@not_used; select @test,@`select`,@TEST,@not_used;
@test @`select` @TEST @not_used @test @`select` @TEST @not_used
...@@ -24,14 +25,22 @@ select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3; ...@@ -24,14 +25,22 @@ select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
select @t5; select @t5;
@t5 @t5
1.23456 1.23456
CREATE TABLE t1 (c_id INT(4) NOT NULL, c_name CHAR(20), c_country CHAR(3), PRIMARY KEY(c_id));
INSERT INTO t1 VALUES (1,'Bozo','USA'),(2,'Ronald','USA'),(3,'Kinko','IRE'),(4,'Mr. Floppy','GB');
SELECT @min_cid:=min(c_id), @max_cid:=max(c_id) from t1;
@min_cid:=min(c_id) @max_cid:=max(c_id) @min_cid:=min(c_id) @max_cid:=max(c_id)
1 4 1 4
SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid;
c_id c_name c_country c_id c_name c_country
1 Bozo USA 1 Bozo USA
4 Mr. Floppy GB 4 Mr. Floppy GB
SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid OR c_id=666;
c_id c_name c_country c_id c_name c_country
1 Bozo USA 1 Bozo USA
4 Mr. Floppy GB 4 Mr. Floppy GB
ALTER TABLE t1 DROP PRIMARY KEY;
select * from t1 where c_id=@min_cid OR c_id=@max_cid;
c_id c_name c_country c_id c_name c_country
1 Bozo USA 1 Bozo USA
4 Mr. Floppy GB 4 Mr. Floppy GB
drop table t1;
...@@ -30,6 +30,6 @@ select min(big),max(big),max(big)-1 from t1; ...@@ -30,6 +30,6 @@ select min(big),max(big),max(big)-1 from t1;
select min(big),max(big),max(big)-1 from t1 group by a; select min(big),max(big),max(big)-1 from t1 group by a;
drop table t1; drop table t1;
select UNSIGNED 1-2; select CAST(1-2 AS UNSIGNED);
select SIGNED (UNSIGNED 1-2); select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
select UNSIGNED '-1'; select CONVERT('-1',UNSIGNED);
...@@ -78,6 +78,6 @@ drop table t2; ...@@ -78,6 +78,6 @@ drop table t2;
create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f; create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f;
describe t2; describe t2;
drop table t2; drop table t2;
create table t2 select DATE "2001-12-29" as d, TIME "20:45:11" as t, DATETIME "2001-12-29 20:45:11" as dt; create table t2 select CAST("2001-12-29" AS DATE) as d, CAST("20:45:11" AS TIME) as t, CAST("2001-12-29 20:45:11" AS DATETIME) as dt;
describe t2; describe t2;
drop table t1,t2; drop table t1,t2;
...@@ -393,3 +393,18 @@ Item *create_wait_for_master_pos(Item* a, Item* b) ...@@ -393,3 +393,18 @@ Item *create_wait_for_master_pos(Item* a, Item* b)
current_thd->safe_to_cache_query=0; current_thd->safe_to_cache_query=0;
return new Item_master_pos_wait(a, b); return new Item_master_pos_wait(a, b);
} }
Item *create_func_cast(Item *a, Item_cast cast_type)
{
Item *res;
LINT_INIT(res);
switch (cast_type) {
case ITEM_CAST_BINARY: res= new Item_func_binary(a); break;
case ITEM_CAST_SIGNED_INT: res= new Item_func_signed(a); break;
case ITEM_CAST_UNSIGNED_INT: res= new Item_func_unsigned(a); break;
case ITEM_CAST_DATE: res= new Item_date_typecast(a); break;
case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
}
return res;
}
...@@ -952,3 +952,12 @@ public: ...@@ -952,3 +952,12 @@ public:
const char *func_name() const { return "match_bool"; } const char *func_name() const { return "match_bool"; }
}; };
/* For type casts */
enum Item_cast
{
ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT,
ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME
};
Item *create_func_cast(Item *a, Item_cast cast_type);
...@@ -1123,3 +1123,13 @@ longlong Item_extract::val_int() ...@@ -1123,3 +1123,13 @@ longlong Item_extract::val_int()
} }
return 0; // Impossible return 0; // Impossible
} }
void Item_typecast::print(String *str)
{
str->append("CASE(");
args[0]->print(str);
str->append(" AS ");
str->append(func_name());
str->append(')');
}
...@@ -414,14 +414,21 @@ class Item_extract :public Item_int_func ...@@ -414,14 +414,21 @@ class Item_extract :public Item_int_func
void fix_length_and_dec(); void fix_length_and_dec();
}; };
class Item_date_typecast :public Item_str_func class Item_typecast :public Item_str_func
{ {
public: public:
Item_date_typecast(Item *a) :Item_str_func(a) {} Item_typecast(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "date_typecast"; }
String *val_str(String *a) { return (args[0]->val_str(a)); } String *val_str(String *a) { return (args[0]->val_str(a)); }
void fix_length_and_dec() { max_length=args[0]->max_length; } void fix_length_and_dec() { max_length=args[0]->max_length; }
void print(String *str) { print_op(str); } void print(String *str);
};
class Item_date_typecast :public Item_typecast
{
public:
Item_date_typecast(Item *a) :Item_typecast(a) {}
const char *func_name() const { return "date"; }
void make_field(Send_field *tmp_field) void make_field(Send_field *tmp_field)
{ {
init_make_field(tmp_field,FIELD_TYPE_DATE); init_make_field(tmp_field,FIELD_TYPE_DATE);
...@@ -433,14 +440,11 @@ public: ...@@ -433,14 +440,11 @@ public:
} }
}; };
class Item_time_typecast :public Item_str_func class Item_time_typecast :public Item_typecast
{ {
public: public:
Item_time_typecast(Item *a) :Item_str_func(a) {} Item_time_typecast(Item *a) :Item_typecast(a) {}
const char *func_name() const { return "time_typecast"; } const char *func_name() const { return "time"; }
String *val_str(String *a) { return (args[0]->val_str(a)); }
void fix_length_and_dec() { max_length=args[0]->max_length; }
void print(String *str) { print_op(str); }
void make_field(Send_field *tmp_field) void make_field(Send_field *tmp_field)
{ {
init_make_field(tmp_field,FIELD_TYPE_TIME); init_make_field(tmp_field,FIELD_TYPE_TIME);
...@@ -452,14 +456,11 @@ public: ...@@ -452,14 +456,11 @@ public:
} }
}; };
class Item_datetime_typecast :public Item_str_func class Item_datetime_typecast :public Item_typecast
{ {
public: public:
Item_datetime_typecast(Item *a) :Item_str_func(a) {} Item_datetime_typecast(Item *a) :Item_typecast(a) {}
const char *func_name() const { return "datetime_typecast"; } const char *func_name() const { return "datetime"; }
String *val_str(String *a) { return (args[0]->val_str(a)); }
void fix_length_and_dec() { max_length=args[0]->max_length; }
void print(String *str) { print_op(str); }
void make_field(Send_field *tmp_field) void make_field(Send_field *tmp_field)
{ {
init_make_field(tmp_field,FIELD_TYPE_DATETIME); init_make_field(tmp_field,FIELD_TYPE_DATETIME);
......
...@@ -228,7 +228,7 @@ static SYMBOL symbols[] = { ...@@ -228,7 +228,7 @@ static SYMBOL symbols[] = {
{ "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM),0,0}, { "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM),0,0},
{ "MASTER_USER", SYM(MASTER_USER_SYM),0,0}, { "MASTER_USER", SYM(MASTER_USER_SYM),0,0},
{ "MAX_ROWS", SYM(MAX_ROWS),0,0}, { "MAX_ROWS", SYM(MAX_ROWS),0,0},
{ "MAXIMUM", SYM(MAXIMUM),0,0}, { "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR), 0,0},
{ "MATCH", SYM(MATCH),0,0}, { "MATCH", SYM(MATCH),0,0},
{ "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0}, { "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0},
{ "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0}, { "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0},
...@@ -242,7 +242,6 @@ static SYMBOL symbols[] = { ...@@ -242,7 +242,6 @@ static SYMBOL symbols[] = {
{ "MODE", SYM(MODE_SYM),0,0}, { "MODE", SYM(MODE_SYM),0,0},
{ "MODIFY", SYM(MODIFY_SYM),0,0}, { "MODIFY", SYM(MODIFY_SYM),0,0},
{ "MONTH", SYM(MONTH_SYM),0,0}, { "MONTH", SYM(MONTH_SYM),0,0},
{ "MQH", SYM(MQH_SYM),0,0},
{ "MRG_MYISAM", SYM(MERGE_SYM),0,0}, { "MRG_MYISAM", SYM(MERGE_SYM),0,0},
{ "MYISAM", SYM(MYISAM_SYM),0,0}, { "MYISAM", SYM(MYISAM_SYM),0,0},
{ "NATURAL", SYM(NATURAL),0,0}, { "NATURAL", SYM(NATURAL),0,0},
...@@ -267,7 +266,6 @@ static SYMBOL symbols[] = { ...@@ -267,7 +266,6 @@ static SYMBOL symbols[] = {
{ "PACK_KEYS", SYM(PACK_KEYS_SYM),0,0}, { "PACK_KEYS", SYM(PACK_KEYS_SYM),0,0},
{ "PARTIAL", SYM(PARTIAL),0,0}, { "PARTIAL", SYM(PARTIAL),0,0},
{ "PASSWORD", SYM(PASSWORD),0,0}, { "PASSWORD", SYM(PASSWORD),0,0},
{ "PER", SYM(PER_SYM),0,0},
{ "PURGE", SYM(PURGE),0,0}, { "PURGE", SYM(PURGE),0,0},
{ "PRECISION", SYM(PRECISION),0,0}, { "PRECISION", SYM(PRECISION),0,0},
{ "PREV", SYM(PREV_SYM),0,0}, { "PREV", SYM(PREV_SYM),0,0},
...@@ -276,7 +274,6 @@ static SYMBOL symbols[] = { ...@@ -276,7 +274,6 @@ static SYMBOL symbols[] = {
{ "PROCESS" , SYM(PROCESS),0,0}, { "PROCESS" , SYM(PROCESS),0,0},
{ "PROCESSLIST", SYM(PROCESSLIST_SYM),0,0}, { "PROCESSLIST", SYM(PROCESSLIST_SYM),0,0},
{ "PRIVILEGES", SYM(PRIVILEGES),0,0}, { "PRIVILEGES", SYM(PRIVILEGES),0,0},
{ "QUERIES", SYM(QUERIES),0,0},
{ "QUERY", SYM(QUERY_SYM),0,0}, { "QUERY", SYM(QUERY_SYM),0,0},
{ "QUICK", SYM(QUICK),0,0}, { "QUICK", SYM(QUICK),0,0},
{ "RAID0", SYM(RAID_0_SYM),0,0}, { "RAID0", SYM(RAID_0_SYM),0,0},
...@@ -305,7 +302,7 @@ static SYMBOL symbols[] = { ...@@ -305,7 +302,7 @@ static SYMBOL symbols[] = {
{ "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0}, { "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0},
{ "SESSION", SYM(SESSION_SYM),0,0}, { "SESSION", SYM(SESSION_SYM),0,0},
{ "SET", SYM(SET),0,0}, { "SET", SYM(SET),0,0},
{ "SIGNED", SYM(SIGNED),0,0}, { "SIGNED", SYM(SIGNED_SYM),0,0},
{ "SHARE", SYM(SHARE_SYM),0,0}, { "SHARE", SYM(SHARE_SYM),0,0},
{ "SHOW", SYM(SHOW),0,0}, { "SHOW", SYM(SHOW),0,0},
{ "SHUTDOWN", SYM(SHUTDOWN),0,0}, { "SHUTDOWN", SYM(SHUTDOWN),0,0},
...@@ -397,6 +394,7 @@ static SYMBOL sql_functions[] = { ...@@ -397,6 +394,7 @@ static SYMBOL sql_functions[] = {
{ "BIT_COUNT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)}, { "BIT_COUNT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)},
{ "BIT_OR", SYM(BIT_OR),0,0}, { "BIT_OR", SYM(BIT_OR),0,0},
{ "BIT_AND", SYM(BIT_AND),0,0}, { "BIT_AND", SYM(BIT_AND),0,0},
{ "CAST", SYM(CAST_SYM),0,0},
{ "CEILING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)}, { "CEILING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
{ "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, { "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
{ "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, { "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
...@@ -405,6 +403,7 @@ static SYMBOL sql_functions[] = { ...@@ -405,6 +403,7 @@ static SYMBOL sql_functions[] = {
{ "CONCAT_WS", SYM(CONCAT_WS),0,0}, { "CONCAT_WS", SYM(CONCAT_WS),0,0},
{ "CONNECTION_ID", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)}, { "CONNECTION_ID", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)},
{ "CONV", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)}, { "CONV", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)},
{ "CONVERT", SYM(CONVERT_SYM),0,0},
{ "COUNT", SYM(COUNT_SYM),0,0}, { "COUNT", SYM(COUNT_SYM),0,0},
{ "COS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)}, { "COS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)},
{ "COT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)}, { "COT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)},
......
...@@ -264,6 +264,7 @@ bool mysql_change_db(THD *thd,const char *name); ...@@ -264,6 +264,7 @@ bool mysql_change_db(THD *thd,const char *name);
void mysql_parse(THD *thd,char *inBuf,uint length); void mysql_parse(THD *thd,char *inBuf,uint length);
void mysql_init_select(LEX *lex); void mysql_init_select(LEX *lex);
bool mysql_new_select(LEX *lex); bool mysql_new_select(LEX *lex);
void mysql_init_multi_delete(LEX *lex);
void init_max_user_conn(void); void init_max_user_conn(void);
void free_max_user_conn(void); void free_max_user_conn(void);
pthread_handler_decl(handle_one_connection,arg); pthread_handler_decl(handle_one_connection,arg);
......
...@@ -2665,6 +2665,16 @@ mysql_new_select(LEX *lex) ...@@ -2665,6 +2665,16 @@ mysql_new_select(LEX *lex)
return 0; return 0;
} }
void mysql_init_multi_delete(LEX *lex)
{
lex->sql_command = SQLCOM_DELETE_MULTI;
mysql_init_select(lex);
lex->select->select_limit=HA_POS_ERROR;
lex->auxilliary_table_list=lex->select_lex.table_list;
lex->select->table_list.elements=0;
lex->select->table_list.first=0;
lex->select->table_list.next= (byte**) &(lex->select->table_list.first);
}
void void
mysql_parse(THD *thd,char *inBuf,uint length) mysql_parse(THD *thd,char *inBuf,uint length)
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000-2001 MySQL AB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -58,6 +58,7 @@ inline Item *or_or_concat(Item* A, Item* B) ...@@ -58,6 +58,7 @@ inline Item *or_or_concat(Item* A, Item* B)
enum row_type row_type; enum row_type row_type;
enum ha_rkey_function ha_rkey_mode; enum ha_rkey_function ha_rkey_mode;
enum enum_tx_isolation tx_isolation; enum enum_tx_isolation tx_isolation;
enum Item_cast cast_type;
String *string; String *string;
key_part_spec *key_part; key_part_spec *key_part;
TABLE_LIST *table_list; TABLE_LIST *table_list;
...@@ -81,11 +82,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -81,11 +82,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token NEXT_SYM %token NEXT_SYM
%token PREV_SYM %token PREV_SYM
%token SQL_CALC_FOUND_ROWS %token SQL_CALC_FOUND_ROWS
%token QUERIES
%token MQH_SYM
%token PER_SYM
%token MAXIMUM
%token EQ %token EQ
%token EQUAL_SYM %token EQUAL_SYM
...@@ -161,6 +157,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -161,6 +157,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token BY %token BY
%token CACHE_SYM %token CACHE_SYM
%token CASCADE %token CASCADE
%token CAST_SYM
%token CHECKSUM_SYM %token CHECKSUM_SYM
%token CHECK_SYM %token CHECK_SYM
%token CIPHER %token CIPHER
...@@ -169,6 +166,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -169,6 +166,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token COLUMN_SYM %token COLUMN_SYM
%token CONCURRENT %token CONCURRENT
%token CONSTRAINT %token CONSTRAINT
%token CONVERT_SYM
%token DATABASES %token DATABASES
%token DATA_SYM %token DATA_SYM
%token DEFAULT %token DEFAULT
...@@ -243,6 +241,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -243,6 +241,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MASTER_SERVER_ID_SYM %token MASTER_SERVER_ID_SYM
%token MATCH %token MATCH
%token MAX_ROWS %token MAX_ROWS
%token MAX_QUERIES_PER_HOUR
%token MEDIUM_SYM %token MEDIUM_SYM
%token MERGE_SYM %token MERGE_SYM
%token MIN_ROWS %token MIN_ROWS
...@@ -356,7 +355,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -356,7 +355,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token PRECISION %token PRECISION
%token QUICK %token QUICK
%token REAL %token REAL
%token SIGNED %token SIGNED_SYM
%token SMALLINT %token SMALLINT
%token STRING_SYM %token STRING_SYM
%token TEXT_SYM %token TEXT_SYM
...@@ -487,11 +486,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -487,11 +486,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%left NEG '~' %left NEG '~'
%right NOT %right NOT
%right BINARY %right BINARY
%right SIGNED
%right UNSIGNED
%right DATE_SYM
%right TIME_SYM
%right DATETIME
%type <lex_str> %type <lex_str>
IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME
...@@ -556,6 +550,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -556,6 +550,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <ha_rkey_mode> handler_rkey_mode %type <ha_rkey_mode> handler_rkey_mode
%type <cast_type> cast_type
%type <udf_type> udf_func_type %type <udf_type> udf_func_type
%type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword %type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword
...@@ -1020,7 +1016,7 @@ field_opt_list: ...@@ -1020,7 +1016,7 @@ field_opt_list:
| field_option {} | field_option {}
field_option: field_option:
SIGNED {} SIGNED_SYM {}
| UNSIGNED { Lex->type|= UNSIGNED_FLAG;} | UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
| ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; } | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
...@@ -1608,13 +1604,10 @@ simple_expr: ...@@ -1608,13 +1604,10 @@ simple_expr:
{ Select->ftfunc_list.push_back((Item_func_match *) { Select->ftfunc_list.push_back((Item_func_match *)
($$=new Item_func_match_bool(*$2,$5))); } ($$=new Item_func_match_bool(*$2,$5))); }
| BINARY expr %prec NEG { $$= new Item_func_binary($2); } | BINARY expr %prec NEG { $$= new Item_func_binary($2); }
| SIGNED expr %prec NEG { $$= new Item_func_signed($2); } | CAST_SYM '(' expr AS cast_type ')' { $$= create_func_cast($3, $5); }
| UNSIGNED expr %prec NEG { $$= new Item_func_unsigned($2); }
| DATE_SYM expr { $$= new Item_date_typecast($2); }
| TIME_SYM expr { $$= new Item_time_typecast($2); }
| DATETIME expr { $$= new Item_datetime_typecast($2); }
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END | CASE_SYM opt_expr WHEN_SYM when_list opt_else END
{ $$= new Item_func_case(* $4, $2, $5 ) } { $$= new Item_func_case(* $4, $2, $5 ) }
| CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); }
| FUNC_ARG0 '(' ')' | FUNC_ARG0 '(' ')'
{ $$= ((Item*(*)(void))($1.symbol->create_func))();} { $$= ((Item*(*)(void))($1.symbol->create_func))();}
| FUNC_ARG1 '(' expr ')' | FUNC_ARG1 '(' expr ')'
...@@ -1886,6 +1879,16 @@ in_sum_expr: ...@@ -1886,6 +1879,16 @@ in_sum_expr:
$$=$2; $$=$2;
} }
cast_type:
BINARY { $$=ITEM_CAST_BINARY; }
| SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; }
| SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; }
| UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; }
| UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; }
| DATE_SYM { $$=ITEM_CAST_DATE; }
| TIME_SYM { $$=ITEM_CAST_TIME; }
| DATETIME { $$=ITEM_CAST_DATETIME; }
expr_list: expr_list:
{ Select->expr_list.push_front(new List<Item>); } { Select->expr_list.push_front(new List<Item>); }
expr_list2 expr_list2
...@@ -2113,9 +2116,10 @@ opt_order_clause: ...@@ -2113,9 +2116,10 @@ opt_order_clause:
order_clause: order_clause:
ORDER_SYM BY ORDER_SYM BY
{ {
if (Lex->sql_command==SQLCOM_MULTI_UPDATE) LEX *lex=Lex;
if (lex->sql_command == SQLCOM_MULTI_UPDATE)
YYABORT; YYABORT;
Select->sort_default=1; lex->select->sort_default=1;
} order_list } order_list
order_list: order_list:
...@@ -2135,7 +2139,8 @@ limit_clause: ...@@ -2135,7 +2139,8 @@ limit_clause:
| LIMIT ULONG_NUM | LIMIT ULONG_NUM
{ {
SELECT_LEX *sel=Select; SELECT_LEX *sel=Select;
sel->select_limit= $2; sel->offset_limit=0L; sel->select_limit= $2;
sel->offset_limit=0L;
} }
| LIMIT ULONG_NUM ',' ULONG_NUM | LIMIT ULONG_NUM ',' ULONG_NUM
{ {
...@@ -2146,9 +2151,10 @@ limit_clause: ...@@ -2146,9 +2151,10 @@ limit_clause:
delete_limit_clause: delete_limit_clause:
/* empty */ /* empty */
{ {
if (Lex->sql_command==SQLCOM_MULTI_UPDATE) LEX *lex=Lex;
if (lex->sql_command == SQLCOM_MULTI_UPDATE)
YYABORT; YYABORT;
Select->select_limit= HA_POS_ERROR; lex->select->select_limit= HA_POS_ERROR;
} }
| LIMIT ulonglong_num | LIMIT ulonglong_num
{ Select->select_limit= (ha_rows) $2; } { Select->select_limit= (ha_rows) $2; }
...@@ -2438,42 +2444,11 @@ delete: ...@@ -2438,42 +2444,11 @@ delete:
single_multi: single_multi:
FROM table_name where_clause opt_order_clause delete_limit_clause {} FROM table_name where_clause opt_order_clause delete_limit_clause {}
| table_wild_list | table_wild_list
{ { mysql_init_multi_delete(Lex); }
LEX *lex=Lex; FROM join_table_list where_clause
lex->sql_command = SQLCOM_DELETE_MULTI;
mysql_init_select(lex);
lex->select->select_limit=HA_POS_ERROR;
lex->auxilliary_table_list.elements=0;
lex->auxilliary_table_list.first=0;
lex->auxilliary_table_list.next= (byte**) &(lex->auxilliary_table_list.first);
}
FROM
{
LEX *lex=Lex;
lex->auxilliary_table_list=lex->select_lex.table_list;
lex->select->table_list.elements=0;
lex->select->table_list.first=0;
lex->select->table_list.next= (byte**) &(lex->select->table_list.first);
} join_table_list where_clause
| FROM table_wild_list | FROM table_wild_list
{ { mysql_init_multi_delete(Lex); }
LEX *lex=Lex; USING join_table_list where_clause
lex->sql_command = SQLCOM_DELETE_MULTI;
mysql_init_select(lex);
lex->select->select_limit=HA_POS_ERROR;
lex->auxilliary_table_list.elements=0;
lex->auxilliary_table_list.first=0;
lex->auxilliary_table_list.next= (byte**) &(lex->auxilliary_table_list.first);
}
USING
{
LEX *lex=Lex;
lex->auxilliary_table_list=lex->select_lex.table_list;
lex->select->table_list.elements=0;
lex->select->table_list.first=0;
lex->select->table_list.next= (byte**) &(lex->select->table_list.first);
} join_table_list where_clause
table_wild_list: table_wild_list:
table_wild_one {} table_wild_one {}
...@@ -3019,6 +2994,7 @@ keyword: ...@@ -3019,6 +2994,7 @@ keyword:
| MASTER_USER_SYM {} | MASTER_USER_SYM {}
| MASTER_PASSWORD_SYM {} | MASTER_PASSWORD_SYM {}
| MASTER_CONNECT_RETRY_SYM {} | MASTER_CONNECT_RETRY_SYM {}
| MAX_QUERIES_PER_HOUR {}
| MEDIUM_SYM {} | MEDIUM_SYM {}
| MERGE_SYM {} | MERGE_SYM {}
| MINUTE_SYM {} | MINUTE_SYM {}
...@@ -3058,6 +3034,7 @@ keyword: ...@@ -3058,6 +3034,7 @@ keyword:
| SECOND_SYM {} | SECOND_SYM {}
| SERIALIZABLE_SYM {} | SERIALIZABLE_SYM {}
| SESSION_SYM {} | SESSION_SYM {}
| SIGNED_SYM {}
| SHARE_SYM {} | SHARE_SYM {}
| SHUTDOWN {} | SHUTDOWN {}
| SLAVE {} | SLAVE {}
...@@ -3607,17 +3584,13 @@ grant_option: ...@@ -3607,17 +3584,13 @@ grant_option:
mqh_option: mqh_option:
/* empty */ {} /* empty */ {}
| AND WITH short_or_long_one EQ NUM | AND WITH MAX_QUERIES_PER_HOUR EQ NUM
{ {
Lex->mqh=atoi($5.str); Lex->mqh=atoi($5.str);
if (Lex->mqh > 65535) if (Lex->mqh > 65535)
YYABORT; YYABORT;
} }
short_or_long_one:
MQH_SYM
| MAXIMUM QUERIES PER_SYM HOUR_SYM
begin: begin:
BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work
......
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