mirror of
https://github.com/MariaDB/server.git
synced 2025-07-04 01:23:45 +03:00
parser cleanup: don't store field properties in LEX, use Create_field directly
length/dec/charset are still in LEX, because they're also used for CAST and dynamic columns. also 1. fix "MDEV-7041 COLLATION(CAST('a' AS CHAR BINARY)) returns a wrong result" 2. allow BINARY modifier in stored function RETURN clause 3. allow "COLLATION without CHARSET" in SP/SF (parameters, RETURN, DECLARE) 4. print correct variable name in error messages for stored routine parameters
This commit is contained in:
@ -796,3 +796,26 @@ DATE("foo")
|
|||||||
NULL
|
NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect datetime value: 'foo'
|
Warning 1292 Incorrect datetime value: 'foo'
|
||||||
|
create table t1 (a int, b char(5) as (cast("a" as char(10) binary) + a) );
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` char(5) AS (cast("a" as char(10) binary) + a) VIRTUAL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
select collation(cast("a" as char(10) binary));
|
||||||
|
collation(cast("a" as char(10) binary))
|
||||||
|
latin1_bin
|
||||||
|
select collation(cast("a" as char(10) charset utf8 binary));
|
||||||
|
collation(cast("a" as char(10) charset utf8 binary))
|
||||||
|
utf8_bin
|
||||||
|
select collation(cast("a" as char(10) ascii binary));
|
||||||
|
collation(cast("a" as char(10) ascii binary))
|
||||||
|
latin1_bin
|
||||||
|
select collation(cast("a" as char(10) binary charset utf8));
|
||||||
|
collation(cast("a" as char(10) binary charset utf8))
|
||||||
|
utf8_bin
|
||||||
|
select collation(cast("a" as char(10) binary ascii));
|
||||||
|
collation(cast("a" as char(10) binary ascii))
|
||||||
|
latin1_bin
|
||||||
|
@ -5535,3 +5535,12 @@ a aa
|
|||||||
#
|
#
|
||||||
# End of 10.0 tests
|
# End of 10.0 tests
|
||||||
#
|
#
|
||||||
|
select collation(cast("a" as char(10) unicode binary));
|
||||||
|
collation(cast("a" as char(10) unicode binary))
|
||||||
|
ucs2_bin
|
||||||
|
select collation(cast("a" as char(10) binary unicode));
|
||||||
|
collation(cast("a" as char(10) binary unicode))
|
||||||
|
ucs2_bin
|
||||||
|
#
|
||||||
|
# End of 10.1 tests
|
||||||
|
#
|
||||||
|
@ -1411,7 +1411,7 @@ end|
|
|||||||
ERROR 0A000: Not allowed to return a result set from a function
|
ERROR 0A000: Not allowed to return a result set from a function
|
||||||
drop function if exists bug20701;
|
drop function if exists bug20701;
|
||||||
create function bug20701() returns varchar(25) binary return "test";
|
create function bug20701() returns varchar(25) binary return "test";
|
||||||
ERROR 42000: This version of MariaDB doesn't yet support 'return value collation'
|
drop function bug20701;
|
||||||
create function bug20701() returns varchar(25) return "test";
|
create function bug20701() returns varchar(25) return "test";
|
||||||
drop function bug20701;
|
drop function bug20701;
|
||||||
create procedure proc_26503_error_1()
|
create procedure proc_26503_error_1()
|
||||||
|
@ -106,20 +106,20 @@ RETURNS VARCHAR(64) CHARACTER SET ucs2
|
|||||||
BEGIN
|
BEGIN
|
||||||
RETURN 'str';
|
RETURN 'str';
|
||||||
END|
|
END|
|
||||||
ERROR 42000: This version of MariaDB doesn't yet support 'COLLATE with no CHARACTER SET in SP parameters, RETURNS, DECLARE'
|
ERROR 42000: COLLATION 'ucs2_unicode_ci' is not valid for CHARACTER SET 'latin1'
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
||||||
RETURNS VARCHAR(64) COLLATE ucs2_unicode_ci
|
RETURNS VARCHAR(64) COLLATE ucs2_unicode_ci
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN 'str';
|
RETURN 'str';
|
||||||
END|
|
END|
|
||||||
ERROR 42000: This version of MariaDB doesn't yet support 'COLLATE with no CHARACTER SET in SP parameters, RETURNS, DECLARE'
|
ERROR 42000: COLLATION 'ucs2_unicode_ci' is not valid for CHARACTER SET 'latin1'
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
||||||
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE f2 VARCHAR(64) COLLATE ucs2_unicode_ci;
|
DECLARE f2 VARCHAR(64) COLLATE ucs2_unicode_ci;
|
||||||
RETURN 'str';
|
RETURN 'str';
|
||||||
END|
|
END|
|
||||||
ERROR 42000: This version of MariaDB doesn't yet support 'COLLATE with no CHARACTER SET in SP parameters, RETURNS, DECLARE'
|
ERROR 42000: COLLATION 'ucs2_unicode_ci' is not valid for CHARACTER SET 'latin1'
|
||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
DROP FUNCTION IF EXISTS bug48766;
|
DROP FUNCTION IF EXISTS bug48766;
|
||||||
CREATE FUNCTION bug48766 ()
|
CREATE FUNCTION bug48766 ()
|
||||||
|
@ -3548,7 +3548,10 @@ begin
|
|||||||
set f1= concat( 'hello', f1 );
|
set f1= concat( 'hello', f1 );
|
||||||
return f1;
|
return f1;
|
||||||
end|
|
end|
|
||||||
ERROR 42000: This version of MariaDB doesn't yet support 'return value collation'
|
select collation(bug9048("foo"))|
|
||||||
|
collation(bug9048("foo"))
|
||||||
|
latin1_bin
|
||||||
|
drop function bug9048|
|
||||||
drop procedure if exists bug12849_1|
|
drop procedure if exists bug12849_1|
|
||||||
create procedure bug12849_1(inout x char) select x into x|
|
create procedure bug12849_1(inout x char) select x into x|
|
||||||
set @var='a'|
|
set @var='a'|
|
||||||
@ -7858,3 +7861,22 @@ v1
|
|||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
# End of 5.5 test
|
# End of 5.5 test
|
||||||
|
CREATE FUNCTION f(f1 VARCHAR(64) COLLATE latin1_german2_ci)
|
||||||
|
RETURNS VARCHAR(64)
|
||||||
|
BEGIN
|
||||||
|
RETURN 'str';
|
||||||
|
END|
|
||||||
|
DROP FUNCTION f|
|
||||||
|
CREATE FUNCTION f(f1 VARCHAR(64))
|
||||||
|
RETURNS VARCHAR(64) COLLATE latin1_german2_ci
|
||||||
|
BEGIN
|
||||||
|
RETURN 'str';
|
||||||
|
END|
|
||||||
|
DROP FUNCTION f|
|
||||||
|
CREATE FUNCTION f(f1 VARCHAR(64))
|
||||||
|
RETURNS VARCHAR(64)
|
||||||
|
BEGIN
|
||||||
|
DECLARE f2 VARCHAR(64) COLLATE latin1_german2_ci;
|
||||||
|
RETURN 'str';
|
||||||
|
END|
|
||||||
|
DROP FUNCTION f|
|
||||||
|
@ -142,7 +142,7 @@ BEGIN
|
|||||||
SET @v1 = f1;
|
SET @v1 = f1;
|
||||||
SELECT @v1;
|
SELECT @v1;
|
||||||
END//
|
END//
|
||||||
ERROR 42000: Too big precision 256 specified for ''. Maximum is 65.
|
ERROR 42000: Too big precision 256 specified for 'f1'. Maximum is 65.
|
||||||
DROP PROCEDURE IF EXISTS sp1//
|
DROP PROCEDURE IF EXISTS sp1//
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1305 PROCEDURE db_storedproc.sp1 does not exist
|
Note 1305 PROCEDURE db_storedproc.sp1 does not exist
|
||||||
@ -152,7 +152,7 @@ BEGIN
|
|||||||
SET @v1 = f1;
|
SET @v1 = f1;
|
||||||
SELECT @v1;
|
SELECT @v1;
|
||||||
END//
|
END//
|
||||||
ERROR 42000: Too big precision 66 specified for ''. Maximum is 65.
|
ERROR 42000: Too big precision 66 specified for 'f1'. Maximum is 65.
|
||||||
DROP PROCEDURE IF EXISTS sp1//
|
DROP PROCEDURE IF EXISTS sp1//
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1305 PROCEDURE db_storedproc.sp1 does not exist
|
Note 1305 PROCEDURE db_storedproc.sp1 does not exist
|
||||||
@ -1407,12 +1407,12 @@ BEGIN
|
|||||||
SELECT f1;
|
SELECT f1;
|
||||||
END//
|
END//
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1291 Column '' has duplicated value 'value1' in ENUM
|
Note 1291 Column 'f1' has duplicated value 'value1' in ENUM
|
||||||
CALL sp1( "value1" );
|
CALL sp1( "value1" );
|
||||||
f1
|
f1
|
||||||
value1
|
value1
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1291 Column '' has duplicated value 'value1' in ENUM
|
Note 1291 Column 'f1' has duplicated value 'value1' in ENUM
|
||||||
SHOW PROCEDURE STATUS WHERE db = 'db_storedproc';
|
SHOW PROCEDURE STATUS WHERE db = 'db_storedproc';
|
||||||
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
|
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
|
||||||
db_storedproc sp1 PROCEDURE root@localhost <modified> <created> INVOKER this is simple latin1 latin1_swedish_ci latin1_swedish_ci
|
db_storedproc sp1 PROCEDURE root@localhost <modified> <created> INVOKER this is simple latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
@ -1423,12 +1423,12 @@ BEGIN
|
|||||||
SELECT f1;
|
SELECT f1;
|
||||||
END//
|
END//
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1291 Column '' has duplicated value 'value1' in SET
|
Note 1291 Column 'f1' has duplicated value 'value1' in SET
|
||||||
CALL sp1( "value1, value1" );
|
CALL sp1( "value1, value1" );
|
||||||
f1
|
f1
|
||||||
value1
|
value1
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1291 Column '' has duplicated value 'value1' in SET
|
Note 1291 Column 'f1' has duplicated value 'value1' in SET
|
||||||
Warning 1265 Data truncated for column 'f1' at row 1
|
Warning 1265 Data truncated for column 'f1' at row 1
|
||||||
SHOW PROCEDURE STATUS WHERE db = 'db_storedproc';
|
SHOW PROCEDURE STATUS WHERE db = 'db_storedproc';
|
||||||
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
|
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
|
||||||
@ -1440,12 +1440,12 @@ BEGIN
|
|||||||
SELECT f1;
|
SELECT f1;
|
||||||
END//
|
END//
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1291 Column '' has duplicated value 'value1' in ENUM
|
Note 1291 Column 'f1' has duplicated value 'value1' in ENUM
|
||||||
CALL sp1( "value1" );
|
CALL sp1( "value1" );
|
||||||
f1
|
f1
|
||||||
value1
|
value1
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1291 Column '' has duplicated value 'value1' in ENUM
|
Note 1291 Column 'f1' has duplicated value 'value1' in ENUM
|
||||||
SHOW PROCEDURE STATUS WHERE db = 'db_storedproc';
|
SHOW PROCEDURE STATUS WHERE db = 'db_storedproc';
|
||||||
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
|
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
|
||||||
db_storedproc sp1 PROCEDURE root@localhost <modified> <created> INVOKER this is simple latin1 latin1_swedish_ci latin1_swedish_ci
|
db_storedproc sp1 PROCEDURE root@localhost <modified> <created> INVOKER this is simple latin1 latin1_swedish_ci latin1_swedish_ci
|
||||||
@ -1548,7 +1548,7 @@ BEGIN
|
|||||||
SET f1 = 1000000 + f1;
|
SET f1 = 1000000 + f1;
|
||||||
RETURN f1;
|
RETURN f1;
|
||||||
END//
|
END//
|
||||||
ERROR 42000: Too big scale 31 specified for ''. Maximum is 30.
|
ERROR 42000: Too big scale 31 specified for 'f1'. Maximum is 30.
|
||||||
SELECT fn1( 1.3326e+8 );
|
SELECT fn1( 1.3326e+8 );
|
||||||
ERROR 42000: FUNCTION db_storedproc.fn1 does not exist
|
ERROR 42000: FUNCTION db_storedproc.fn1 does not exist
|
||||||
CREATE FUNCTION fn1( f1 DECIMAL(63, 30) ) RETURNS DECIMAL(63, 30)
|
CREATE FUNCTION fn1( f1 DECIMAL(63, 30) ) RETURNS DECIMAL(63, 30)
|
||||||
@ -1570,7 +1570,7 @@ BEGIN
|
|||||||
RETURN f1;
|
RETURN f1;
|
||||||
END//
|
END//
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1291 Column '' has duplicated value 'value1' in ENUM
|
Note 1291 Column 'f1' has duplicated value 'value1' in ENUM
|
||||||
SELECT fn1( "value1" );
|
SELECT fn1( "value1" );
|
||||||
fn1( "value1" )
|
fn1( "value1" )
|
||||||
1.000000000000000000000000000000
|
1.000000000000000000000000000000
|
||||||
@ -1584,7 +1584,7 @@ BEGIN
|
|||||||
RETURN f1;
|
RETURN f1;
|
||||||
END//
|
END//
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1291 Column '' has duplicated value 'value1' in SET
|
Note 1291 Column 'f1' has duplicated value 'value1' in SET
|
||||||
SELECT fn1( "value1, value1" );
|
SELECT fn1( "value1, value1" );
|
||||||
fn1( "value1, value1" )
|
fn1( "value1, value1" )
|
||||||
1.000000000000000000000000000000
|
1.000000000000000000000000000000
|
||||||
@ -3119,10 +3119,7 @@ return f1;
|
|||||||
DROP FUNCTION IF EXISTS fn1;
|
DROP FUNCTION IF EXISTS fn1;
|
||||||
CREATE FUNCTION fn1(f1 char binary ) returns char binary
|
CREATE FUNCTION fn1(f1 char binary ) returns char binary
|
||||||
return f1;
|
return f1;
|
||||||
ERROR 42000: This version of MariaDB doesn't yet support 'return value collation'
|
|
||||||
DROP FUNCTION IF EXISTS fn1;
|
DROP FUNCTION IF EXISTS fn1;
|
||||||
Warnings:
|
|
||||||
Note 1305 FUNCTION db_storedproc.fn1 does not exist
|
|
||||||
CREATE FUNCTION fn1(f1 char ascii ) returns char ascii
|
CREATE FUNCTION fn1(f1 char ascii ) returns char ascii
|
||||||
return f1;
|
return f1;
|
||||||
DROP FUNCTION IF EXISTS fn1;
|
DROP FUNCTION IF EXISTS fn1;
|
||||||
@ -5836,7 +5833,7 @@ fetch cur1 into e;
|
|||||||
SELECT x, y, z, a, b, c, d, e;
|
SELECT x, y, z, a, b, c, d, e;
|
||||||
close cur1;
|
close cur1;
|
||||||
END//
|
END//
|
||||||
ERROR 42000: Too big scale 255 specified for ''. Maximum is 30.
|
ERROR 42000: Too big scale 255 specified for 'b'. Maximum is 30.
|
||||||
CALL sp6();
|
CALL sp6();
|
||||||
ERROR 42000: PROCEDURE db_storedproc.sp6 does not exist
|
ERROR 42000: PROCEDURE db_storedproc.sp6 does not exist
|
||||||
DROP PROCEDURE IF EXISTS sp6;
|
DROP PROCEDURE IF EXISTS sp6;
|
||||||
|
@ -2155,7 +2155,6 @@ CREATE FUNCTION fn1(f1 char ) returns char
|
|||||||
return f1;
|
return f1;
|
||||||
|
|
||||||
DROP FUNCTION IF EXISTS fn1;
|
DROP FUNCTION IF EXISTS fn1;
|
||||||
--error ER_NOT_SUPPORTED_YET
|
|
||||||
CREATE FUNCTION fn1(f1 char binary ) returns char binary
|
CREATE FUNCTION fn1(f1 char binary ) returns char binary
|
||||||
return f1;
|
return f1;
|
||||||
|
|
||||||
|
@ -456,3 +456,19 @@ SELECT CAST(TIME('10:20:30') AS DATE) + INTERVAL 1 DAY;
|
|||||||
SET SQL_MODE=ALLOW_INVALID_DATES;
|
SET SQL_MODE=ALLOW_INVALID_DATES;
|
||||||
SELECT DATE("foo");
|
SELECT DATE("foo");
|
||||||
|
|
||||||
|
#
|
||||||
|
# CAST and field definition using same fields in LEX
|
||||||
|
#
|
||||||
|
create table t1 (a int, b char(5) as (cast("a" as char(10) binary) + a) );
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# CAST (... BINARY)
|
||||||
|
#
|
||||||
|
select collation(cast("a" as char(10) binary));
|
||||||
|
select collation(cast("a" as char(10) charset utf8 binary));
|
||||||
|
select collation(cast("a" as char(10) ascii binary));
|
||||||
|
select collation(cast("a" as char(10) binary charset utf8));
|
||||||
|
select collation(cast("a" as char(10) binary ascii));
|
||||||
|
|
||||||
|
@ -914,7 +914,16 @@ SELECT CONCAT(CONVERT('pi=' USING ucs2),PI()) AS PI;
|
|||||||
SET NAMES utf8, character_set_connection=ucs2;
|
SET NAMES utf8, character_set_connection=ucs2;
|
||||||
SELECT 'a','aa';
|
SELECT 'a','aa';
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.0 tests
|
--echo # End of 10.0 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
#
|
||||||
|
# CAST (... BINARY)
|
||||||
|
#
|
||||||
|
select collation(cast("a" as char(10) unicode binary));
|
||||||
|
select collation(cast("a" as char(10) binary unicode));
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.1 tests
|
||||||
|
--echo #
|
||||||
|
@ -2051,13 +2051,8 @@ delimiter ;|
|
|||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop function if exists bug20701;
|
drop function if exists bug20701;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
#
|
|
||||||
# This was disabled in 5.1.12. See bug #20701
|
|
||||||
# When collation support in SP is implemented, then this test should
|
|
||||||
# be removed.
|
|
||||||
#
|
|
||||||
--error ER_NOT_SUPPORTED_YET
|
|
||||||
create function bug20701() returns varchar(25) binary return "test";
|
create function bug20701() returns varchar(25) binary return "test";
|
||||||
|
drop function bug20701;
|
||||||
create function bug20701() returns varchar(25) return "test";
|
create function bug20701() returns varchar(25) return "test";
|
||||||
drop function bug20701;
|
drop function bug20701;
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ DROP FUNCTION f1|
|
|||||||
#
|
#
|
||||||
# COLLATE with no CHARACTER SET in IN param
|
# COLLATE with no CHARACTER SET in IN param
|
||||||
#
|
#
|
||||||
--error ER_NOT_SUPPORTED_YET
|
--error ER_COLLATION_CHARSET_MISMATCH
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) COLLATE ucs2_unicode_ci)
|
CREATE FUNCTION f(f1 VARCHAR(64) COLLATE ucs2_unicode_ci)
|
||||||
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -125,7 +125,7 @@ END|
|
|||||||
#
|
#
|
||||||
# COLLATE with no CHARACTER SET in RETURNS
|
# COLLATE with no CHARACTER SET in RETURNS
|
||||||
#
|
#
|
||||||
--error ER_NOT_SUPPORTED_YET
|
--error ER_COLLATION_CHARSET_MISMATCH
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
||||||
RETURNS VARCHAR(64) COLLATE ucs2_unicode_ci
|
RETURNS VARCHAR(64) COLLATE ucs2_unicode_ci
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -136,7 +136,7 @@ END|
|
|||||||
#
|
#
|
||||||
# COLLATE with no CHARACTER SET in DECLARE
|
# COLLATE with no CHARACTER SET in DECLARE
|
||||||
#
|
#
|
||||||
--error ER_NOT_SUPPORTED_YET
|
--error ER_COLLATION_CHARSET_MISMATCH
|
||||||
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
CREATE FUNCTION f(f1 VARCHAR(64) CHARACTER SET ucs2)
|
||||||
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
RETURNS VARCHAR(64) CHARACTER SET ucs2
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -4355,17 +4355,14 @@ begin
|
|||||||
return f1;
|
return f1;
|
||||||
end|
|
end|
|
||||||
drop function bug9048|
|
drop function bug9048|
|
||||||
#
|
|
||||||
# This was disabled in 5.1.12. See bug #20701
|
|
||||||
# When collation support in SP is implemented, then this test should
|
|
||||||
# be removed.
|
|
||||||
#
|
|
||||||
--error ER_NOT_SUPPORTED_YET
|
|
||||||
create function bug9048(f1 char binary) returns char binary
|
create function bug9048(f1 char binary) returns char binary
|
||||||
begin
|
begin
|
||||||
set f1= concat( 'hello', f1 );
|
set f1= concat( 'hello', f1 );
|
||||||
return f1;
|
return f1;
|
||||||
end|
|
end|
|
||||||
|
select collation(bug9048("foo"))|
|
||||||
|
drop function bug9048|
|
||||||
|
|
||||||
# Bug #12849 Stored Procedure: Crash on procedure call with CHAR type
|
# Bug #12849 Stored Procedure: Crash on procedure call with CHAR type
|
||||||
# 'INOUT' parameter
|
# 'INOUT' parameter
|
||||||
@ -9303,3 +9300,27 @@ DROP PROCEDURE p1;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo # End of 5.5 test
|
--echo # End of 5.5 test
|
||||||
|
|
||||||
|
DELIMITER |;
|
||||||
|
CREATE FUNCTION f(f1 VARCHAR(64) COLLATE latin1_german2_ci)
|
||||||
|
RETURNS VARCHAR(64)
|
||||||
|
BEGIN
|
||||||
|
RETURN 'str';
|
||||||
|
END|
|
||||||
|
DROP FUNCTION f|
|
||||||
|
|
||||||
|
CREATE FUNCTION f(f1 VARCHAR(64))
|
||||||
|
RETURNS VARCHAR(64) COLLATE latin1_german2_ci
|
||||||
|
BEGIN
|
||||||
|
RETURN 'str';
|
||||||
|
END|
|
||||||
|
DROP FUNCTION f|
|
||||||
|
|
||||||
|
CREATE FUNCTION f(f1 VARCHAR(64))
|
||||||
|
RETURNS VARCHAR(64)
|
||||||
|
BEGIN
|
||||||
|
DECLARE f2 VARCHAR(64) COLLATE latin1_german2_ci;
|
||||||
|
RETURN 'str';
|
||||||
|
END|
|
||||||
|
DROP FUNCTION f|
|
||||||
|
DELIMITER ;|
|
||||||
|
282
sql/field.cc
282
sql/field.cc
@ -9163,96 +9163,100 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
static inline bool is_item_func(Item* x)
|
||||||
Initialize field definition for create.
|
|
||||||
|
|
||||||
@param thd Thread handle
|
|
||||||
@param fld_name Field name
|
|
||||||
@param fld_type Field type
|
|
||||||
@param fld_length Field length
|
|
||||||
@param fld_decimals Decimal (if any)
|
|
||||||
@param fld_type_modifier Additional type information
|
|
||||||
@param fld_default_value Field default value (if any)
|
|
||||||
@param fld_on_update_value The value of ON UPDATE clause
|
|
||||||
@param fld_comment Field comment
|
|
||||||
@param fld_change Field change
|
|
||||||
@param fld_interval_list Interval list (if any)
|
|
||||||
@param fld_charset Field charset
|
|
||||||
@param fld_geom_type Field geometry type (if any)
|
|
||||||
@param fld_vcol_info Virtual column data
|
|
||||||
|
|
||||||
@retval
|
|
||||||
FALSE on success
|
|
||||||
@retval
|
|
||||||
TRUE on error
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|
||||||
char *fld_length, char *fld_decimals,
|
|
||||||
uint fld_type_modifier, Item *fld_default_value,
|
|
||||||
Item *fld_on_update_value, LEX_STRING *fld_comment,
|
|
||||||
char *fld_change, List<String> *fld_interval_list,
|
|
||||||
CHARSET_INFO *fld_charset, uint fld_geom_type,
|
|
||||||
Virtual_column_info *fld_vcol_info,
|
|
||||||
engine_option_value *create_opt, bool check_exists)
|
|
||||||
{
|
{
|
||||||
|
return x != NULL && x->type() == Item::FUNC_ITEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Create_field::check(THD *thd)
|
||||||
|
{
|
||||||
|
const uint conditional_type_modifiers= AUTO_INCREMENT_FLAG;
|
||||||
uint sign_len, allowed_type_modifier= 0;
|
uint sign_len, allowed_type_modifier= 0;
|
||||||
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
|
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
|
||||||
const bool on_update_is_function=
|
DBUG_ENTER("Create_field::check");
|
||||||
(fld_on_update_value != NULL &&
|
|
||||||
fld_on_update_value->type() == Item::FUNC_ITEM);
|
|
||||||
|
|
||||||
DBUG_ENTER("Create_field::init()");
|
if (vcol_info)
|
||||||
|
{
|
||||||
|
vcol_info->set_field_type(sql_type);
|
||||||
|
sql_type= (enum enum_field_types)MYSQL_TYPE_VIRTUAL;
|
||||||
|
}
|
||||||
|
|
||||||
field= 0;
|
if (length > MAX_FIELD_BLOBLENGTH)
|
||||||
field_name= fld_name;
|
{
|
||||||
flags= fld_type_modifier;
|
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name, MAX_FIELD_BLOBLENGTH);
|
||||||
option_list= create_opt;
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (fld_default_value != NULL && fld_default_value->type() == Item::FUNC_ITEM)
|
if (decimals >= NOT_FIXED_DEC)
|
||||||
|
{
|
||||||
|
my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, field_name,
|
||||||
|
static_cast<ulong>(NOT_FIXED_DEC - 1));
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Default value should be literal => basic constants =>
|
||||||
|
no need fix_fields()
|
||||||
|
|
||||||
|
We allow only one function as part of default value -
|
||||||
|
NOW() as default for TIMESTAMP and DATETIME type.
|
||||||
|
*/
|
||||||
|
if (def->type() == Item::FUNC_ITEM &&
|
||||||
|
(static_cast<Item_func*>(def)->functype() != Item_func::NOW_FUNC ||
|
||||||
|
(mysql_type_to_time_type(sql_type) != MYSQL_TIMESTAMP_DATETIME) ||
|
||||||
|
def->decimals < length))
|
||||||
|
{
|
||||||
|
my_error(ER_INVALID_DEFAULT, MYF(0), field_name);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
else if (def->type() == Item::NULL_ITEM)
|
||||||
|
{
|
||||||
|
def= 0;
|
||||||
|
if ((flags & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG)
|
||||||
|
{
|
||||||
|
my_error(ER_INVALID_DEFAULT, MYF(0), field_name);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (flags & AUTO_INCREMENT_FLAG)
|
||||||
|
{
|
||||||
|
my_error(ER_INVALID_DEFAULT, MYF(0), field_name);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_item_func(def))
|
||||||
{
|
{
|
||||||
/* There is a function default for insertions. */
|
/* There is a function default for insertions. */
|
||||||
def= NULL;
|
def= NULL;
|
||||||
unireg_check= (on_update_is_function ?
|
unireg_check= (is_item_func(on_update) ?
|
||||||
Field::TIMESTAMP_DNUN_FIELD : // for insertions and for updates.
|
Field::TIMESTAMP_DNUN_FIELD : // for insertions and for updates.
|
||||||
Field::TIMESTAMP_DN_FIELD); // only for insertions.
|
Field::TIMESTAMP_DN_FIELD); // only for insertions.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No function default for insertions. Either NULL or a constant. */
|
/* No function default for insertions. Either NULL or a constant. */
|
||||||
def= fld_default_value;
|
if (is_item_func(on_update))
|
||||||
if (on_update_is_function)
|
|
||||||
unireg_check= Field::TIMESTAMP_UN_FIELD; // function default for updates
|
unireg_check= Field::TIMESTAMP_UN_FIELD; // function default for updates
|
||||||
else
|
else
|
||||||
unireg_check= ((fld_type_modifier & AUTO_INCREMENT_FLAG) != 0 ?
|
unireg_check= ((flags & AUTO_INCREMENT_FLAG) ?
|
||||||
Field::NEXT_NUMBER : // Automatic increment.
|
Field::NEXT_NUMBER : // Automatic increment.
|
||||||
Field::NONE);
|
Field::NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
|
if (on_update &&
|
||||||
if (decimals >= NOT_FIXED_DEC)
|
(mysql_type_to_time_type(sql_type) != MYSQL_TIMESTAMP_DATETIME ||
|
||||||
|
on_update->decimals < length))
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name,
|
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name);
|
||||||
static_cast<ulong>(NOT_FIXED_DEC - 1));
|
DBUG_RETURN(1);
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sql_type= fld_type;
|
|
||||||
length= 0;
|
|
||||||
change= fld_change;
|
|
||||||
interval= 0;
|
|
||||||
pack_length= key_length= 0;
|
|
||||||
charset= fld_charset;
|
|
||||||
geom_type= (Field::geometry_type) fld_geom_type;
|
|
||||||
interval_list.empty();
|
|
||||||
|
|
||||||
comment= *fld_comment;
|
|
||||||
vcol_info= fld_vcol_info;
|
|
||||||
create_if_not_exists= check_exists;
|
|
||||||
stored_in_db= TRUE;
|
|
||||||
|
|
||||||
/* Initialize data for a computed field */
|
/* Initialize data for a computed field */
|
||||||
if ((uchar)fld_type == (uchar)MYSQL_TYPE_VIRTUAL)
|
if (sql_type == MYSQL_TYPE_VIRTUAL)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(vcol_info && vcol_info->expr_item);
|
DBUG_ASSERT(vcol_info && vcol_info->expr_item);
|
||||||
stored_in_db= vcol_info->is_stored();
|
stored_in_db= vcol_info->is_stored();
|
||||||
@ -9272,56 +9276,42 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
Field::vcol_info. It is is always NULL for a column that is not
|
Field::vcol_info. It is is always NULL for a column that is not
|
||||||
computed.
|
computed.
|
||||||
*/
|
*/
|
||||||
sql_type= fld_type= vcol_info->get_real_type();
|
sql_type= vcol_info->get_real_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
|
Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
|
||||||
it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
|
it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
|
||||||
*/
|
*/
|
||||||
if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) &&
|
if (!def && unireg_check == Field::NONE &&
|
||||||
(fld_type_modifier & NOT_NULL_FLAG) && !is_timestamp_type(fld_type))
|
(flags & NOT_NULL_FLAG) && !is_timestamp_type(sql_type))
|
||||||
flags|= NO_DEFAULT_VALUE_FLAG;
|
flags|= NO_DEFAULT_VALUE_FLAG;
|
||||||
|
|
||||||
if (fld_length != NULL)
|
sign_len= flags & UNSIGNED_FLAG ? 0 : 1;
|
||||||
{
|
|
||||||
errno= 0;
|
|
||||||
length= strtoul(fld_length, NULL, 10);
|
|
||||||
if ((errno != 0) || (length > MAX_FIELD_BLOBLENGTH))
|
|
||||||
{
|
|
||||||
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name, MAX_FIELD_BLOBLENGTH);
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length == 0)
|
switch (sql_type) {
|
||||||
fld_length= NULL; /* purecov: inspected */
|
|
||||||
}
|
|
||||||
|
|
||||||
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
|
|
||||||
|
|
||||||
switch (fld_type) {
|
|
||||||
case MYSQL_TYPE_TINY:
|
case MYSQL_TYPE_TINY:
|
||||||
if (!fld_length)
|
if (!length)
|
||||||
length= MAX_TINYINT_WIDTH+sign_len;
|
length= MAX_TINYINT_WIDTH+sign_len;
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_SHORT:
|
case MYSQL_TYPE_SHORT:
|
||||||
if (!fld_length)
|
if (!length)
|
||||||
length= MAX_SMALLINT_WIDTH+sign_len;
|
length= MAX_SMALLINT_WIDTH+sign_len;
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_INT24:
|
case MYSQL_TYPE_INT24:
|
||||||
if (!fld_length)
|
if (!length)
|
||||||
length= MAX_MEDIUMINT_WIDTH+sign_len;
|
length= MAX_MEDIUMINT_WIDTH+sign_len;
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_LONG:
|
case MYSQL_TYPE_LONG:
|
||||||
if (!fld_length)
|
if (!length)
|
||||||
length= MAX_INT_WIDTH+sign_len;
|
length= MAX_INT_WIDTH+sign_len;
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_LONGLONG:
|
case MYSQL_TYPE_LONGLONG:
|
||||||
if (!fld_length)
|
if (!length)
|
||||||
length= MAX_BIGINT_WIDTH;
|
length= MAX_BIGINT_WIDTH;
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
break;
|
break;
|
||||||
@ -9331,18 +9321,17 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
my_decimal_trim(&length, &decimals);
|
my_decimal_trim(&length, &decimals);
|
||||||
if (length > DECIMAL_MAX_PRECISION)
|
if (length > DECIMAL_MAX_PRECISION)
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast<int>(length),
|
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name,
|
||||||
fld_name, static_cast<ulong>(DECIMAL_MAX_PRECISION));
|
DECIMAL_MAX_PRECISION);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
if (length < decimals)
|
if (length < decimals)
|
||||||
{
|
{
|
||||||
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
|
my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
length=
|
length=
|
||||||
my_decimal_precision_to_length(length, decimals,
|
my_decimal_precision_to_length(length, decimals, flags & UNSIGNED_FLAG);
|
||||||
fld_type_modifier & UNSIGNED_FLAG);
|
|
||||||
pack_length=
|
pack_length=
|
||||||
my_decimal_get_binary_size(length, decimals);
|
my_decimal_get_binary_size(length, decimals);
|
||||||
break;
|
break;
|
||||||
@ -9360,11 +9349,11 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
case MYSQL_TYPE_LONG_BLOB:
|
case MYSQL_TYPE_LONG_BLOB:
|
||||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||||
case MYSQL_TYPE_GEOMETRY:
|
case MYSQL_TYPE_GEOMETRY:
|
||||||
if (fld_default_value)
|
if (def)
|
||||||
{
|
{
|
||||||
/* Allow empty as default value. */
|
/* Allow empty as default value. */
|
||||||
String str,*res;
|
String str,*res;
|
||||||
res= fld_default_value->val_str(&str);
|
res= def->val_str(&str);
|
||||||
/*
|
/*
|
||||||
A default other than '' is always an error, and any non-NULL
|
A default other than '' is always an error, and any non-NULL
|
||||||
specified default is an error in strict mode.
|
specified default is an error in strict mode.
|
||||||
@ -9372,7 +9361,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
if (res->length() || thd->is_strict_mode())
|
if (res->length() || thd->is_strict_mode())
|
||||||
{
|
{
|
||||||
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0),
|
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0),
|
||||||
fld_name); /* purecov: inspected */
|
field_name); /* purecov: inspected */
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -9383,39 +9372,21 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
ER_BLOB_CANT_HAVE_DEFAULT,
|
ER_BLOB_CANT_HAVE_DEFAULT,
|
||||||
ER(ER_BLOB_CANT_HAVE_DEFAULT),
|
ER(ER_BLOB_CANT_HAVE_DEFAULT),
|
||||||
fld_name);
|
field_name);
|
||||||
}
|
}
|
||||||
def= 0;
|
def= 0;
|
||||||
}
|
}
|
||||||
flags|= BLOB_FLAG;
|
flags|= BLOB_FLAG;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_YEAR:
|
case MYSQL_TYPE_YEAR:
|
||||||
if (!fld_length || length != 2)
|
if (!length || length != 2)
|
||||||
length= 4; /* Default length */
|
length= 4; /* Default length */
|
||||||
flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
|
flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_FLOAT:
|
case MYSQL_TYPE_FLOAT:
|
||||||
/* change FLOAT(precision) to FLOAT or DOUBLE */
|
/* change FLOAT(precision) to FLOAT or DOUBLE */
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
if (fld_length && !fld_decimals)
|
if (!length && !decimals)
|
||||||
{
|
|
||||||
uint tmp_length= length;
|
|
||||||
if (tmp_length > PRECISION_FOR_DOUBLE)
|
|
||||||
{
|
|
||||||
my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
else if (tmp_length > PRECISION_FOR_FLOAT)
|
|
||||||
{
|
|
||||||
sql_type= MYSQL_TYPE_DOUBLE;
|
|
||||||
length= MAX_DOUBLE_STR_LENGTH;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
length= MAX_FLOAT_STR_LENGTH;
|
|
||||||
decimals= NOT_FIXED_DEC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!fld_length && !fld_decimals)
|
|
||||||
{
|
{
|
||||||
length= MAX_FLOAT_STR_LENGTH;
|
length= MAX_FLOAT_STR_LENGTH;
|
||||||
decimals= NOT_FIXED_DEC;
|
decimals= NOT_FIXED_DEC;
|
||||||
@ -9423,13 +9394,13 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
if (length < decimals &&
|
if (length < decimals &&
|
||||||
decimals != NOT_FIXED_DEC)
|
decimals != NOT_FIXED_DEC)
|
||||||
{
|
{
|
||||||
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
|
my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_DOUBLE:
|
case MYSQL_TYPE_DOUBLE:
|
||||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||||
if (!fld_length && !fld_decimals)
|
if (!length && !decimals)
|
||||||
{
|
{
|
||||||
length= DBL_DIG+7;
|
length= DBL_DIG+7;
|
||||||
decimals= NOT_FIXED_DEC;
|
decimals= NOT_FIXED_DEC;
|
||||||
@ -9437,7 +9408,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
if (length < decimals &&
|
if (length < decimals &&
|
||||||
decimals != NOT_FIXED_DEC)
|
decimals != NOT_FIXED_DEC)
|
||||||
{
|
{
|
||||||
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
|
my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -9445,7 +9416,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
case MYSQL_TYPE_TIMESTAMP2:
|
case MYSQL_TYPE_TIMESTAMP2:
|
||||||
if (length > MAX_DATETIME_PRECISION)
|
if (length > MAX_DATETIME_PRECISION)
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
|
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name,
|
||||||
MAX_DATETIME_PRECISION);
|
MAX_DATETIME_PRECISION);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
@ -9463,7 +9434,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
case MYSQL_TYPE_TIME2:
|
case MYSQL_TYPE_TIME2:
|
||||||
if (length > MAX_DATETIME_PRECISION)
|
if (length > MAX_DATETIME_PRECISION)
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
|
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name,
|
||||||
MAX_DATETIME_PRECISION);
|
MAX_DATETIME_PRECISION);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
@ -9473,50 +9444,29 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
case MYSQL_TYPE_DATETIME2:
|
case MYSQL_TYPE_DATETIME2:
|
||||||
if (length > MAX_DATETIME_PRECISION)
|
if (length > MAX_DATETIME_PRECISION)
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
|
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name,
|
||||||
MAX_DATETIME_PRECISION);
|
MAX_DATETIME_PRECISION);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
length+= MAX_DATETIME_WIDTH + (length ? 1 : 0);
|
length+= MAX_DATETIME_WIDTH + (length ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_SET:
|
case MYSQL_TYPE_SET:
|
||||||
{
|
pack_length= get_set_pack_length(interval_list.elements);
|
||||||
pack_length= get_set_pack_length(fld_interval_list->elements);
|
break;
|
||||||
|
|
||||||
List_iterator<String> it(*fld_interval_list);
|
|
||||||
String *tmp;
|
|
||||||
while ((tmp= it++))
|
|
||||||
interval_list.push_back(tmp);
|
|
||||||
/*
|
|
||||||
Set fake length to 1 to pass the below conditions.
|
|
||||||
Real length will be set in mysql_prepare_table()
|
|
||||||
when we know the character set of the column
|
|
||||||
*/
|
|
||||||
length= 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MYSQL_TYPE_ENUM:
|
case MYSQL_TYPE_ENUM:
|
||||||
{
|
/* Should be safe. */
|
||||||
/* Should be safe. */
|
pack_length= get_enum_pack_length(interval_list.elements);
|
||||||
pack_length= get_enum_pack_length(fld_interval_list->elements);
|
break;
|
||||||
|
|
||||||
List_iterator<String> it(*fld_interval_list);
|
|
||||||
String *tmp;
|
|
||||||
while ((tmp= it++))
|
|
||||||
interval_list.push_back(tmp);
|
|
||||||
length= 1; /* See comment for MYSQL_TYPE_SET above. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MYSQL_TYPE_VAR_STRING:
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
DBUG_ASSERT(0); /* Impossible. */
|
DBUG_ASSERT(0); /* Impossible. */
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_BIT:
|
case MYSQL_TYPE_BIT:
|
||||||
{
|
{
|
||||||
if (!fld_length)
|
if (!length)
|
||||||
length= 1;
|
length= 1;
|
||||||
if (length > MAX_BIT_FIELD_LENGTH)
|
if (length > MAX_BIT_FIELD_LENGTH)
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name,
|
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name,
|
||||||
static_cast<ulong>(MAX_BIT_FIELD_LENGTH));
|
static_cast<ulong>(MAX_BIT_FIELD_LENGTH));
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
@ -9525,37 +9475,35 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
}
|
}
|
||||||
case MYSQL_TYPE_DECIMAL:
|
case MYSQL_TYPE_DECIMAL:
|
||||||
DBUG_ASSERT(0); /* Was obsolete */
|
DBUG_ASSERT(0); /* Was obsolete */
|
||||||
}
|
}
|
||||||
/* Remember the value of length */
|
/* Remember the value of length */
|
||||||
char_length= length;
|
char_length= length;
|
||||||
|
|
||||||
if (!(flags & BLOB_FLAG) &&
|
if (!(flags & BLOB_FLAG) &&
|
||||||
((length > max_field_charlength && fld_type != MYSQL_TYPE_SET &&
|
((length > max_field_charlength &&
|
||||||
fld_type != MYSQL_TYPE_ENUM &&
|
(sql_type != MYSQL_TYPE_VARCHAR || def)) ||
|
||||||
(fld_type != MYSQL_TYPE_VARCHAR || fld_default_value)) ||
|
(length == 0 &&
|
||||||
((length == 0) &&
|
sql_type != MYSQL_TYPE_ENUM && sql_type != MYSQL_TYPE_SET &&
|
||||||
fld_type != MYSQL_TYPE_STRING &&
|
sql_type != MYSQL_TYPE_STRING && sql_type != MYSQL_TYPE_VARCHAR &&
|
||||||
fld_type != MYSQL_TYPE_VARCHAR && fld_type != MYSQL_TYPE_GEOMETRY)))
|
sql_type != MYSQL_TYPE_GEOMETRY)))
|
||||||
{
|
{
|
||||||
my_error((fld_type == MYSQL_TYPE_VAR_STRING ||
|
my_error((sql_type == MYSQL_TYPE_VAR_STRING ||
|
||||||
fld_type == MYSQL_TYPE_VARCHAR ||
|
sql_type == MYSQL_TYPE_VARCHAR ||
|
||||||
fld_type == MYSQL_TYPE_STRING) ? ER_TOO_BIG_FIELDLENGTH :
|
sql_type == MYSQL_TYPE_STRING) ? ER_TOO_BIG_FIELDLENGTH :
|
||||||
ER_TOO_BIG_DISPLAYWIDTH,
|
ER_TOO_BIG_DISPLAYWIDTH,
|
||||||
MYF(0),
|
MYF(0),
|
||||||
fld_name, max_field_charlength); /* purecov: inspected */
|
field_name, max_field_charlength); /* purecov: inspected */
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
fld_type_modifier&= AUTO_INCREMENT_FLAG;
|
if ((~allowed_type_modifier) & flags & conditional_type_modifiers)
|
||||||
if ((~allowed_type_modifier) & fld_type_modifier)
|
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
|
my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(FALSE); /* success */
|
DBUG_RETURN(FALSE); /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum_field_types get_blob_type_from_length(ulong length)
|
enum_field_types get_blob_type_from_length(ulong length)
|
||||||
{
|
{
|
||||||
enum_field_types type;
|
enum_field_types type;
|
||||||
|
21
sql/field.h
21
sql/field.h
@ -2835,13 +2835,13 @@ public:
|
|||||||
const char *change; // If done with alter table
|
const char *change; // If done with alter table
|
||||||
const char *after; // Put column after this one
|
const char *after; // Put column after this one
|
||||||
LEX_STRING comment; // Comment for field
|
LEX_STRING comment; // Comment for field
|
||||||
Item *def; // Default value
|
Item *def, *on_update; // Default value
|
||||||
enum enum_field_types sql_type;
|
enum enum_field_types sql_type;
|
||||||
/*
|
/*
|
||||||
At various stages in execution this can be length of field in bytes or
|
At various stages in execution this can be length of field in bytes or
|
||||||
max number of characters.
|
max number of characters.
|
||||||
*/
|
*/
|
||||||
ulong length;
|
ulonglong length;
|
||||||
/*
|
/*
|
||||||
The value of `length' as set by parser: is the number of characters
|
The value of `length' as set by parser: is the number of characters
|
||||||
for most of the types, or of bytes for BLOBs or numeric types.
|
for most of the types, or of bytes for BLOBs or numeric types.
|
||||||
@ -2877,9 +2877,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool stored_in_db;
|
bool stored_in_db;
|
||||||
|
|
||||||
Create_field() :after(0), option_list(NULL), option_struct(NULL),
|
Create_field() :after(0), pack_length(0), key_length(0), interval(0),
|
||||||
create_if_not_exists(FALSE)
|
field(0), option_list(NULL), option_struct(NULL),
|
||||||
{}
|
create_if_not_exists(false), stored_in_db(true)
|
||||||
|
{
|
||||||
|
interval_list.empty();
|
||||||
|
}
|
||||||
|
|
||||||
Create_field(Field *field, Field *orig_field);
|
Create_field(Field *field, Field *orig_field);
|
||||||
/* Used to make a clone of this object for ALTER/CREATE TABLE */
|
/* Used to make a clone of this object for ALTER/CREATE TABLE */
|
||||||
Create_field *clone(MEM_ROOT *mem_root) const;
|
Create_field *clone(MEM_ROOT *mem_root) const;
|
||||||
@ -2891,12 +2895,7 @@ public:
|
|||||||
bool maybe_null, bool is_unsigned,
|
bool maybe_null, bool is_unsigned,
|
||||||
uint pack_length = ~0U);
|
uint pack_length = ~0U);
|
||||||
|
|
||||||
bool init(THD *thd, char *field_name, enum_field_types type, char *length,
|
bool check(THD *thd);
|
||||||
char *decimals, uint type_modifier, Item *default_value,
|
|
||||||
Item *on_update_value, LEX_STRING *comment, char *change,
|
|
||||||
List<String> *interval_list, CHARSET_INFO *cs,
|
|
||||||
uint uint_geom_type, Virtual_column_info *vcol_info,
|
|
||||||
engine_option_value *option_list, bool check_exists);
|
|
||||||
|
|
||||||
bool field_flags_are_binary()
|
bool field_flags_are_binary()
|
||||||
{
|
{
|
||||||
|
@ -53,13 +53,12 @@ static const char* item_name(Item *a, String *str)
|
|||||||
|
|
||||||
|
|
||||||
static void wrong_precision_error(uint errcode, Item *a,
|
static void wrong_precision_error(uint errcode, Item *a,
|
||||||
ulonglong number, ulong maximum)
|
ulonglong number, uint maximum)
|
||||||
{
|
{
|
||||||
char buff[1024];
|
char buff[1024];
|
||||||
String buf(buff, sizeof(buff), system_charset_info);
|
String buf(buff, sizeof(buff), system_charset_info);
|
||||||
|
|
||||||
my_error(errcode, MYF(0), (uint) MY_MIN(number, UINT_MAX32),
|
my_error(errcode, MYF(0), number, item_name(a, &buf), maximum);
|
||||||
item_name(a, &buf), maximum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -87,9 +86,9 @@ bool get_length_and_scale(ulonglong length, ulonglong decimals,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_length= (ulong) length;
|
|
||||||
*out_decimals= (uint) decimals;
|
*out_decimals= (uint) decimals;
|
||||||
my_decimal_trim(out_length, out_decimals);
|
my_decimal_trim(&length, out_decimals);
|
||||||
|
*out_length= (ulong) length;
|
||||||
|
|
||||||
if (*out_length < *out_decimals)
|
if (*out_length < *out_decimals)
|
||||||
{
|
{
|
||||||
|
@ -1628,8 +1628,8 @@ bool Item_func_curtime::fix_fields(THD *thd, Item **items)
|
|||||||
{
|
{
|
||||||
if (decimals > TIME_SECOND_PART_DIGITS)
|
if (decimals > TIME_SECOND_PART_DIGITS)
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_BIG_PRECISION, MYF(0), decimals, func_name(),
|
my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast<ulonglong>(decimals),
|
||||||
TIME_SECOND_PART_DIGITS);
|
func_name(), TIME_SECOND_PART_DIGITS);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return Item_timefunc::fix_fields(thd, items);
|
return Item_timefunc::fix_fields(thd, items);
|
||||||
@ -1690,8 +1690,8 @@ bool Item_func_now::fix_fields(THD *thd, Item **items)
|
|||||||
{
|
{
|
||||||
if (decimals > TIME_SECOND_PART_DIGITS)
|
if (decimals > TIME_SECOND_PART_DIGITS)
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_BIG_PRECISION, MYF(0), decimals, func_name(),
|
my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast<ulonglong>(decimals),
|
||||||
TIME_SECOND_PART_DIGITS);
|
func_name(), TIME_SECOND_PART_DIGITS);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return Item_temporal_func::fix_fields(thd, items);
|
return Item_temporal_func::fix_fields(thd, items);
|
||||||
|
@ -335,7 +335,7 @@ my_decimal *date2my_decimal(MYSQL_TIME *ltime, my_decimal *dec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void my_decimal_trim(ulong *precision, uint *scale)
|
void my_decimal_trim(ulonglong *precision, uint *scale)
|
||||||
{
|
{
|
||||||
if (!(*precision) && !(*scale))
|
if (!(*precision) && !(*scale))
|
||||||
{
|
{
|
||||||
|
@ -486,7 +486,7 @@ int my_decimal_intg(const my_decimal *a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void my_decimal_trim(ulong *precision, uint *scale);
|
void my_decimal_trim(ulonglong *precision, uint *scale);
|
||||||
|
|
||||||
|
|
||||||
#endif /*my_decimal_h*/
|
#endif /*my_decimal_h*/
|
||||||
|
@ -5472,8 +5472,8 @@ ER_TOO_BIG_SCALE 42000 S1009
|
|||||||
eng "Too big scale %u specified for '%-.192s'. Maximum is %lu."
|
eng "Too big scale %u specified for '%-.192s'. Maximum is %lu."
|
||||||
ger "Zu großer Skalierungsfaktor %u für '%-.192s' angegeben. Maximum ist %lu"
|
ger "Zu großer Skalierungsfaktor %u für '%-.192s' angegeben. Maximum ist %lu"
|
||||||
ER_TOO_BIG_PRECISION 42000 S1009
|
ER_TOO_BIG_PRECISION 42000 S1009
|
||||||
eng "Too big precision %u specified for '%-.192s'. Maximum is %lu."
|
eng "Too big precision %llu specified for '%-.192s'. Maximum is %u."
|
||||||
ger "Zu große Genauigkeit %u für '%-.192s' angegeben. Maximum ist %lu"
|
ger "Zu große Genauigkeit %llu für '%-.192s' angegeben. Maximum ist %u"
|
||||||
ER_M_BIGGER_THAN_D 42000 S1009
|
ER_M_BIGGER_THAN_D 42000 S1009
|
||||||
eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.192s')."
|
eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.192s')."
|
||||||
ger "Für FLOAT(M,D), DOUBLE(M,D) oder DECIMAL(M,D) muss M >= D sein (Feld '%-.192s')"
|
ger "Für FLOAT(M,D), DOUBLE(M,D) oder DECIMAL(M,D) muss M >= D sein (Feld '%-.192s')"
|
||||||
|
@ -2216,16 +2216,6 @@ sp_head::reset_lex(THD *thd)
|
|||||||
sublex->trg_table_fields.empty();
|
sublex->trg_table_fields.empty();
|
||||||
sublex->sp_lex_in_use= FALSE;
|
sublex->sp_lex_in_use= FALSE;
|
||||||
|
|
||||||
/* Reset type info. */
|
|
||||||
|
|
||||||
sublex->charset= NULL;
|
|
||||||
sublex->length= NULL;
|
|
||||||
sublex->dec= NULL;
|
|
||||||
sublex->interval_list.empty();
|
|
||||||
sublex->type= 0;
|
|
||||||
sublex->uint_geom_type= 0;
|
|
||||||
sublex->vcol_info= 0;
|
|
||||||
|
|
||||||
/* Reset part of parser state which needs this. */
|
/* Reset part of parser state which needs this. */
|
||||||
thd->m_parser_state->m_yacc.reset_before_substatement();
|
thd->m_parser_state->m_yacc.reset_before_substatement();
|
||||||
|
|
||||||
@ -2351,16 +2341,9 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
|
|||||||
enum enum_field_types field_type,
|
enum enum_field_types field_type,
|
||||||
Create_field *field_def)
|
Create_field *field_def)
|
||||||
{
|
{
|
||||||
LEX_STRING cmt = { 0, 0 };
|
|
||||||
uint unused1= 0;
|
uint unused1= 0;
|
||||||
|
|
||||||
if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec,
|
if (field_def->check(thd))
|
||||||
lex->type, (Item*) 0, (Item*) 0, &cmt, 0,
|
|
||||||
&lex->interval_list,
|
|
||||||
lex->charset ? lex->charset :
|
|
||||||
thd->variables.collation_database,
|
|
||||||
lex->uint_geom_type,
|
|
||||||
lex->vcol_info, NULL, FALSE))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (field_def->interval_list.elements)
|
if (field_def->interval_list.elements)
|
||||||
|
@ -183,13 +183,10 @@ sp_variable *sp_pcontext::find_variable(uint offset) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sp_variable *sp_pcontext::add_variable(THD *thd,
|
sp_variable *sp_pcontext::add_variable(THD *thd, LEX_STRING name)
|
||||||
LEX_STRING name,
|
|
||||||
enum enum_field_types type,
|
|
||||||
sp_variable::enum_mode mode)
|
|
||||||
{
|
{
|
||||||
sp_variable *p=
|
sp_variable *p=
|
||||||
new (thd->mem_root) sp_variable(name, type,mode, current_var_count());
|
new (thd->mem_root) sp_variable(name, current_var_count());
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -63,12 +63,11 @@ public:
|
|||||||
Create_field field_def;
|
Create_field field_def;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sp_variable(LEX_STRING _name, enum_field_types _type, enum_mode _mode,
|
sp_variable(LEX_STRING _name, uint _offset)
|
||||||
uint _offset)
|
|
||||||
:Sql_alloc(),
|
:Sql_alloc(),
|
||||||
name(_name),
|
name(_name),
|
||||||
type(_type),
|
type(MYSQL_TYPE_NULL),
|
||||||
mode(_mode),
|
mode(MODE_IN),
|
||||||
offset(_offset),
|
offset(_offset),
|
||||||
default_value(NULL)
|
default_value(NULL)
|
||||||
{ }
|
{ }
|
||||||
@ -340,14 +339,9 @@ public:
|
|||||||
///
|
///
|
||||||
/// @param thd Thread context.
|
/// @param thd Thread context.
|
||||||
/// @param name Name of the SP-variable.
|
/// @param name Name of the SP-variable.
|
||||||
/// @param type Type of the SP-variable.
|
|
||||||
/// @param mode Mode of the SP-variable.
|
|
||||||
///
|
///
|
||||||
/// @return instance of newly added SP-variable.
|
/// @return instance of newly added SP-variable.
|
||||||
sp_variable *add_variable(THD *thd,
|
sp_variable *add_variable(THD *thd, LEX_STRING name);
|
||||||
LEX_STRING name,
|
|
||||||
enum enum_field_types type,
|
|
||||||
sp_variable::enum_mode mode);
|
|
||||||
|
|
||||||
/// Retrieve full type information about SP-variables in this parsing
|
/// Retrieve full type information about SP-variables in this parsing
|
||||||
/// context and its children.
|
/// context and its children.
|
||||||
|
@ -125,6 +125,7 @@ struct LEX_TYPE
|
|||||||
#if MYSQL_LEX
|
#if MYSQL_LEX
|
||||||
#include "item_func.h" /* Cast_target used in sql_yacc.h */
|
#include "item_func.h" /* Cast_target used in sql_yacc.h */
|
||||||
#include "sql_get_diagnostics.h" /* Types used in sql_yacc.h */
|
#include "sql_get_diagnostics.h" /* Types used in sql_yacc.h */
|
||||||
|
#include "sp_pcontext.h"
|
||||||
#include "sql_yacc.h"
|
#include "sql_yacc.h"
|
||||||
#define LEX_YYSTYPE YYSTYPE *
|
#define LEX_YYSTYPE YYSTYPE *
|
||||||
#else
|
#else
|
||||||
@ -2380,7 +2381,10 @@ struct LEX: public Query_tables_list
|
|||||||
/* Query Plan Footprint of a currently running select */
|
/* Query Plan Footprint of a currently running select */
|
||||||
Explain_query *explain;
|
Explain_query *explain;
|
||||||
|
|
||||||
char *length,*dec,*change;
|
// type information
|
||||||
|
char *length,*dec;
|
||||||
|
CHARSET_INFO *charset;
|
||||||
|
|
||||||
LEX_STRING name;
|
LEX_STRING name;
|
||||||
char *help_arg;
|
char *help_arg;
|
||||||
char *backup_dir; /* For RESTORE/BACKUP */
|
char *backup_dir; /* For RESTORE/BACKUP */
|
||||||
@ -2389,18 +2393,15 @@ struct LEX: public Query_tables_list
|
|||||||
String *wild; /* Wildcard in SHOW {something} LIKE 'wild'*/
|
String *wild; /* Wildcard in SHOW {something} LIKE 'wild'*/
|
||||||
sql_exchange *exchange;
|
sql_exchange *exchange;
|
||||||
select_result *result;
|
select_result *result;
|
||||||
Item *default_value, *on_update_value;
|
|
||||||
LEX_STRING comment, ident;
|
LEX_STRING comment, ident;
|
||||||
LEX_USER *grant_user;
|
LEX_USER *grant_user;
|
||||||
XID *xid;
|
XID *xid;
|
||||||
THD *thd;
|
THD *thd;
|
||||||
Virtual_column_info *vcol_info;
|
|
||||||
|
|
||||||
/* maintain a list of used plugins for this LEX */
|
/* maintain a list of used plugins for this LEX */
|
||||||
DYNAMIC_ARRAY plugins;
|
DYNAMIC_ARRAY plugins;
|
||||||
plugin_ref plugins_static_buffer[INITIAL_LEX_PLUGIN_LIST_SIZE];
|
plugin_ref plugins_static_buffer[INITIAL_LEX_PLUGIN_LIST_SIZE];
|
||||||
|
|
||||||
CHARSET_INFO *charset;
|
|
||||||
bool text_string_is_7bit;
|
bool text_string_is_7bit;
|
||||||
|
|
||||||
/** SELECT of CREATE VIEW statement */
|
/** SELECT of CREATE VIEW statement */
|
||||||
@ -2422,7 +2423,6 @@ struct LEX: public Query_tables_list
|
|||||||
|
|
||||||
List<Key_part_spec> col_list;
|
List<Key_part_spec> col_list;
|
||||||
List<Key_part_spec> ref_list;
|
List<Key_part_spec> ref_list;
|
||||||
List<String> interval_list;
|
|
||||||
List<LEX_USER> users_list;
|
List<LEX_USER> users_list;
|
||||||
List<LEX_COLUMN> columns;
|
List<LEX_COLUMN> columns;
|
||||||
List<Item> *insert_list,field_list,value_list,update_list;
|
List<Item> *insert_list,field_list,value_list,update_list;
|
||||||
@ -2512,7 +2512,6 @@ struct LEX: public Query_tables_list
|
|||||||
|
|
||||||
uint profile_query_id;
|
uint profile_query_id;
|
||||||
uint profile_options;
|
uint profile_options;
|
||||||
uint uint_geom_type;
|
|
||||||
uint grant, grant_tot_col, which_columns;
|
uint grant, grant_tot_col, which_columns;
|
||||||
enum Foreign_key::fk_match_opt fk_match_option;
|
enum Foreign_key::fk_match_opt fk_match_option;
|
||||||
enum Foreign_key::fk_option fk_update_opt;
|
enum Foreign_key::fk_option fk_update_opt;
|
||||||
@ -2623,9 +2622,17 @@ struct LEX: public Query_tables_list
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Collects create options for Field and KEY
|
Collects create options for KEY
|
||||||
*/
|
*/
|
||||||
engine_option_value *option_list, *option_list_last;
|
engine_option_value *option_list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper pointer to the end of the list when parsing options for
|
||||||
|
LEX::create_info.option_list (for table)
|
||||||
|
LEX::last_field->option_list (for fields)
|
||||||
|
LEX::option_list (for indexes)
|
||||||
|
*/
|
||||||
|
engine_option_value *option_list_last;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
During name resolution search only in the table list given by
|
During name resolution search only in the table list given by
|
||||||
@ -2806,6 +2813,10 @@ struct LEX: public Query_tables_list
|
|||||||
int print_explain(select_result_sink *output, uint8 explain_flags,
|
int print_explain(select_result_sink *output, uint8 explain_flags,
|
||||||
bool is_analyze, bool *printed_anything);
|
bool is_analyze, bool *printed_anything);
|
||||||
void restore_set_statement_var();
|
void restore_set_statement_var();
|
||||||
|
|
||||||
|
void init_last_field(Create_field *field, const char *name, CHARSET_INFO *cs);
|
||||||
|
void set_last_field_type(enum enum_field_types type);
|
||||||
|
bool set_bincmp(CHARSET_INFO *cs, bool bin);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
122
sql/sql_parse.cc
122
sql/sql_parse.cc
@ -7097,113 +7097,6 @@ bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Store field definition for create.
|
|
||||||
|
|
||||||
@return
|
|
||||||
Return 0 if ok
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
|
|
||||||
char *length, char *decimals,
|
|
||||||
uint type_modifier,
|
|
||||||
Item *default_value, Item *on_update_value,
|
|
||||||
LEX_STRING *comment,
|
|
||||||
char *change,
|
|
||||||
List<String> *interval_list, CHARSET_INFO *cs,
|
|
||||||
uint uint_geom_type,
|
|
||||||
Virtual_column_info *vcol_info,
|
|
||||||
engine_option_value *create_options)
|
|
||||||
{
|
|
||||||
register Create_field *new_field;
|
|
||||||
LEX *lex= thd->lex;
|
|
||||||
uint8 datetime_precision= length ? atoi(length) : 0;
|
|
||||||
DBUG_ENTER("add_field_to_list");
|
|
||||||
|
|
||||||
if (check_string_char_length(field_name, "", NAME_CHAR_LEN,
|
|
||||||
system_charset_info, 1))
|
|
||||||
{
|
|
||||||
my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */
|
|
||||||
DBUG_RETURN(1); /* purecov: inspected */
|
|
||||||
}
|
|
||||||
if (type_modifier & PRI_KEY_FLAG)
|
|
||||||
{
|
|
||||||
Key *key;
|
|
||||||
lex->col_list.push_back(new Key_part_spec(*field_name, 0));
|
|
||||||
key= new Key(Key::PRIMARY, null_lex_str,
|
|
||||||
&default_key_create_info,
|
|
||||||
0, lex->col_list, NULL, lex->check_exists);
|
|
||||||
lex->alter_info.key_list.push_back(key);
|
|
||||||
lex->col_list.empty();
|
|
||||||
}
|
|
||||||
if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
|
|
||||||
{
|
|
||||||
Key *key;
|
|
||||||
lex->col_list.push_back(new Key_part_spec(*field_name, 0));
|
|
||||||
key= new Key(Key::UNIQUE, null_lex_str,
|
|
||||||
&default_key_create_info, 0,
|
|
||||||
lex->col_list, NULL, lex->check_exists);
|
|
||||||
lex->alter_info.key_list.push_back(key);
|
|
||||||
lex->col_list.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_value)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Default value should be literal => basic constants =>
|
|
||||||
no need fix_fields()
|
|
||||||
|
|
||||||
We allow only one function as part of default value -
|
|
||||||
NOW() as default for TIMESTAMP and DATETIME type.
|
|
||||||
*/
|
|
||||||
if (default_value->type() == Item::FUNC_ITEM &&
|
|
||||||
(static_cast<Item_func*>(default_value)->functype() !=
|
|
||||||
Item_func::NOW_FUNC ||
|
|
||||||
(mysql_type_to_time_type(type) != MYSQL_TIMESTAMP_DATETIME) ||
|
|
||||||
default_value->decimals < datetime_precision))
|
|
||||||
{
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
else if (default_value->type() == Item::NULL_ITEM)
|
|
||||||
{
|
|
||||||
default_value= 0;
|
|
||||||
if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
|
|
||||||
NOT_NULL_FLAG)
|
|
||||||
{
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (type_modifier & AUTO_INCREMENT_FLAG)
|
|
||||||
{
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (on_update_value &&
|
|
||||||
(mysql_type_to_time_type(type) != MYSQL_TIMESTAMP_DATETIME ||
|
|
||||||
on_update_value->decimals < datetime_precision))
|
|
||||||
{
|
|
||||||
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(new_field= new Create_field()) ||
|
|
||||||
new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
|
|
||||||
default_value, on_update_value, comment, change,
|
|
||||||
interval_list, cs, uint_geom_type, vcol_info,
|
|
||||||
create_options, lex->check_exists))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
|
|
||||||
lex->alter_info.create_list.push_back(new_field);
|
|
||||||
lex->last_field=new_field;
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Store position for column in ALTER TABLE .. ADD column. */
|
/** Store position for column in ALTER TABLE .. ADD column. */
|
||||||
|
|
||||||
void store_position_for_column(const char *name)
|
void store_position_for_column(const char *name)
|
||||||
@ -9138,3 +9031,18 @@ merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl)
|
|||||||
}
|
}
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** find a collation with binary comparison rules
|
||||||
|
*/
|
||||||
|
CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
const char *csname= cs->csname;
|
||||||
|
cs= get_charset_by_csname(csname, MY_CS_BINSORT, MYF(0));
|
||||||
|
if (!cs)
|
||||||
|
{
|
||||||
|
char tmp[65];
|
||||||
|
strxnmov(tmp, sizeof(tmp)-1, csname, "_bin", NULL);
|
||||||
|
my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
|
||||||
|
}
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
@ -73,6 +73,7 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg,
|
|||||||
uint max_char_length, CHARSET_INFO *cs,
|
uint max_char_length, CHARSET_INFO *cs,
|
||||||
bool no_error);
|
bool no_error);
|
||||||
CHARSET_INFO* merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl);
|
CHARSET_INFO* merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl);
|
||||||
|
CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs);
|
||||||
bool check_host_name(LEX_STRING *str);
|
bool check_host_name(LEX_STRING *str);
|
||||||
bool check_identifier_name(LEX_STRING *str, uint max_char_length,
|
bool check_identifier_name(LEX_STRING *str, uint max_char_length,
|
||||||
uint err_code, const char *param_for_err_msg);
|
uint err_code, const char *param_for_err_msg);
|
||||||
@ -104,16 +105,6 @@ bool append_file_to_dir(THD *thd, const char **filename_ptr,
|
|||||||
const char *table_name);
|
const char *table_name);
|
||||||
void execute_init_command(THD *thd, LEX_STRING *init_command,
|
void execute_init_command(THD *thd, LEX_STRING *init_command,
|
||||||
mysql_rwlock_t *var_lock);
|
mysql_rwlock_t *var_lock);
|
||||||
bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum enum_field_types type,
|
|
||||||
char *length, char *decimal,
|
|
||||||
uint type_modifier,
|
|
||||||
Item *default_value, Item *on_update_value,
|
|
||||||
LEX_STRING *comment,
|
|
||||||
char *change, List<String> *interval_list,
|
|
||||||
CHARSET_INFO *cs,
|
|
||||||
uint uint_geom_type,
|
|
||||||
Virtual_column_info *vcol_info,
|
|
||||||
engine_option_value *create_options);
|
|
||||||
bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *group, bool asc);
|
bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *group, bool asc);
|
||||||
void add_join_on(TABLE_LIST *b,Item *expr);
|
void add_join_on(TABLE_LIST *b,Item *expr);
|
||||||
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields,
|
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields,
|
||||||
|
@ -3077,7 +3077,9 @@ void plugin_thdvar_init(THD *thd)
|
|||||||
intern_plugin_unlock(NULL, old_table_plugin);
|
intern_plugin_unlock(NULL, old_table_plugin);
|
||||||
intern_plugin_unlock(NULL, old_tmp_table_plugin);
|
intern_plugin_unlock(NULL, old_tmp_table_plugin);
|
||||||
mysql_mutex_unlock(&LOCK_plugin);
|
mysql_mutex_unlock(&LOCK_plugin);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
thd->variables.table_plugin= NULL;
|
thd->variables.table_plugin= NULL;
|
||||||
thd->variables.tmp_table_plugin= NULL;
|
thd->variables.tmp_table_plugin= NULL;
|
||||||
}
|
}
|
||||||
|
@ -3248,18 +3248,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
*/
|
*/
|
||||||
sql_field->length= sql_field->char_length;
|
sql_field->length= sql_field->char_length;
|
||||||
/* Set field charset. */
|
/* Set field charset. */
|
||||||
save_cs= sql_field->charset= get_sql_field_charset(sql_field,
|
save_cs= sql_field->charset= get_sql_field_charset(sql_field, create_info);
|
||||||
create_info);
|
|
||||||
if ((sql_field->flags & BINCMP_FLAG) &&
|
if ((sql_field->flags & BINCMP_FLAG) &&
|
||||||
!(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
|
!(sql_field->charset= find_bin_collation(sql_field->charset)))
|
||||||
MY_CS_BINSORT,MYF(0))))
|
|
||||||
{
|
|
||||||
char tmp[65];
|
|
||||||
strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
|
|
||||||
STRING_WITH_LEN("_bin"));
|
|
||||||
my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Convert the default value from client character
|
Convert the default value from client character
|
||||||
|
519
sql/sql_yacc.yy
519
sql/sql_yacc.yy
@ -45,7 +45,6 @@
|
|||||||
#include "lex_symbol.h"
|
#include "lex_symbol.h"
|
||||||
#include "item_create.h"
|
#include "item_create.h"
|
||||||
#include "sp_head.h"
|
#include "sp_head.h"
|
||||||
#include "sp_pcontext.h"
|
|
||||||
#include "sp_rcontext.h"
|
#include "sp_rcontext.h"
|
||||||
#include "sp.h"
|
#include "sp.h"
|
||||||
#include "sql_show.h"
|
#include "sql_show.h"
|
||||||
@ -731,7 +730,6 @@ static bool add_create_index_prepare (LEX *lex, Table_ident *table)
|
|||||||
lex->alter_info.reset();
|
lex->alter_info.reset();
|
||||||
lex->alter_info.flags= Alter_info::ALTER_ADD_INDEX;
|
lex->alter_info.flags= Alter_info::ALTER_ADD_INDEX;
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
lex->change= NullS;
|
|
||||||
lex->option_list= NULL;
|
lex->option_list= NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -862,6 +860,85 @@ static bool sp_create_assignment_instr(THD *thd, bool no_lookahead)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void add_key_to_list(LEX *lex, LEX_STRING *field_name,
|
||||||
|
enum Key::Keytype type)
|
||||||
|
{
|
||||||
|
Key *key;
|
||||||
|
lex->col_list.push_back(new Key_part_spec(*field_name, 0));
|
||||||
|
key= new Key(type, null_lex_str,
|
||||||
|
&default_key_create_info, 0,
|
||||||
|
lex->col_list, NULL, lex->check_exists);
|
||||||
|
lex->alter_info.key_list.push_back(key);
|
||||||
|
lex->col_list.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEX::init_last_field(Create_field *field, const char *name, CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
last_field= field;
|
||||||
|
|
||||||
|
field->field_name= name;
|
||||||
|
field->flags= 0;
|
||||||
|
field->def= 0;
|
||||||
|
field->on_update= 0;
|
||||||
|
field->sql_type= MYSQL_TYPE_NULL;
|
||||||
|
field->change= 0;
|
||||||
|
field->geom_type= Field::GEOM_GEOMETRY;
|
||||||
|
field->comment= null_lex_str;
|
||||||
|
field->vcol_info= 0;
|
||||||
|
field->interval_list.empty();
|
||||||
|
|
||||||
|
/* reset LEX fields that are used in Create_field::set_and_check() */
|
||||||
|
length= 0;
|
||||||
|
dec= 0;
|
||||||
|
charset= cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEX::set_last_field_type(enum enum_field_types type)
|
||||||
|
{
|
||||||
|
last_field->sql_type= type;
|
||||||
|
last_field->create_if_not_exists= check_exists;
|
||||||
|
last_field->charset= charset;
|
||||||
|
|
||||||
|
if (length)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
last_field->length= my_strtoll10(length, NULL, &err);
|
||||||
|
if (err)
|
||||||
|
last_field->length= ~0ULL; // safety
|
||||||
|
}
|
||||||
|
else
|
||||||
|
last_field->length= 0;
|
||||||
|
|
||||||
|
last_field->decimals= dec ? (uint)atoi(dec) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if charset is NULL - we're parsing a field declaration.
|
||||||
|
we cannot call find_bin_collation for a field here, because actual
|
||||||
|
field charset is determined in get_sql_field_charset() much later.
|
||||||
|
so we only set a flag.
|
||||||
|
*/
|
||||||
|
if (!charset)
|
||||||
|
{
|
||||||
|
charset= cs;
|
||||||
|
last_field->flags|= bin ? BINCMP_FLAG : 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
charset= bin ? find_bin_collation(cs ? cs : charset)
|
||||||
|
: cs ? cs : charset;
|
||||||
|
return charset == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define bincmp_collation(X,Y) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (Lex->set_bincmp(X,Y)) \
|
||||||
|
MYSQL_YYABORT; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
%}
|
%}
|
||||||
%union {
|
%union {
|
||||||
int num;
|
int num;
|
||||||
@ -871,7 +948,6 @@ static bool sp_create_assignment_instr(THD *thd, bool no_lookahead)
|
|||||||
LEX_STRING lex_str;
|
LEX_STRING lex_str;
|
||||||
LEX_STRING *lex_str_ptr;
|
LEX_STRING *lex_str_ptr;
|
||||||
LEX_SYMBOL symbol;
|
LEX_SYMBOL symbol;
|
||||||
LEX_TYPE lex_type;
|
|
||||||
Table_ident *table;
|
Table_ident *table;
|
||||||
char *simple_string;
|
char *simple_string;
|
||||||
Item *item;
|
Item *item;
|
||||||
@ -888,6 +964,8 @@ static bool sp_create_assignment_instr(THD *thd, bool no_lookahead)
|
|||||||
enum enum_var_type var_type;
|
enum enum_var_type var_type;
|
||||||
Key::Keytype key_type;
|
Key::Keytype key_type;
|
||||||
enum ha_key_alg key_alg;
|
enum ha_key_alg key_alg;
|
||||||
|
enum enum_field_types field_type;
|
||||||
|
enum Field::geometry_type geom_type;
|
||||||
handlerton *db_type;
|
handlerton *db_type;
|
||||||
enum row_type row_type;
|
enum row_type row_type;
|
||||||
enum ha_rkey_function ha_rkey_mode;
|
enum ha_rkey_function ha_rkey_mode;
|
||||||
@ -907,12 +985,14 @@ static bool sp_create_assignment_instr(THD *thd, bool no_lookahead)
|
|||||||
class sp_label *splabel;
|
class sp_label *splabel;
|
||||||
LEX *lex;
|
LEX *lex;
|
||||||
class my_var *myvar;
|
class my_var *myvar;
|
||||||
sp_head *sphead;
|
class sp_head *sphead;
|
||||||
|
class sp_variable *spvar;
|
||||||
struct p_elem_val *p_elem_value;
|
struct p_elem_val *p_elem_value;
|
||||||
enum index_hint_type index_hint;
|
enum index_hint_type index_hint;
|
||||||
enum enum_filetype filetype;
|
enum enum_filetype filetype;
|
||||||
enum Foreign_key::fk_option m_fk_option;
|
enum Foreign_key::fk_option m_fk_option;
|
||||||
enum enum_yes_no_unknown m_yes_no_unk;
|
enum enum_yes_no_unknown m_yes_no_unk;
|
||||||
|
enum sp_variable::enum_mode spvar_mode;
|
||||||
Diag_condition_item_name diag_condition_item_name;
|
Diag_condition_item_name diag_condition_item_name;
|
||||||
Diagnostics_information::Which_area diag_area;
|
Diagnostics_information::Which_area diag_area;
|
||||||
Diagnostics_information *diag_info;
|
Diagnostics_information *diag_info;
|
||||||
@ -1643,14 +1723,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%type <string>
|
%type <string>
|
||||||
text_string hex_or_bin_String opt_gconcat_separator
|
text_string hex_or_bin_String opt_gconcat_separator
|
||||||
|
|
||||||
%type <lex_type> field_def
|
%type <field_type> type_with_opt_collate int_type real_type field_type
|
||||||
|
|
||||||
|
%type <geom_type> spatial_type
|
||||||
|
|
||||||
%type <num>
|
%type <num>
|
||||||
type type_with_opt_collate int_type real_type order_dir lock_option
|
order_dir lock_option
|
||||||
udf_type opt_if_exists opt_local opt_table_options table_options
|
udf_type opt_if_exists opt_local opt_table_options table_options
|
||||||
table_option opt_if_not_exists create_or_replace opt_no_write_to_binlog
|
table_option opt_if_not_exists create_or_replace opt_no_write_to_binlog
|
||||||
opt_temporary all_or_any opt_distinct
|
opt_temporary all_or_any opt_distinct
|
||||||
opt_ignore_leaves fulltext_options spatial_type union_option
|
opt_ignore_leaves fulltext_options union_option
|
||||||
opt_not opt_union_order_or_limit
|
opt_not opt_union_order_or_limit
|
||||||
union_opt select_derived_init transaction_access_mode_types
|
union_opt select_derived_init transaction_access_mode_types
|
||||||
opt_natural_language_mode opt_query_expansion
|
opt_natural_language_mode opt_query_expansion
|
||||||
@ -1659,7 +1741,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
optional_flush_tables_arguments opt_dyncol_type dyncol_type
|
optional_flush_tables_arguments opt_dyncol_type dyncol_type
|
||||||
opt_time_precision kill_type kill_option int_num
|
opt_time_precision kill_type kill_option int_num
|
||||||
opt_default_time_precision
|
opt_default_time_precision
|
||||||
case_stmt_body
|
case_stmt_body opt_bin_mod
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bit field of MYSQL_START_TRANS_OPT_* flags.
|
Bit field of MYSQL_START_TRANS_OPT_* flags.
|
||||||
@ -1763,6 +1845,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%type <charset>
|
%type <charset>
|
||||||
opt_collate
|
opt_collate
|
||||||
charset_name
|
charset_name
|
||||||
|
charset_or_alias
|
||||||
charset_name_or_default
|
charset_name_or_default
|
||||||
old_or_new_charset_name
|
old_or_new_charset_name
|
||||||
old_or_new_charset_name_or_default
|
old_or_new_charset_name_or_default
|
||||||
@ -1805,10 +1888,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
select_item_list select_item values_list no_braces
|
select_item_list select_item values_list no_braces
|
||||||
opt_limit_clause delete_limit_clause fields opt_values values
|
opt_limit_clause delete_limit_clause fields opt_values values
|
||||||
procedure_list procedure_list2 procedure_item
|
procedure_list procedure_list2 procedure_item
|
||||||
handler
|
field_def handler opt_generated_always
|
||||||
opt_precision opt_ignore opt_column opt_restrict
|
opt_precision opt_ignore opt_column opt_restrict
|
||||||
grant revoke set lock unlock string_list field_options field_option
|
grant revoke set lock unlock string_list field_options field_option
|
||||||
field_opt_list opt_binary ascii unicode table_lock_list table_lock
|
field_opt_list opt_binary table_lock_list table_lock
|
||||||
ref_list opt_match_clause opt_on_update_delete use
|
ref_list opt_match_clause opt_on_update_delete use
|
||||||
opt_delete_options opt_delete_option varchar nchar nvarchar
|
opt_delete_options opt_delete_option varchar nchar nvarchar
|
||||||
opt_outer table_list table_name table_alias_ref_list table_alias_ref
|
opt_outer table_list table_name table_alias_ref_list table_alias_ref
|
||||||
@ -1863,12 +1946,14 @@ END_OF_INPUT
|
|||||||
%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
|
%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
|
||||||
%type <NONE> case_stmt_specification
|
%type <NONE> case_stmt_specification
|
||||||
|
|
||||||
%type <num> sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list
|
%type <num> sp_decl_idents sp_handler_type sp_hcond_list
|
||||||
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
|
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
|
||||||
%type <spblock> sp_decls sp_decl
|
%type <spblock> sp_decls sp_decl
|
||||||
%type <lex> sp_cursor_stmt
|
%type <lex> sp_cursor_stmt
|
||||||
%type <spname> sp_name
|
%type <spname> sp_name
|
||||||
%type <splabel> sp_block_content
|
%type <splabel> sp_block_content
|
||||||
|
%type <spvar> sp_param_name_and_type
|
||||||
|
%type <spvar_mode> sp_opt_inout
|
||||||
%type <index_hint> index_hint_type
|
%type <index_hint> index_hint_type
|
||||||
%type <num> index_hint_clause normal_join inner_join
|
%type <num> index_hint_clause normal_join inner_join
|
||||||
%type <filetype> data_or_xml
|
%type <filetype> data_or_xml
|
||||||
@ -2379,7 +2464,6 @@ create:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
lex->alter_info.reset();
|
lex->alter_info.reset();
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
lex->change=NullS;
|
|
||||||
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
||||||
/*
|
/*
|
||||||
For CREATE TABLE we should not open the table even if it exists.
|
For CREATE TABLE we should not open the table even if it exists.
|
||||||
@ -2836,33 +2920,12 @@ sp_fdparam_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
sp_fdparams:
|
sp_fdparams:
|
||||||
sp_fdparams ',' sp_fdparam
|
sp_fdparams ',' sp_param_name_and_type
|
||||||
| sp_fdparam
|
| sp_param_name_and_type
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_init_param:
|
sp_param_name_and_type:
|
||||||
/* Empty */
|
ident
|
||||||
{
|
|
||||||
LEX *lex= Lex;
|
|
||||||
|
|
||||||
lex->length= 0;
|
|
||||||
lex->dec= 0;
|
|
||||||
lex->type= 0;
|
|
||||||
|
|
||||||
lex->default_value= 0;
|
|
||||||
lex->on_update_value= 0;
|
|
||||||
|
|
||||||
lex->comment= null_lex_str;
|
|
||||||
lex->charset= NULL;
|
|
||||||
|
|
||||||
lex->interval_list.empty();
|
|
||||||
lex->uint_geom_type= 0;
|
|
||||||
lex->vcol_info= 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
sp_fdparam:
|
|
||||||
ident sp_init_param type_with_opt_collate
|
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_pcontext *spc= lex->spcont;
|
sp_pcontext *spc= lex->spcont;
|
||||||
@ -2873,19 +2936,27 @@ sp_fdparam:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp_variable *spvar= spc->add_variable(thd,
|
sp_variable *spvar= spc->add_variable(thd, $1);
|
||||||
$1,
|
|
||||||
(enum enum_field_types) $3,
|
|
||||||
sp_variable::MODE_IN);
|
|
||||||
|
|
||||||
if (lex->sphead->fill_field_definition(thd, lex,
|
lex->init_last_field(&spvar->field_def, $1.str,
|
||||||
(enum enum_field_types) $3,
|
thd->variables.collation_database);
|
||||||
&spvar->field_def))
|
$<spvar>$= spvar;
|
||||||
|
}
|
||||||
|
type_with_opt_collate
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
sp_variable *spvar= $<spvar>2;
|
||||||
|
|
||||||
|
spvar->type= $3;
|
||||||
|
if (lex->sphead->fill_field_definition(thd, lex, $3,
|
||||||
|
lex->last_field))
|
||||||
{
|
{
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
spvar->field_def.field_name= spvar->name.str;
|
spvar->field_def.field_name= spvar->name.str;
|
||||||
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
|
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
|
||||||
|
|
||||||
|
$$= spvar;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -2901,30 +2972,7 @@ sp_pdparams:
|
|||||||
;
|
;
|
||||||
|
|
||||||
sp_pdparam:
|
sp_pdparam:
|
||||||
sp_opt_inout sp_init_param ident type_with_opt_collate
|
sp_opt_inout sp_param_name_and_type { $2->mode=$1; }
|
||||||
{
|
|
||||||
LEX *lex= Lex;
|
|
||||||
sp_pcontext *spc= lex->spcont;
|
|
||||||
|
|
||||||
if (spc->find_variable($3, TRUE))
|
|
||||||
{
|
|
||||||
my_error(ER_SP_DUP_PARAM, MYF(0), $3.str);
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
sp_variable *spvar= spc->add_variable(thd,
|
|
||||||
$3,
|
|
||||||
(enum enum_field_types) $4,
|
|
||||||
(sp_variable::enum_mode) $1);
|
|
||||||
|
|
||||||
if (lex->sphead->fill_field_definition(thd, lex,
|
|
||||||
(enum enum_field_types) $4,
|
|
||||||
&spvar->field_def))
|
|
||||||
{
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
spvar->field_def.field_name= spvar->name.str;
|
|
||||||
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_opt_inout:
|
sp_opt_inout:
|
||||||
@ -2978,9 +3026,17 @@ sp_decl:
|
|||||||
DECLARE_SYM sp_decl_idents
|
DECLARE_SYM sp_decl_idents
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
|
sp_pcontext *pctx= lex->spcont;
|
||||||
|
|
||||||
|
// get the last variable:
|
||||||
|
uint num_vars= pctx->context_var_count();
|
||||||
|
uint var_idx= pctx->var_context2runtime(num_vars - 1);
|
||||||
|
sp_variable *spvar= pctx->find_variable(var_idx);
|
||||||
|
|
||||||
lex->sphead->reset_lex(thd);
|
lex->sphead->reset_lex(thd);
|
||||||
lex->spcont->declare_var_boundary($2);
|
pctx->declare_var_boundary($2);
|
||||||
|
thd->lex->init_last_field(&spvar->field_def, spvar->name.str,
|
||||||
|
thd->variables.collation_database);
|
||||||
}
|
}
|
||||||
type_with_opt_collate
|
type_with_opt_collate
|
||||||
sp_opt_default
|
sp_opt_default
|
||||||
@ -2988,7 +3044,7 @@ sp_decl:
|
|||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_pcontext *pctx= lex->spcont;
|
sp_pcontext *pctx= lex->spcont;
|
||||||
uint num_vars= pctx->context_var_count();
|
uint num_vars= pctx->context_var_count();
|
||||||
enum enum_field_types var_type= (enum enum_field_types) $4;
|
enum enum_field_types var_type= $4;
|
||||||
Item *dflt_value_item= $5;
|
Item *dflt_value_item= $5;
|
||||||
|
|
||||||
if (!dflt_value_item)
|
if (!dflt_value_item)
|
||||||
@ -3003,12 +3059,17 @@ sp_decl:
|
|||||||
{
|
{
|
||||||
uint var_idx= pctx->var_context2runtime(i);
|
uint var_idx= pctx->var_context2runtime(i);
|
||||||
sp_variable *spvar= pctx->find_variable(var_idx);
|
sp_variable *spvar= pctx->find_variable(var_idx);
|
||||||
|
bool last= i == num_vars - 1;
|
||||||
|
|
||||||
if (!spvar)
|
if (!spvar)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
|
if (!last)
|
||||||
|
spvar->field_def= *lex->last_field;
|
||||||
|
|
||||||
spvar->type= var_type;
|
spvar->type= var_type;
|
||||||
spvar->default_value= dflt_value_item;
|
spvar->default_value= dflt_value_item;
|
||||||
|
spvar->field_def.field_name= spvar->name.str;
|
||||||
|
|
||||||
if (lex->sphead->fill_field_definition(thd, lex, var_type,
|
if (lex->sphead->fill_field_definition(thd, lex, var_type,
|
||||||
&spvar->field_def))
|
&spvar->field_def))
|
||||||
@ -3016,7 +3077,6 @@ sp_decl:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
spvar->field_def.field_name= spvar->name.str;
|
|
||||||
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
|
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
|
||||||
|
|
||||||
/* The last instruction is responsible for freeing LEX. */
|
/* The last instruction is responsible for freeing LEX. */
|
||||||
@ -3027,7 +3087,7 @@ sp_decl:
|
|||||||
dflt_value_item,
|
dflt_value_item,
|
||||||
var_type,
|
var_type,
|
||||||
lex,
|
lex,
|
||||||
(i == num_vars - 1));
|
last);
|
||||||
if (is == NULL ||
|
if (is == NULL ||
|
||||||
lex->sphead->add_instr(is))
|
lex->sphead->add_instr(is))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@ -3581,10 +3641,7 @@ sp_decl_idents:
|
|||||||
my_error(ER_SP_DUP_VAR, MYF(0), $1.str);
|
my_error(ER_SP_DUP_VAR, MYF(0), $1.str);
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
spc->add_variable(thd,
|
spc->add_variable(thd, $1);
|
||||||
$1,
|
|
||||||
MYSQL_TYPE_DECIMAL,
|
|
||||||
sp_variable::MODE_IN);
|
|
||||||
$$= 1;
|
$$= 1;
|
||||||
}
|
}
|
||||||
| sp_decl_idents ',' ident
|
| sp_decl_idents ',' ident
|
||||||
@ -3599,10 +3656,7 @@ sp_decl_idents:
|
|||||||
my_error(ER_SP_DUP_VAR, MYF(0), $3.str);
|
my_error(ER_SP_DUP_VAR, MYF(0), $3.str);
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
spc->add_variable(thd,
|
spc->add_variable(thd, $3);
|
||||||
$3,
|
|
||||||
MYSQL_TYPE_DECIMAL,
|
|
||||||
sp_variable::MODE_IN);
|
|
||||||
$$= $1 + 1;
|
$$= $1 + 1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -6038,58 +6092,62 @@ field_spec:
|
|||||||
field_ident
|
field_ident
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->length=lex->dec=0;
|
Create_field *f= new Create_field();
|
||||||
lex->type=0;
|
|
||||||
lex->default_value= lex->on_update_value= 0;
|
if (check_string_char_length(&$1, "", NAME_CHAR_LEN,
|
||||||
lex->comment=null_lex_str;
|
system_charset_info, 1))
|
||||||
lex->charset=NULL;
|
{
|
||||||
lex->vcol_info= 0;
|
my_error(ER_TOO_LONG_IDENT, MYF(0), $1.str);
|
||||||
lex->option_list= NULL;
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
|
lex->init_last_field(f, $1.str, NULL);
|
||||||
}
|
}
|
||||||
|
field_type { Lex->set_last_field_type($3); }
|
||||||
field_def
|
field_def
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
if (add_field_to_list(lex->thd, &$1, $3.type,
|
Create_field *f= lex->last_field;
|
||||||
$3.length, $3.dec, lex->type,
|
|
||||||
lex->default_value, lex->on_update_value,
|
if (f->check(thd))
|
||||||
&lex->comment,
|
|
||||||
lex->change, &lex->interval_list, $3.charset,
|
|
||||||
lex->uint_geom_type,
|
|
||||||
lex->vcol_info, lex->option_list))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
|
lex->alter_info.create_list.push_back(f);
|
||||||
|
|
||||||
|
if (f->flags & PRI_KEY_FLAG)
|
||||||
|
add_key_to_list(lex, &$1, Key::PRIMARY);
|
||||||
|
else if (f->flags & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
|
||||||
|
add_key_to_list(lex, &$1, Key::UNIQUE);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
field_def:
|
field_def:
|
||||||
type opt_attribute
|
opt_attribute
|
||||||
{ $$.set($1, Lex->length, Lex->dec, Lex->charset); }
|
| opt_generated_always AS
|
||||||
| type opt_generated_always AS
|
'(' virtual_column_func ')'
|
||||||
{ $<lex_type>$.set($1, Lex->length, Lex->dec, Lex->charset); }
|
vcol_opt_specifier vcol_opt_attribute
|
||||||
'(' virtual_column_func ')' vcol_opt_specifier vcol_opt_attribute
|
|
||||||
{
|
|
||||||
$$= $<lex_type>4;
|
|
||||||
Lex->vcol_info->set_field_type($$.type);
|
|
||||||
$$.type= (enum enum_field_types)MYSQL_TYPE_VIRTUAL;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_generated_always:
|
opt_generated_always:
|
||||||
/* empty */
|
/* empty */ {}
|
||||||
| GENERATED_SYM ALWAYS_SYM {}
|
| GENERATED_SYM ALWAYS_SYM {}
|
||||||
;
|
;
|
||||||
|
|
||||||
vcol_opt_specifier:
|
vcol_opt_specifier:
|
||||||
/* empty */
|
/* empty */
|
||||||
{
|
{
|
||||||
Lex->vcol_info->set_stored_in_db_flag(FALSE);
|
Lex->last_field->vcol_info->set_stored_in_db_flag(FALSE);
|
||||||
}
|
}
|
||||||
| VIRTUAL_SYM
|
| VIRTUAL_SYM
|
||||||
{
|
{
|
||||||
Lex->vcol_info->set_stored_in_db_flag(FALSE);
|
Lex->last_field->vcol_info->set_stored_in_db_flag(FALSE);
|
||||||
}
|
}
|
||||||
| PERSISTENT_SYM
|
| PERSISTENT_SYM
|
||||||
{
|
{
|
||||||
Lex->vcol_info->set_stored_in_db_flag(TRUE);
|
Lex->last_field->vcol_info->set_stored_in_db_flag(TRUE);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -6107,16 +6165,16 @@ vcol_attribute:
|
|||||||
UNIQUE_SYM
|
UNIQUE_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->type|= UNIQUE_FLAG;
|
lex->last_field->flags|= UNIQUE_FLAG;
|
||||||
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
||||||
}
|
}
|
||||||
| UNIQUE_SYM KEY_SYM
|
| UNIQUE_SYM KEY_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->type|= UNIQUE_KEY_FLAG;
|
lex->last_field->flags|= UNIQUE_FLAG;
|
||||||
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
||||||
}
|
}
|
||||||
| COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; }
|
| COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
parse_vcol_expr:
|
parse_vcol_expr:
|
||||||
@ -6138,23 +6196,41 @@ parse_vcol_expr:
|
|||||||
virtual_column_func:
|
virtual_column_func:
|
||||||
remember_name expr remember_end
|
remember_name expr remember_end
|
||||||
{
|
{
|
||||||
Lex->vcol_info= new Virtual_column_info();
|
Virtual_column_info *v= new Virtual_column_info();
|
||||||
if (!Lex->vcol_info)
|
if (!v)
|
||||||
{
|
{
|
||||||
mem_alloc_error(sizeof(Virtual_column_info));
|
mem_alloc_error(sizeof(Virtual_column_info));
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
uint expr_len= (uint)($3 - $1) - 1;
|
uint expr_len= (uint)($3 - $1) - 1;
|
||||||
Lex->vcol_info->expr_str.str= (char* ) thd->memdup($1 + 1, expr_len);
|
v->expr_str.str= (char* ) thd->memdup($1 + 1, expr_len);
|
||||||
Lex->vcol_info->expr_str.length= expr_len;
|
v->expr_str.length= expr_len;
|
||||||
Lex->vcol_info->expr_item= $2;
|
v->expr_item= $2;
|
||||||
|
Lex->last_field->vcol_info= v;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
type:
|
field_type:
|
||||||
int_type opt_field_length field_options { $$=$1; }
|
int_type opt_field_length field_options { $$=$1; }
|
||||||
| real_type opt_precision field_options { $$=$1; }
|
| real_type opt_precision field_options { $$=$1; }
|
||||||
| FLOAT_SYM float_options field_options { $$=MYSQL_TYPE_FLOAT; }
|
| FLOAT_SYM float_options field_options
|
||||||
|
{
|
||||||
|
$$=MYSQL_TYPE_FLOAT;
|
||||||
|
if (Lex->length && !Lex->dec)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
ulonglong tmp_length= my_strtoll10(Lex->length, NULL, &err);
|
||||||
|
if (err || tmp_length > PRECISION_FOR_DOUBLE)
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_FIELD_SPEC, MYF(0),
|
||||||
|
Lex->last_field->field_name);
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
else if (tmp_length > PRECISION_FOR_FLOAT)
|
||||||
|
$$= MYSQL_TYPE_DOUBLE;
|
||||||
|
Lex->length= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
| BIT_SYM
|
| BIT_SYM
|
||||||
{
|
{
|
||||||
Lex->length= (char*) "1";
|
Lex->length= (char*) "1";
|
||||||
@ -6186,13 +6262,13 @@ type:
|
|||||||
| nchar field_length opt_bin_mod
|
| nchar field_length opt_bin_mod
|
||||||
{
|
{
|
||||||
$$=MYSQL_TYPE_STRING;
|
$$=MYSQL_TYPE_STRING;
|
||||||
Lex->charset=national_charset_info;
|
bincmp_collation(national_charset_info, $3);
|
||||||
}
|
}
|
||||||
| nchar opt_bin_mod
|
| nchar opt_bin_mod
|
||||||
{
|
{
|
||||||
Lex->length= (char*) "1";
|
Lex->length= (char*) "1";
|
||||||
$$=MYSQL_TYPE_STRING;
|
$$=MYSQL_TYPE_STRING;
|
||||||
Lex->charset=national_charset_info;
|
bincmp_collation(national_charset_info, $2);
|
||||||
}
|
}
|
||||||
| BINARY field_length
|
| BINARY field_length
|
||||||
{
|
{
|
||||||
@ -6212,7 +6288,7 @@ type:
|
|||||||
| nvarchar field_length opt_bin_mod
|
| nvarchar field_length opt_bin_mod
|
||||||
{
|
{
|
||||||
$$= MYSQL_TYPE_VARCHAR;
|
$$= MYSQL_TYPE_VARCHAR;
|
||||||
Lex->charset=national_charset_info;
|
bincmp_collation(national_charset_info, $3);
|
||||||
}
|
}
|
||||||
| VARBINARY field_length
|
| VARBINARY field_length
|
||||||
{
|
{
|
||||||
@ -6252,9 +6328,9 @@ type:
|
|||||||
/*
|
/*
|
||||||
Unlike other types TIMESTAMP fields are NOT NULL by default.
|
Unlike other types TIMESTAMP fields are NOT NULL by default.
|
||||||
*/
|
*/
|
||||||
Lex->type|= NOT_NULL_FLAG;
|
Lex->last_field->flags|= NOT_NULL_FLAG;
|
||||||
$$= opt_mysql56_temporal_format ?
|
$$= opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2
|
||||||
MYSQL_TYPE_TIMESTAMP2 : MYSQL_TYPE_TIMESTAMP;
|
: MYSQL_TYPE_TIMESTAMP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| DATETIME opt_field_length
|
| DATETIME opt_field_length
|
||||||
@ -6274,7 +6350,7 @@ type:
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_SPATIAL
|
#ifdef HAVE_SPATIAL
|
||||||
Lex->charset=&my_charset_bin;
|
Lex->charset=&my_charset_bin;
|
||||||
Lex->uint_geom_type= (uint)$1;
|
Lex->last_field->geom_type= $1;
|
||||||
$$=MYSQL_TYPE_GEOMETRY;
|
$$=MYSQL_TYPE_GEOMETRY;
|
||||||
#else
|
#else
|
||||||
my_error(ER_FEATURE_DISABLED, MYF(0),
|
my_error(ER_FEATURE_DISABLED, MYF(0),
|
||||||
@ -6313,20 +6389,16 @@ type:
|
|||||||
{ $$=MYSQL_TYPE_NEWDECIMAL;}
|
{ $$=MYSQL_TYPE_NEWDECIMAL;}
|
||||||
| FIXED_SYM float_options field_options
|
| FIXED_SYM float_options field_options
|
||||||
{ $$=MYSQL_TYPE_NEWDECIMAL;}
|
{ $$=MYSQL_TYPE_NEWDECIMAL;}
|
||||||
| ENUM
|
| ENUM '(' string_list ')' opt_binary
|
||||||
{Lex->interval_list.empty();}
|
|
||||||
'(' string_list ')' opt_binary
|
|
||||||
{ $$=MYSQL_TYPE_ENUM; }
|
{ $$=MYSQL_TYPE_ENUM; }
|
||||||
| SET
|
| SET '(' string_list ')' opt_binary
|
||||||
{ Lex->interval_list.empty();}
|
|
||||||
'(' string_list ')' opt_binary
|
|
||||||
{ $$=MYSQL_TYPE_SET; }
|
{ $$=MYSQL_TYPE_SET; }
|
||||||
| LONG_SYM opt_binary
|
| LONG_SYM opt_binary
|
||||||
{ $$=MYSQL_TYPE_MEDIUM_BLOB; }
|
{ $$=MYSQL_TYPE_MEDIUM_BLOB; }
|
||||||
| SERIAL_SYM
|
| SERIAL_SYM
|
||||||
{
|
{
|
||||||
$$=MYSQL_TYPE_LONGLONG;
|
$$=MYSQL_TYPE_LONGLONG;
|
||||||
Lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG |
|
Lex->last_field->flags|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG |
|
||||||
UNIQUE_FLAG);
|
UNIQUE_FLAG);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -6419,8 +6491,8 @@ field_opt_list:
|
|||||||
|
|
||||||
field_option:
|
field_option:
|
||||||
SIGNED_SYM {}
|
SIGNED_SYM {}
|
||||||
| UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
|
| UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG;}
|
||||||
| ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
|
| ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
|
||||||
;
|
;
|
||||||
|
|
||||||
field_length:
|
field_length:
|
||||||
@ -6450,42 +6522,42 @@ opt_attribute_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
attribute:
|
attribute:
|
||||||
NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
|
NULL_SYM { Lex->last_field->flags&= ~ NOT_NULL_FLAG; }
|
||||||
| not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
|
| not NULL_SYM { Lex->last_field->flags|= NOT_NULL_FLAG; }
|
||||||
| DEFAULT now_or_signed_literal { Lex->default_value=$2; }
|
| DEFAULT now_or_signed_literal { Lex->last_field->def= $2; }
|
||||||
| ON UPDATE_SYM NOW_SYM opt_default_time_precision
|
| ON UPDATE_SYM NOW_SYM opt_default_time_precision
|
||||||
{
|
{
|
||||||
Item *item= new (thd->mem_root) Item_func_now_local($4);
|
Item *item= new (thd->mem_root) Item_func_now_local($4);
|
||||||
if (item == NULL)
|
if (item == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->on_update_value= item;
|
Lex->last_field->on_update= item;
|
||||||
}
|
}
|
||||||
| AUTO_INC { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
|
| AUTO_INC { Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
|
||||||
| SERIAL_SYM DEFAULT VALUE_SYM
|
| SERIAL_SYM DEFAULT VALUE_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG;
|
lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG;
|
||||||
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
||||||
}
|
}
|
||||||
| opt_primary KEY_SYM
|
| opt_primary KEY_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
|
lex->last_field->flags|= PRI_KEY_FLAG | NOT_NULL_FLAG;
|
||||||
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
||||||
}
|
}
|
||||||
| UNIQUE_SYM
|
| UNIQUE_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->type|= UNIQUE_FLAG;
|
lex->last_field->flags|= UNIQUE_FLAG;
|
||||||
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
||||||
}
|
}
|
||||||
| UNIQUE_SYM KEY_SYM
|
| UNIQUE_SYM KEY_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->type|= UNIQUE_KEY_FLAG;
|
lex->last_field->flags|= UNIQUE_KEY_FLAG;
|
||||||
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
|
||||||
}
|
}
|
||||||
| COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; }
|
| COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; }
|
||||||
| COLLATE_SYM collation_name
|
| COLLATE_SYM collation_name
|
||||||
{
|
{
|
||||||
if (Lex->charset && !my_charset_same(Lex->charset,$2))
|
if (Lex->charset && !my_charset_same(Lex->charset,$2))
|
||||||
@ -6496,52 +6568,46 @@ attribute:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Lex->charset=$2;
|
Lex->last_field->charset= $2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| IDENT_sys equal TEXT_STRING_sys
|
| IDENT_sys equal TEXT_STRING_sys
|
||||||
{
|
{
|
||||||
new (thd->mem_root)
|
new (thd->mem_root)
|
||||||
engine_option_value($1, $3, true, &Lex->option_list,
|
engine_option_value($1, $3, true, &Lex->last_field->option_list,
|
||||||
&Lex->option_list_last);
|
&Lex->option_list_last);
|
||||||
}
|
}
|
||||||
| IDENT_sys equal ident
|
| IDENT_sys equal ident
|
||||||
{
|
{
|
||||||
new (thd->mem_root)
|
new (thd->mem_root)
|
||||||
engine_option_value($1, $3, false, &Lex->option_list,
|
engine_option_value($1, $3, false, &Lex->last_field->option_list,
|
||||||
&Lex->option_list_last);
|
&Lex->option_list_last);
|
||||||
}
|
}
|
||||||
| IDENT_sys equal real_ulonglong_num
|
| IDENT_sys equal real_ulonglong_num
|
||||||
{
|
{
|
||||||
new (thd->mem_root)
|
new (thd->mem_root)
|
||||||
engine_option_value($1, $3, &Lex->option_list,
|
engine_option_value($1, $3, &Lex->last_field->option_list,
|
||||||
&Lex->option_list_last, thd->mem_root);
|
&Lex->option_list_last, thd->mem_root);
|
||||||
}
|
}
|
||||||
| IDENT_sys equal DEFAULT
|
| IDENT_sys equal DEFAULT
|
||||||
{
|
{
|
||||||
new (thd->mem_root)
|
new (thd->mem_root)
|
||||||
engine_option_value($1, &Lex->option_list, &Lex->option_list_last);
|
engine_option_value($1, &Lex->last_field->option_list, &Lex->option_list_last);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
type_with_opt_collate:
|
type_with_opt_collate:
|
||||||
type opt_collate
|
field_type opt_collate
|
||||||
{
|
{
|
||||||
$$= $1;
|
$$= $1;
|
||||||
|
|
||||||
if (Lex->charset) /* Lex->charset is scanned in "type" */
|
if ($2)
|
||||||
{
|
{
|
||||||
if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))
|
if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
else if ($2)
|
Lex->set_last_field_type($1);
|
||||||
{
|
|
||||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
|
|
||||||
"COLLATE with no CHARACTER SET "
|
|
||||||
"in SP parameters, RETURNS, DECLARE");
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -6625,62 +6691,30 @@ opt_default:
|
|||||||
| DEFAULT {}
|
| DEFAULT {}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
charset_or_alias:
|
||||||
ascii:
|
charset charset_name { $$= $2; }
|
||||||
ASCII_SYM { Lex->charset= &my_charset_latin1; }
|
| ASCII_SYM { $$= &my_charset_latin1; }
|
||||||
| BINARY ASCII_SYM
|
| UNICODE_SYM
|
||||||
{
|
{
|
||||||
Lex->charset= &my_charset_latin1_bin;
|
if (!($$= get_charset_by_csname("ucs2", MY_CS_PRIMARY,MYF(0))))
|
||||||
}
|
|
||||||
| ASCII_SYM BINARY
|
|
||||||
{
|
|
||||||
Lex->charset= &my_charset_latin1_bin;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
unicode:
|
|
||||||
UNICODE_SYM
|
|
||||||
{
|
|
||||||
if (!(Lex->charset=get_charset_by_csname("ucs2",
|
|
||||||
MY_CS_PRIMARY,MYF(0))))
|
|
||||||
{
|
{
|
||||||
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2");
|
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2");
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| UNICODE_SYM BINARY
|
|
||||||
{
|
|
||||||
if (!(Lex->charset= mysqld_collation_get_by_name("ucs2_bin")))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
| BINARY UNICODE_SYM
|
|
||||||
{
|
|
||||||
if (!(Lex->charset= mysqld_collation_get_by_name("ucs2_bin")))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_binary:
|
opt_binary:
|
||||||
/* empty */ { Lex->charset=NULL; }
|
/* empty */ { bincmp_collation(NULL, false); }
|
||||||
| ascii
|
| BYTE_SYM { bincmp_collation(&my_charset_bin, false); }
|
||||||
| unicode
|
| charset_or_alias opt_bin_mod { bincmp_collation($1, $2); }
|
||||||
| BYTE_SYM { Lex->charset=&my_charset_bin; }
|
| BINARY { bincmp_collation(NULL, true); }
|
||||||
| charset charset_name opt_bin_mod { Lex->charset=$2; }
|
| BINARY charset_or_alias { bincmp_collation($2, true); }
|
||||||
| BINARY
|
|
||||||
{
|
|
||||||
Lex->charset= NULL;
|
|
||||||
Lex->type|= BINCMP_FLAG;
|
|
||||||
}
|
|
||||||
| BINARY charset charset_name
|
|
||||||
{
|
|
||||||
Lex->charset= $3;
|
|
||||||
Lex->type|= BINCMP_FLAG;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_bin_mod:
|
opt_bin_mod:
|
||||||
/* empty */ { }
|
/* empty */ { $$= false; }
|
||||||
| BINARY { Lex->type|= BINCMP_FLAG; }
|
| BINARY { $$= true; }
|
||||||
;
|
;
|
||||||
|
|
||||||
ws_nweights:
|
ws_nweights:
|
||||||
@ -7051,8 +7085,8 @@ opt_component:
|
|||||||
;
|
;
|
||||||
|
|
||||||
string_list:
|
string_list:
|
||||||
text_string { Lex->interval_list.push_back($1); }
|
text_string { Lex->last_field->interval_list.push_back($1); }
|
||||||
| string_list ',' text_string { Lex->interval_list.push_back($3); };
|
| string_list ',' text_string { Lex->last_field->interval_list.push_back($3); };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Alter table
|
** Alter table
|
||||||
@ -7522,7 +7556,6 @@ add_column:
|
|||||||
ADD opt_column opt_if_not_exists
|
ADD opt_column opt_if_not_exists
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->change=0;
|
|
||||||
lex->alter_info.flags|= Alter_info::ALTER_ADD_COLUMN;
|
lex->alter_info.flags|= Alter_info::ALTER_ADD_COLUMN;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -7542,44 +7575,17 @@ alter_list_item:
|
|||||||
Lex->alter_info.flags|= Alter_info::ALTER_ADD_COLUMN |
|
Lex->alter_info.flags|= Alter_info::ALTER_ADD_COLUMN |
|
||||||
Alter_info::ALTER_ADD_INDEX;
|
Alter_info::ALTER_ADD_INDEX;
|
||||||
}
|
}
|
||||||
| CHANGE opt_column opt_if_exists field_ident
|
| CHANGE opt_column opt_if_exists field_ident field_spec opt_place
|
||||||
{
|
|
||||||
LEX *lex=Lex;
|
|
||||||
lex->change= $4.str;
|
|
||||||
lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
|
|
||||||
lex->option_list= NULL;
|
|
||||||
}
|
|
||||||
field_spec opt_place
|
|
||||||
{
|
{
|
||||||
|
Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
|
||||||
Lex->create_last_non_select_table= Lex->last_table();
|
Lex->create_last_non_select_table= Lex->last_table();
|
||||||
|
Lex->last_field->change= $4.str;
|
||||||
}
|
}
|
||||||
| MODIFY_SYM opt_column opt_if_exists field_ident
|
| MODIFY_SYM opt_column opt_if_exists field_spec opt_place
|
||||||
{
|
|
||||||
LEX *lex=Lex;
|
|
||||||
lex->length=lex->dec=0; lex->type=0;
|
|
||||||
lex->default_value= lex->on_update_value= 0;
|
|
||||||
lex->comment=null_lex_str;
|
|
||||||
lex->charset= NULL;
|
|
||||||
lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
|
|
||||||
lex->vcol_info= 0;
|
|
||||||
lex->option_list= NULL;
|
|
||||||
}
|
|
||||||
field_def
|
|
||||||
{
|
|
||||||
LEX *lex=Lex;
|
|
||||||
if (add_field_to_list(lex->thd,&$4,
|
|
||||||
$6.type,
|
|
||||||
$6.length, $6.dec, lex->type,
|
|
||||||
lex->default_value, lex->on_update_value,
|
|
||||||
&lex->comment,
|
|
||||||
$4.str, &lex->interval_list, $6.charset,
|
|
||||||
lex->uint_geom_type,
|
|
||||||
lex->vcol_info, lex->option_list))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
opt_place
|
|
||||||
{
|
{
|
||||||
|
Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
|
||||||
Lex->create_last_non_select_table= Lex->last_table();
|
Lex->create_last_non_select_table= Lex->last_table();
|
||||||
|
Lex->last_field->change= Lex->last_field->field_name;
|
||||||
}
|
}
|
||||||
| DROP opt_column opt_if_exists field_ident opt_restrict
|
| DROP opt_column opt_if_exists field_ident opt_restrict
|
||||||
{
|
{
|
||||||
@ -9083,7 +9089,9 @@ dyncol_type:
|
|||||||
$$= DYN_COL_DECIMAL;
|
$$= DYN_COL_DECIMAL;
|
||||||
Lex->charset= NULL;
|
Lex->charset= NULL;
|
||||||
}
|
}
|
||||||
| char opt_binary
|
| char
|
||||||
|
{ Lex->charset= thd->variables.collation_connection; }
|
||||||
|
opt_binary
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
$$= DYN_COL_STRING;
|
$$= DYN_COL_STRING;
|
||||||
@ -10414,7 +10422,9 @@ in_sum_expr:
|
|||||||
cast_type:
|
cast_type:
|
||||||
BINARY opt_field_length
|
BINARY opt_field_length
|
||||||
{ $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; }
|
{ $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; }
|
||||||
| CHAR_SYM opt_field_length opt_binary
|
| CHAR_SYM opt_field_length
|
||||||
|
{ Lex->charset= thd->variables.collation_connection; }
|
||||||
|
opt_binary
|
||||||
{ $$=ITEM_CAST_CHAR; Lex->dec= 0; }
|
{ $$=ITEM_CAST_CHAR; Lex->dec= 0; }
|
||||||
| NCHAR_SYM opt_field_length
|
| NCHAR_SYM opt_field_length
|
||||||
{ $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; }
|
{ $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; }
|
||||||
@ -13259,8 +13269,7 @@ opt_ignore_lines:
|
|||||||
;
|
;
|
||||||
|
|
||||||
lines_or_rows:
|
lines_or_rows:
|
||||||
LINES { }
|
LINES { }
|
||||||
|
|
||||||
| ROWS_SYM { }
|
| ROWS_SYM { }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -16233,31 +16242,13 @@ sf_tail:
|
|||||||
RETURNS_SYM /* $9 */
|
RETURNS_SYM /* $9 */
|
||||||
{ /* $10 */
|
{ /* $10 */
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
lex->charset= NULL;
|
lex->init_last_field(&lex->sphead->m_return_field_def, NULL,
|
||||||
lex->length= lex->dec= NULL;
|
thd->variables.collation_database);
|
||||||
lex->interval_list.empty();
|
|
||||||
lex->type= 0;
|
|
||||||
lex->vcol_info= 0;
|
|
||||||
}
|
}
|
||||||
type_with_opt_collate /* $11 */
|
type_with_opt_collate /* $11 */
|
||||||
{ /* $12 */
|
{ /* $12 */
|
||||||
LEX *lex= Lex;
|
if (Lex->sphead->fill_field_definition(thd, Lex, $11,
|
||||||
sp_head *sp= lex->sphead;
|
Lex->last_field))
|
||||||
/*
|
|
||||||
This was disabled in 5.1.12. See bug #20701
|
|
||||||
When collation support in SP is implemented, then this test
|
|
||||||
should be removed.
|
|
||||||
*/
|
|
||||||
if (($11 == MYSQL_TYPE_STRING || $11 == MYSQL_TYPE_VARCHAR)
|
|
||||||
&& (lex->type & BINCMP_FLAG))
|
|
||||||
{
|
|
||||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "return value collation");
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sp->fill_field_definition(thd, lex,
|
|
||||||
(enum enum_field_types) $11,
|
|
||||||
&sp->m_return_field_def))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
sp_c_chistics /* $13 */
|
sp_c_chistics /* $13 */
|
||||||
|
@ -2395,6 +2395,7 @@ bool unpack_vcol_info_from_frm(THD *thd,
|
|||||||
Query_arena *backup_stmt_arena_ptr;
|
Query_arena *backup_stmt_arena_ptr;
|
||||||
Query_arena backup_arena;
|
Query_arena backup_arena;
|
||||||
Query_arena *vcol_arena= 0;
|
Query_arena *vcol_arena= 0;
|
||||||
|
Create_field vcol_storage; // placeholder for vcol_info
|
||||||
Parser_state parser_state;
|
Parser_state parser_state;
|
||||||
LEX *old_lex= thd->lex;
|
LEX *old_lex= thd->lex;
|
||||||
LEX lex;
|
LEX lex;
|
||||||
@ -2458,7 +2459,8 @@ bool unpack_vcol_info_from_frm(THD *thd,
|
|||||||
if (init_lex_with_single_table(thd, table, &lex))
|
if (init_lex_with_single_table(thd, table, &lex))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
thd->lex->parse_vcol_expr= TRUE;
|
lex.parse_vcol_expr= TRUE;
|
||||||
|
lex.last_field= &vcol_storage;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Step 3: Use the parser to build an Item object from vcol_expr_str.
|
Step 3: Use the parser to build an Item object from vcol_expr_str.
|
||||||
@ -2468,7 +2470,7 @@ bool unpack_vcol_info_from_frm(THD *thd,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
/* From now on use vcol_info generated by the parser. */
|
/* From now on use vcol_info generated by the parser. */
|
||||||
field->vcol_info= thd->lex->vcol_info;
|
field->vcol_info= vcol_storage.vcol_info;
|
||||||
|
|
||||||
/* Validate the Item tree. */
|
/* Validate the Item tree. */
|
||||||
if (fix_vcol_expr(thd, table, field))
|
if (fix_vcol_expr(thd, table, field))
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
This code needs extra visibility in the lexer structures
|
This code needs extra visibility in the lexer structures
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define MYSQL_LEX 1
|
||||||
|
|
||||||
#include "my_global.h"
|
#include "my_global.h"
|
||||||
#include "my_sys.h"
|
#include "my_sys.h"
|
||||||
#include "pfs_instr.h"
|
#include "pfs_instr.h"
|
||||||
@ -35,7 +37,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* Generated code */
|
/* Generated code */
|
||||||
#include "../sql/sql_yacc.h"
|
|
||||||
#include "../storage/perfschema/pfs_lex_token.h"
|
#include "../storage/perfschema/pfs_lex_token.h"
|
||||||
|
|
||||||
/* Name pollution from sql/sql_lex.h */
|
/* Name pollution from sql/sql_lex.h */
|
||||||
|
Reference in New Issue
Block a user