1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

Merge remote-tracking branch 'origin/bb-10.2-ext' into 10.3

This commit is contained in:
Alexander Barkov
2017-09-28 18:56:15 +04:00
32 changed files with 959 additions and 261 deletions

View File

@@ -836,6 +836,47 @@ void revert_properties();
static void handle_no_active_connection(struct st_command* command,
struct st_connection *cn, DYNAMIC_STRING *ds);
/* Wrapper for fgets.Strips \r off newlines on Windows.
Should be used with together with my_popen().
*/
static char *my_fgets(char * s, int n, FILE * stream, int *len)
{
char *buf = fgets(s, n, stream);
if (!buf)
{
*len= 0;
return buf;
}
*len = (int)strlen(buf);
#ifdef _WIN32
/* Strip '\r' off newlines. */
if (*len > 1 && buf[*len - 2] == '\r' && buf[*len - 1] == '\n')
{
buf[*len - 2]= '\n';
buf[*len - 1]= 0;
(*len)--;
}
#endif
return buf;
}
/*
Wrapper for popen().
On Windows, uses binary mode to workaround
C runtime bug mentioned in MDEV-9409
*/
static FILE* my_popen(const char *cmd, const char *mode)
{
FILE *f= popen(cmd, mode);
#ifdef _WIN32
if (f)
_setmode(fileno(f), O_BINARY);
#endif
return f;
}
#ifdef EMBEDDED_LIBRARY
#define EMB_SEND_QUERY 1
@@ -1785,19 +1826,20 @@ static int run_command(char* cmd,
DBUG_ENTER("run_command");
DBUG_PRINT("enter", ("cmd: %s", cmd));
if (!(res_file= popen(cmd, "r")))
if (!(res_file= my_popen(cmd, "r")))
{
report_or_die("popen(\"%s\", \"r\") failed", cmd);
DBUG_RETURN(-1);
}
while (fgets(buf, sizeof(buf), res_file))
int len;
while (my_fgets(buf, sizeof(buf), res_file, &len))
{
DBUG_PRINT("info", ("buf: %s", buf));
if(ds_res)
{
/* Save the output of this command in the supplied string */
dynstr_append(ds_res, buf);
dynstr_append_mem(ds_res, buf,len);
}
else
{
@@ -1886,14 +1928,15 @@ static int diff_check(const char *diff_name)
my_snprintf(buf, sizeof(buf), "%s -v", diff_name);
if (!(res_file= popen(buf, "r")))
if (!(res_file= my_popen(buf, "r")))
die("popen(\"%s\", \"r\") failed", buf);
/*
if diff is not present, nothing will be in stdout to increment
have_diff
*/
if (fgets(buf, sizeof(buf), res_file))
int len;
if (my_fgets(buf, sizeof(buf), res_file, &len))
have_diff= 1;
pclose(res_file);
@@ -3246,18 +3289,6 @@ void free_tmp_sh_file()
#endif
FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode)
{
#if defined _WIN32 && defined USE_CYGWIN
/* Dump the command into a sh script file and execute with popen */
str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length);
return popen(tmp_sh_cmd, mode);
#else
return popen(ds_cmd->str, mode);
#endif
}
static void init_builtin_echo(void)
{
#ifdef _WIN32
@@ -3392,7 +3423,7 @@ void do_exec(struct st_command *command)
DBUG_PRINT("info", ("Executing '%s' as '%s'",
command->first_argument, ds_cmd.str));
if (!(res_file= my_popen(&ds_cmd, "r")))
if (!(res_file= my_popen(ds_cmd.str, "r")))
{
dynstr_free(&ds_cmd);
if (command->abort_on_error)
@@ -3406,24 +3437,9 @@ void do_exec(struct st_command *command)
init_dynamic_string(&ds_sorted, "", 1024, 1024);
ds_result= &ds_sorted;
}
#ifdef _WIN32
/* Workaround for CRT bug, MDEV-9409 */
_setmode(fileno(res_file), O_BINARY);
#endif
while (fgets(buf, sizeof(buf), res_file))
int len;
while (my_fgets(buf, sizeof(buf), res_file,&len))
{
int len = (int)strlen(buf);
#ifdef _WIN32
/* Strip '\r' off newlines. */
if (len > 1 && buf[len-2] == '\r' && buf[len-1] == '\n')
{
buf[len-2] = '\n';
buf[len-1] = 0;
len--;
}
#endif
replace_dynstr_append_mem(ds_result, buf, len);
}
error= pclose(res_file);
@@ -4685,7 +4701,7 @@ void do_perl(struct st_command *command)
/* Format the "perl <filename>" command */
my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path);
if (!(res_file= popen(buf, "r")))
if (!(res_file= my_popen(buf, "r")))
{
if (command->abort_on_error)
die("popen(\"%s\", \"r\") failed", buf);
@@ -4693,16 +4709,17 @@ void do_perl(struct st_command *command)
DBUG_VOID_RETURN;
}
while (fgets(buf, sizeof(buf), res_file))
int len;
while (my_fgets(buf, sizeof(buf), res_file,&len))
{
if (disable_result_log)
{
buf[strlen(buf)-1]=0;
DBUG_PRINT("exec_result",("%s", buf));
buf[len - 1] = 0;
DBUG_PRINT("exec_result", ("%s", buf));
}
else
{
replace_dynstr_append(&ds_res, buf);
replace_dynstr_append_mem(&ds_res, buf, len);
}
}
error= pclose(res_file);

View File

@@ -16,7 +16,7 @@
--net-buffer-length=#
Buffer length for TCP/IP and socket communication
--net-read-timeout=#
@@ -956,6 +956,9 @@
@@ -957,6 +957,9 @@
characteristics (isolation level, read only/read
write,snapshot - but not any work done / data modified
within the transaction).
@@ -26,7 +26,7 @@
--show-slave-auth-info
Show user and password in SHOW SLAVE HOSTS on this
master.
@@ -1068,6 +1071,10 @@
@@ -1069,6 +1072,10 @@
Log slow queries to given log file. Defaults logging to
'hostname'-slow.log. Must be enabled to activate other
slow log options
@@ -37,7 +37,7 @@
--socket=name Socket file to use for connection
--sort-buffer-size=#
Each thread that needs to do a sort allocates a buffer of
@@ -1086,6 +1093,7 @@
@@ -1087,6 +1094,7 @@
NO_ENGINE_SUBSTITUTION, PAD_CHAR_TO_FULL_LENGTH
--stack-trace Print a symbolic stack trace on failure
(Defaults to on; use --skip-stack-trace to disable.)

View File

@@ -626,9 +626,10 @@ The following options may be given as the first argument:
--open-files-limit=#
If this is not 0, then mysqld will use this value to
reserve file descriptors to use with setrlimit(). If this
value is 0 then mysqld will reserve max_connections*5 or
max_connections + table_cache*2 (whichever is larger)
number of file descriptors
value is 0 or autoset then mysqld will reserve
max_connections*5 or max_connections + table_cache*2
(whichever is larger) number of file descriptors
(Automatically configured unless set explicitly)
--optimizer-prune-level=#
Controls the heuristic(s) applied during query
optimization to prune less-promising partial plans from

View File

@@ -130,3 +130,275 @@ t1 CREATE TABLE "t1" (
)
DROP TABLE t1;
DROP FUNCTION f1;
MDEV-13919 sql_mode=ORACLE: Derive length of VARCHAR SP parameters with no length from actual parameters
set sql_mode= 'oracle,strict_trans_tables';
CREATE OR REPLACE PROCEDURE p1(pinout INOUT varchar, pin IN varchar)
AS
BEGIN
pinout:=pin;
END;
/
call p1(@w,'0123456789')
/
declare w varchar(10);
begin
call p1(w,'0123456789');
end;
/
declare w varchar(5);
begin
call p1(w,'0123456789');
end;
/
ERROR 22001: Data too long for column 'pinout' at row 1
declare w varchar(20);
begin
w:='aaa';
call p1(w,'0123456789');
end;
/
declare w varchar(8);
begin
w:='aaa';
call p1(w,'0123456789');
end;
/
ERROR 22001: Data too long for column 'pinout' at row 1
declare str varchar(6000);
pout varchar(6000);
begin
str:=lpad('x',6000,'y');
call p1(pout,str);
select length(pout);
end;
/
length(pout)
6000
declare str varchar(6000);
pout varchar(4000);
begin
str:=lpad('x',6000,'y');
call p1(pout,str);
select length(pout);
end;
/
ERROR 22001: Data too long for column 'pinout' at row 1
declare str varchar(40000);
pout varchar(60000);
begin
str:=lpad('x',40000,'y');
call p1(pout,str);
select length(pout);
end;
/
length(pout)
40000
declare str text(80000);
pout text(80000);
begin
str:=lpad('x',80000,'y');
call p1(pout,str);
select length(pout);
end;
/
ERROR 22001: Data too long for column 'pin' at row 1
declare str text(80000);
pout text(80000);
begin
str:=lpad('x',60000,'y');
call p1(pout,str);
select length(pout);
end;
/
length(pout)
60000
drop procedure p1
/
SET sql_mode=ORACLE;
CREATE PROCEDURE p1(pinout INOUT varchar, pin IN varchar)
AS
BEGIN
pinout:=pin;
END;
/
CREATE PROCEDURE p2(len INT)
AS
pinout VARCHAR(10);
pin VARCHAR(30);
BEGIN
pin:= REPEAT('x', len);
p1(pinout, pin);
SELECT LENGTH(pinout);
END;
/
CALL p2(10);
LENGTH(pinout)
10
CALL p2(11);
LENGTH(pinout)
10
Warnings:
Warning 1265 Data truncated for column 'pinout' at row 1
DROP PROCEDURE p1;
DROP PROCEDURE p2;
SET sql_mode=ORACLE;
CREATE FUNCTION f1(pin VARCHAR, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT :='x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
CALL p2(65535);
LENGTH(f1(str,padlen))
65535
CALL p2(65536);
LENGTH(f1(str,padlen))
65535
Warnings:
Warning 1265 Data truncated for column 'pin' at row 1
DROP PROCEDURE p2;
DROP FUNCTION f1;
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
CREATE PROCEDURE p1(pinout INOUT VARCHAR CHARACTER SET utf8,
pin IN VARCHAR CHARACTER SET utf8)
AS
BEGIN
pinout:=pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str VARCHAR(40000) CHARACTER SET latin1;
pout VARCHAR(60000) CHARACTER SET latin1;
BEGIN
str:=lpad('x',padlen,'y');
p1(pout,str);
SELECT length(pout);
END;
/
CALL p2(21844);
length(pout)
21844
CALL p2(21845);
length(pout)
21845
CALL p2(21846);
ERROR 22001: Data too long for column 'pin' at row 1
DROP PROCEDURE p2;
DROP PROCEDURE p1;
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
CREATE PROCEDURE p1(pinout INOUT VARCHAR CHARACTER SET utf8,
pin IN VARCHAR CHARACTER SET utf8)
AS
BEGIN
pinout:=pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET utf8;
pout TEXT CHARACTER SET utf8;
BEGIN
str:=lpad('x',padlen,'y');
p1(pout,str);
SELECT length(pout);
END;
/
CALL p2(21845);
length(pout)
21845
CALL p2(21846);
ERROR 22001: Data too long for column 'pin' at row 1
DROP PROCEDURE p2;
DROP PROCEDURE p1;
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
CREATE FUNCTION f1(pin VARCHAR CHARACTER SET latin1, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET latin1 :='x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
CALL p2(65535);
LENGTH(f1(str,padlen))
65535
CALL p2(65536);
ERROR 22001: Data too long for column 'pin' at row 1
DROP PROCEDURE p2;
DROP FUNCTION f1;
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
CREATE FUNCTION f1(pin VARCHAR CHARACTER SET utf8, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET utf8 := 'x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
CALL p2(21845);
LENGTH(f1(str,padlen))
21845
CALL p2(21846);
ERROR 22001: Data too long for column 'pin' at row 1
DROP PROCEDURE p2;
DROP FUNCTION f1;
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
CREATE FUNCTION f1(pin VARCHAR CHARACTER SET utf8, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET latin1 := 'x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
CALL p2(21845);
LENGTH(f1(str,padlen))
21845
CALL p2(21846);
ERROR 22001: Data too long for column 'pin' at row 1
DROP PROCEDURE p2;
DROP FUNCTION f1;
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
CREATE FUNCTION f1(pin VARCHAR CHARACTER SET latin1, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET utf8 := 'x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
CALL p2(65535);
LENGTH(f1(str,padlen))
65535
CALL p2(65536);
ERROR 22001: Data too long for column 'pin' at row 1
DROP PROCEDURE p2;
DROP FUNCTION f1;

View File

@@ -35,3 +35,310 @@ SET sql_mode=ORACLE;
--let type = RAW
--let length = 4000
--source sp-param.inc
--echo
--echo MDEV-13919 sql_mode=ORACLE: Derive length of VARCHAR SP parameters with no length from actual parameters
--echo
set sql_mode= 'oracle,strict_trans_tables';
delimiter /;
CREATE OR REPLACE PROCEDURE p1(pinout INOUT varchar, pin IN varchar)
AS
BEGIN
pinout:=pin;
END;
/
call p1(@w,'0123456789')
/
declare w varchar(10);
begin
call p1(w,'0123456789');
end;
/
--error ER_DATA_TOO_LONG
declare w varchar(5);
begin
call p1(w,'0123456789');
end;
/
declare w varchar(20);
begin
w:='aaa';
call p1(w,'0123456789');
end;
/
--error ER_DATA_TOO_LONG
declare w varchar(8);
begin
w:='aaa';
call p1(w,'0123456789');
end;
/
declare str varchar(6000);
pout varchar(6000);
begin
str:=lpad('x',6000,'y');
call p1(pout,str);
select length(pout);
end;
/
--error ER_DATA_TOO_LONG
declare str varchar(6000);
pout varchar(4000);
begin
str:=lpad('x',6000,'y');
call p1(pout,str);
select length(pout);
end;
/
declare str varchar(40000);
pout varchar(60000);
begin
str:=lpad('x',40000,'y');
call p1(pout,str);
select length(pout);
end;
/
--error ER_DATA_TOO_LONG
declare str text(80000);
pout text(80000);
begin
str:=lpad('x',80000,'y');
call p1(pout,str);
select length(pout);
end;
/
declare str text(80000);
pout text(80000);
begin
str:=lpad('x',60000,'y');
call p1(pout,str);
select length(pout);
end;
/
drop procedure p1
/
DELIMITER ;/
#
# Procedure, non-strict mode
#
SET sql_mode=ORACLE;
DELIMITER /;
CREATE PROCEDURE p1(pinout INOUT varchar, pin IN varchar)
AS
BEGIN
pinout:=pin;
END;
/
CREATE PROCEDURE p2(len INT)
AS
pinout VARCHAR(10);
pin VARCHAR(30);
BEGIN
pin:= REPEAT('x', len);
p1(pinout, pin);
SELECT LENGTH(pinout);
END;
/
DELIMITER ;/
CALL p2(10);
CALL p2(11);
DROP PROCEDURE p1;
DROP PROCEDURE p2;
#
# Function, not-strict mode
#
SET sql_mode=ORACLE;
DELIMITER /;
CREATE FUNCTION f1(pin VARCHAR, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT :='x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
DELIMITER ;/
CALL p2(65535);
CALL p2(65536);
DROP PROCEDURE p2;
DROP FUNCTION f1;
#
# Procedure, utf8 formal parameter, latin actual parameter
#
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
DELIMITER /;
CREATE PROCEDURE p1(pinout INOUT VARCHAR CHARACTER SET utf8,
pin IN VARCHAR CHARACTER SET utf8)
AS
BEGIN
pinout:=pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str VARCHAR(40000) CHARACTER SET latin1;
pout VARCHAR(60000) CHARACTER SET latin1;
BEGIN
str:=lpad('x',padlen,'y');
p1(pout,str);
SELECT length(pout);
END;
/
DELIMITER ;/
CALL p2(21844);
CALL p2(21845);
--error ER_DATA_TOO_LONG
CALL p2(21846);
DROP PROCEDURE p2;
DROP PROCEDURE p1;
#
# Procedure, utf8 formal parameter, utf8 actual parameter
#
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
DELIMITER /;
CREATE PROCEDURE p1(pinout INOUT VARCHAR CHARACTER SET utf8,
pin IN VARCHAR CHARACTER SET utf8)
AS
BEGIN
pinout:=pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET utf8;
pout TEXT CHARACTER SET utf8;
BEGIN
str:=lpad('x',padlen,'y');
p1(pout,str);
SELECT length(pout);
END;
/
DELIMITER ;/
CALL p2(21845);
--error ER_DATA_TOO_LONG
CALL p2(21846);
DROP PROCEDURE p2;
DROP PROCEDURE p1;
#
# Function, latin1 formal parameter, latin1 actual parameter
#
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
DELIMITER /;
CREATE FUNCTION f1(pin VARCHAR CHARACTER SET latin1, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET latin1 :='x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
DELIMITER ;/
CALL p2(65535);
--error ER_DATA_TOO_LONG
CALL p2(65536);
DROP PROCEDURE p2;
DROP FUNCTION f1;
#
# Function, utf8 formal parameter, utf8 actual parameter
#
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
DELIMITER /;
CREATE FUNCTION f1(pin VARCHAR CHARACTER SET utf8, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET utf8 := 'x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
DELIMITER ;/
CALL p2(21845);
--error ER_DATA_TOO_LONG
CALL p2(21846);
DROP PROCEDURE p2;
DROP FUNCTION f1;
#
# Function, utf8 formal parameter, latin1 actual parameter
#
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
DELIMITER /;
CREATE FUNCTION f1(pin VARCHAR CHARACTER SET utf8, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET latin1 := 'x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
DELIMITER ;/
CALL p2(21845);
--error ER_DATA_TOO_LONG
CALL p2(21846);
DROP PROCEDURE p2;
DROP FUNCTION f1;
#
# Function, latin1 formal parameter, utf8 actual parameter
#
SET sql_mode='ORACLE,STRICT_TRANS_TABLES';
DELIMITER /;
CREATE FUNCTION f1(pin VARCHAR CHARACTER SET latin1, padlen INT) RETURN TEXT
AS
BEGIN
pin:=LPAD(pin, padlen);
RETURN pin;
END;
/
CREATE PROCEDURE p2(padlen INT) AS
str TEXT CHARACTER SET utf8 := 'x';
BEGIN
SELECT LENGTH(f1(str,padlen));
END;
/
DELIMITER ;/
CALL p2(65535);
--error ER_DATA_TOO_LONG
CALL p2(65536);
DROP PROCEDURE p2;
DROP FUNCTION f1;

View File

@@ -0,0 +1,3 @@
select @@global.host_cache_size;
@@global.host_cache_size
653

View File

@@ -1237,7 +1237,7 @@
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
@@ -4402,7 +4402,7 @@

View File

@@ -4476,7 +4476,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME OPEN_FILES_LIMIT
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
NUMERIC_BLOCK_SIZE 1

View File

@@ -1291,7 +1291,7 @@
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
@@ -5382,7 +5382,7 @@

View File

@@ -5372,7 +5372,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME OPEN_FILES_LIMIT
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
NUMERIC_BLOCK_SIZE 1

View File

@@ -0,0 +1 @@
--max_connections=1000 --open-files-limit=1000 --autoset-host-cache-size

View File

@@ -0,0 +1 @@
select @@global.host_cache_size;

View File

@@ -4244,6 +4244,10 @@ public:
}
return 0;
}
bool adjust_formal_params_to_actual_params(THD *thd, List<Item> *args);
bool adjust_formal_params_to_actual_params(THD *thd,
Item **args, uint arg_count);
bool resolve_type_refs(THD *);
};

View File

@@ -1541,6 +1541,45 @@ bool mark_unsupported_function(const char *w1, const char *w2,
return mark_unsupported_function(ptr, store, result);
}
Query_fragment::Query_fragment(THD *thd, sp_head *sphead,
const char *start, const char *end)
{
DBUG_ASSERT(start <= end);
if (sphead)
{
if (sphead->m_tmp_query)
{
// Normal SP statement
DBUG_ASSERT(sphead->m_tmp_query <= start);
set(start - sphead->m_tmp_query, end - start);
}
else
{
/*
We're in the "if" expression of a compound query:
if (expr)
do_something;
end if;
sphead->m_tmp_query is not set yet at this point, because
the "if" part of such statements is never put into the binary log.
Values of Rewritable_query_parameter::pos_in_query and
Rewritable_query_parameter:len_in_query will not be important,
so setting both to 0 should be fine.
*/
set(0, 0);
}
}
else
{
// Non-SP statement
DBUG_ASSERT(thd->query() <= start);
DBUG_ASSERT(end <= thd->query_end());
set(start - thd->query(), end - start);
}
}
/*****************************************************************************
Item_sp_variable methods
*****************************************************************************/

View File

@@ -89,6 +89,7 @@ public:
const char *dbug_print_item(Item *item);
class sp_head;
class Protocol;
struct TABLE_LIST;
void item_init(void); /* Init item functions */
@@ -391,6 +392,31 @@ public:
{ return NULL; }
};
/*
A helper class to calculate offset and length of a query fragment
- outside of SP
- inside an SP
- inside a compound block
*/
class Query_fragment
{
uint m_pos;
uint m_length;
void set(size_t pos, size_t length)
{
DBUG_ASSERT(pos < UINT_MAX32);
DBUG_ASSERT(length < UINT_MAX32);
m_pos= (uint) pos;
m_length= (uint) length;
}
public:
Query_fragment(THD *thd, sp_head *sphead, const char *start, const char *end);
uint pos() const { return m_pos; }
uint length() const { return m_length; }
};
/**
This is used for items in the query that needs to be rewritten
before binlogging
@@ -2100,7 +2126,6 @@ public:
Field_enumerator() {} /* Remove gcc warning */
};
class sp_head;
class Item_string;

View File

@@ -4432,21 +4432,6 @@ static int init_common_variables()
SYSVAR_AUTOSIZE(threadpool_size, my_getncpus());
#endif
/* Fix host_cache_size. */
if (IS_SYSVAR_AUTOSIZE(&host_cache_size))
{
if (max_connections <= 628 - 128)
SYSVAR_AUTOSIZE(host_cache_size, 128 + max_connections);
else if (max_connections <= ((ulong)(2000 - 628)) * 20 + 500)
SYSVAR_AUTOSIZE(host_cache_size, 628 + ((max_connections - 500) / 20));
else
SYSVAR_AUTOSIZE(host_cache_size, 2000);
}
/* Fix back_log (back_log == 0 added for MySQL compatibility) */
if (back_log == 0 || IS_SYSVAR_AUTOSIZE(&back_log))
SYSVAR_AUTOSIZE(back_log, MY_MIN(900, (50 + max_connections / 5)));
/* connections and databases needs lots of files */
{
uint files, wanted_files, max_open_files;
@@ -4471,7 +4456,7 @@ static int init_common_variables()
if (files < wanted_files)
{
if (!open_files_limit)
if (!open_files_limit || IS_SYSVAR_AUTOSIZE(&open_files_limit))
{
/*
If we have requested too much file handles than we bring
@@ -4500,6 +4485,36 @@ static int init_common_variables()
}
SYSVAR_AUTOSIZE(open_files_limit, files);
}
/*
Max_connections is now set.
Now we can fix other variables depending on this variable.
*/
/* Fix host_cache_size */
if (IS_SYSVAR_AUTOSIZE(&host_cache_size))
{
/*
The default value is 128.
The autoset value is 128, plus 1 for a value of max_connections
up to 500, plus 1 for every increment of 20 over 500 in the
max_connections value, capped at 2000.
*/
uint size= (HOST_CACHE_SIZE + MY_MIN(max_connections, 500) +
MY_MAX(((long) max_connections)-500,0)/20);
SYSVAR_AUTOSIZE(host_cache_size, size);
}
/* Fix back_log (back_log == 0 added for MySQL compatibility) */
if (back_log == 0 || IS_SYSVAR_AUTOSIZE(&back_log))
{
/*
The default value is 150.
The autoset value is 50 + max_connections / 5 capped at 900
*/
SYSVAR_AUTOSIZE(back_log, MY_MIN(900, (50 + max_connections / 5)));
}
unireg_init(opt_specialflag); /* Set up extern variabels */
if (!(my_default_lc_messages=
my_locale_by_name(lc_messages)))

View File

@@ -545,6 +545,7 @@ sp_head::sp_head(const Sp_handler *sph)
Database_qualified_name(&null_clex_str, &null_clex_str),
m_handler(sph),
m_flags(0),
m_tmp_query(NULL),
m_explicit_name(false),
/*
FIXME: the only use case when name is NULL is events, and it should
@@ -1426,7 +1427,7 @@ bool sp_head::check_execute_access(THD *thd) const
/**
Create rcontext using the routine security.
Create rcontext optionally using the routine security.
This is important for sql_mode=ORACLE to make sure that the invoker has
access to the tables mentioned in the %TYPE references.
@@ -1438,25 +1439,52 @@ bool sp_head::check_execute_access(THD *thd) const
@retval NULL - error (access denided or EOM)
@retval !NULL - success (the invoker has rights to all %TYPE tables)
*/
sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value)
sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value,
Row_definition_list *defs,
bool switch_security_ctx)
{
bool has_column_type_refs= m_flags & HAS_COLUMN_TYPE_REFS;
if (!(m_flags & HAS_COLUMN_TYPE_REFS))
return sp_rcontext::create(thd, m_pcont, ret_value, *defs);
sp_rcontext *res= NULL;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *save_security_ctx;
if (has_column_type_refs &&
if (switch_security_ctx &&
set_routine_security_ctx(thd, this, &save_security_ctx))
return NULL;
#endif
sp_rcontext *res= sp_rcontext::create(thd, m_pcont, ret_value,
has_column_type_refs);
if (!defs->resolve_type_refs(thd))
res= sp_rcontext::create(thd, m_pcont, ret_value, *defs);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (has_column_type_refs)
if (switch_security_ctx)
m_security_ctx.restore_security_context(thd, save_security_ctx);
#endif
return res;
}
sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value,
List<Item> *args)
{
DBUG_ASSERT(args);
Row_definition_list defs;
m_pcont->retrieve_field_definitions(&defs);
if (defs.adjust_formal_params_to_actual_params(thd, args))
return NULL;
return rcontext_create(thd, ret_value, &defs, true);
}
sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value,
Item **args, uint arg_count)
{
Row_definition_list defs;
m_pcont->retrieve_field_definitions(&defs);
if (defs.adjust_formal_params_to_actual_params(thd, args, arg_count))
return NULL;
return rcontext_create(thd, ret_value, &defs, true);
}
/**
Execute trigger stored program.
@@ -1554,8 +1582,9 @@ sp_head::execute_trigger(THD *thd,
init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(0));
thd->set_n_backup_active_arena(&call_arena, &backup_arena);
if (!(nctx= sp_rcontext::create(thd, m_pcont, NULL,
m_flags & HAS_COLUMN_TYPE_REFS)))
Row_definition_list defs;
m_pcont->retrieve_field_definitions(&defs);
if (!(nctx= rcontext_create(thd, NULL, &defs, false)))
{
err_status= TRUE;
goto err_with_cleanup;
@@ -1669,7 +1698,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(0));
thd->set_n_backup_active_arena(&call_arena, &backup_arena);
if (!(nctx= rcontext_create(thd, return_value_fld)))
if (!(nctx= rcontext_create(thd, return_value_fld, argp, argcount)))
{
thd->restore_active_arena(&call_arena, &backup_arena);
err_status= TRUE;
@@ -1883,7 +1912,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (! octx)
{
/* Create a temporary old context. */
if (!(octx= rcontext_create(thd, NULL)))
if (!(octx= rcontext_create(thd, NULL, args)))
{
DBUG_PRINT("error", ("Could not create octx"));
DBUG_RETURN(TRUE);
@@ -1896,7 +1925,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
thd->spcont->callers_arena= thd;
}
if (!(nctx= rcontext_create(thd, NULL)))
if (!(nctx= rcontext_create(thd, NULL, args)))
{
delete nctx; /* Delete nctx if it was init() that failed. */
thd->spcont= save_spcont;

View File

@@ -214,8 +214,12 @@ public:
m_sp_cache_version= version_arg;
}
sp_rcontext *rcontext_create(THD *thd, Field *retval);
sp_rcontext *rcontext_create(THD *thd, Field *retval, List<Item> *args);
sp_rcontext *rcontext_create(THD *thd, Field *retval,
Item **args, uint arg_count);
sp_rcontext *rcontext_create(THD *thd, Field *retval,
Row_definition_list *list,
bool switch_security_ctx);
private:
/**
Version of the stored routine cache at the moment when the

View File

@@ -63,20 +63,15 @@ sp_rcontext::~sp_rcontext()
sp_rcontext *sp_rcontext::create(THD *thd,
const sp_pcontext *root_parsing_ctx,
Field *return_value_fld,
bool resolve_type_refs)
Row_definition_list &field_def_lst)
{
sp_rcontext *ctx= new (thd->mem_root) sp_rcontext(root_parsing_ctx,
return_value_fld,
thd->in_sub_stmt);
if (!ctx)
return NULL;
List<Spvar_definition> field_def_lst;
ctx->m_root_parsing_ctx->retrieve_field_definitions(&field_def_lst);
if (ctx->alloc_arrays(thd) ||
(resolve_type_refs && ctx->resolve_type_refs(thd, field_def_lst)) ||
ctx->init_var_table(thd, field_def_lst) ||
ctx->init_var_items(thd, field_def_lst))
{
@@ -88,6 +83,39 @@ sp_rcontext *sp_rcontext::create(THD *thd,
}
bool Row_definition_list::
adjust_formal_params_to_actual_params(THD *thd, List<Item> *args)
{
List_iterator<Spvar_definition> it(*this);
List_iterator<Item> it_args(*args);
DBUG_ASSERT(elements >= args->elements );
Spvar_definition *def;
Item *arg;
while ((def= it++) && (arg= it_args++))
{
if (def->type_handler()->adjust_spparam_type(def, arg))
return true;
}
return false;
}
bool Row_definition_list::
adjust_formal_params_to_actual_params(THD *thd,
Item **args, uint arg_count)
{
List_iterator<Spvar_definition> it(*this);
DBUG_ASSERT(elements >= arg_count );
Spvar_definition *def;
for (uint i= 0; (def= it++) && (i < arg_count) ; i++)
{
if (def->type_handler()->adjust_spparam_type(def, args[i]))
return true;
}
return false;
}
bool sp_rcontext::alloc_arrays(THD *thd)
{
{
@@ -146,8 +174,7 @@ check_column_grant_for_type_ref(THD *thd, TABLE_LIST *table_list,
/**
This method implementation is very close to fill_schema_table_by_open().
*/
bool sp_rcontext::resolve_type_ref(THD *thd, Column_definition *def,
Qualified_column_ident *ref)
bool Qualified_column_ident::resolve_type_ref(THD *thd, Column_definition *def)
{
Open_tables_backup open_tables_state_backup;
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
@@ -164,18 +191,18 @@ bool sp_rcontext::resolve_type_ref(THD *thd, Column_definition *def,
// Make %TYPE variables see temporary tables that shadow permanent tables
thd->temporary_tables= open_tables_state_backup.temporary_tables;
if ((table_list= lex.select_lex.add_table_to_list(thd, ref, NULL, 0,
if ((table_list= lex.select_lex.add_table_to_list(thd, this, NULL, 0,
TL_READ_NO_INSERT,
MDL_SHARED_READ)) &&
!check_table_access(thd, SELECT_ACL, table_list, TRUE, UINT_MAX, FALSE) &&
!open_tables_only_view_structure(thd, table_list,
thd->mdl_context.has_locks()))
{
if ((src= lex.query_tables->table->find_field_by_name(&ref->m_column)))
if ((src= lex.query_tables->table->find_field_by_name(&m_column)))
{
if (!(rc= check_column_grant_for_type_ref(thd, table_list,
ref->m_column.str,
ref->m_column.length)))
m_column.str,
m_column.length)))
{
*def= Column_definition(thd, src, NULL/*No defaults,no constraints*/);
def->flags&= (uint) ~NOT_NULL_FLAG;
@@ -183,7 +210,7 @@ bool sp_rcontext::resolve_type_ref(THD *thd, Column_definition *def,
}
}
else
my_error(ER_BAD_FIELD_ERROR, MYF(0), ref->m_column.str, ref->table.str);
my_error(ER_BAD_FIELD_ERROR, MYF(0), m_column.str, table.str);
}
lex.unit.cleanup();
@@ -200,9 +227,8 @@ bool sp_rcontext::resolve_type_ref(THD *thd, Column_definition *def,
rec t1%ROWTYPE;
It opens the table "t1" and copies its structure to %ROWTYPE variable.
*/
bool sp_rcontext::resolve_table_rowtype_ref(THD *thd,
Row_definition_list &defs,
Table_ident *ref)
bool Table_ident::resolve_table_rowtype_ref(THD *thd,
Row_definition_list &defs)
{
Open_tables_backup open_tables_state_backup;
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
@@ -223,7 +249,7 @@ bool sp_rcontext::resolve_table_rowtype_ref(THD *thd,
// Make %ROWTYPE variables see temporary tables that shadow permanent tables
thd->temporary_tables= open_tables_state_backup.temporary_tables;
if ((table_list= lex.select_lex.add_table_to_list(thd, ref, NULL, 0,
if ((table_list= lex.select_lex.add_table_to_list(thd, this, NULL, 0,
TL_READ_NO_INSERT,
MDL_SHARED_READ)) &&
!check_table_access(thd, SELECT_ACL, table_list, TRUE, UINT_MAX, FALSE) &&
@@ -261,14 +287,14 @@ bool sp_rcontext::resolve_table_rowtype_ref(THD *thd,
}
bool sp_rcontext::resolve_type_refs(THD *thd, List<Spvar_definition> &defs)
bool Row_definition_list::resolve_type_refs(THD *thd)
{
List_iterator<Spvar_definition> it(defs);
List_iterator<Spvar_definition> it(*this);
Spvar_definition *def;
while ((def= it++))
{
if (def->is_column_type_ref() &&
resolve_type_ref(thd, def, def->column_type_ref()))
def->column_type_ref()->resolve_type_ref(thd, def))
return true;
}
return false;
@@ -300,7 +326,7 @@ bool sp_rcontext::init_var_items(THD *thd,
Row_definition_list defs;
Item_field_row *item= new (thd->mem_root) Item_field_row(thd, field);
if (!(m_var_items[idx]= item) ||
resolve_table_rowtype_ref(thd, defs, def->table_rowtype_ref()) ||
def->table_rowtype_ref()->resolve_table_rowtype_ref(thd, defs) ||
item->row_create_items(thd, &defs))
return true;
}

View File

@@ -71,7 +71,7 @@ public:
static sp_rcontext *create(THD *thd,
const sp_pcontext *root_parsing_ctx,
Field *return_value_fld,
bool resolve_type_refs);
Row_definition_list &defs);
~sp_rcontext();
@@ -337,12 +337,6 @@ private:
/// @retval true on error.
bool init_var_table(THD *thd, List<Spvar_definition> &defs);
bool resolve_type_refs(THD *, List<Spvar_definition> &defs);
bool resolve_type_ref(THD *thd, Column_definition *def,
Qualified_column_ident *ref);
bool resolve_table_rowtype_ref(THD *thd, Row_definition_list &defs,
Table_ident *ref);
/// Create and initialize an Item-adapter (Item_field) for each SP-var field.
///
/// param thd Thread handle.

View File

@@ -1081,6 +1081,10 @@ public:
{
return static_cast<uint32>(query_string.length());
}
inline char *query_end() const
{
return query_string.str() + query_string.length();
}
CHARSET_INFO *query_charset() const { return query_string.charset(); }
void set_query_inner(const CSET_STRING &string_arg)
{
@@ -5587,6 +5591,7 @@ public:
{
db= *db_name;
}
bool resolve_table_rowtype_ref(THD *thd, Row_definition_list &defs);
};
@@ -5610,6 +5615,7 @@ public:
:Table_ident(thd, db, table, false),
m_column(*column)
{ }
bool resolve_type_ref(THD *thd, Column_definition *def);
};

View File

@@ -6261,15 +6261,17 @@ Item *LEX::create_and_link_Item_trigger_field(THD *thd,
Item_param *LEX::add_placeholder(THD *thd, const LEX_CSTRING *name,
uint pos_in_query, uint len_in_query)
const char *start, const char *end)
{
if (!parsing_options.allows_variable)
{
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
return NULL;
}
Query_fragment pos(thd, sphead, start, end);
Item_param *item= new (thd->mem_root) Item_param(thd, name,
pos_in_query, len_in_query);
pos.pos(), pos.length());
if (!item || param_list.push_back(item, thd->mem_root))
{
my_error(ER_OUT_OF_RESOURCES, MYF(0));
@@ -6279,12 +6281,6 @@ Item_param *LEX::add_placeholder(THD *thd, const LEX_CSTRING *name,
}
const char *LEX::substatement_query(THD *thd) const
{
return sphead ? sphead->m_tmp_query : thd->query();
}
bool LEX::add_signal_statement(THD *thd, const sp_condition_value *v)
{
Yacc_state *state= &thd->m_parser_state->m_yacc;
@@ -6338,8 +6334,8 @@ Item_splocal *LEX::create_item_spvar_row_field(THD *thd,
const LEX_CSTRING *a,
const LEX_CSTRING *b,
sp_variable *spv,
uint pos_in_q,
uint length_in_q)
const char *start,
const char *end)
{
if (!parsing_options.allows_variable)
{
@@ -6347,6 +6343,7 @@ Item_splocal *LEX::create_item_spvar_row_field(THD *thd,
return NULL;
}
Query_fragment pos(thd, sphead, start, end);
Item_splocal *item;
if (spv->field_def.is_table_rowtype_ref() ||
spv->field_def.is_cursor_rowtype_ref())
@@ -6354,7 +6351,7 @@ Item_splocal *LEX::create_item_spvar_row_field(THD *thd,
if (!(item= new (thd->mem_root)
Item_splocal_row_field_by_name(thd, a, b, spv->offset,
MYSQL_TYPE_NULL,
pos_in_q, length_in_q)))
pos.pos(), pos.length())))
return NULL;
}
else
@@ -6368,7 +6365,7 @@ Item_splocal *LEX::create_item_spvar_row_field(THD *thd,
Item_splocal_row_field(thd, a, b,
spv->offset, row_field_offset,
def->real_field_type(),
pos_in_q, length_in_q)))
pos.pos(), pos.length())))
return NULL;
}
#ifdef DBUG_ASSERT_EXISTS
@@ -6463,14 +6460,14 @@ Item *LEX::create_item_func_setval(THD *thd, Table_ident *table_ident,
Item *LEX::create_item_ident(THD *thd,
const LEX_CSTRING *a,
const LEX_CSTRING *b,
uint pos_in_q, uint length_in_q)
const char *start, const char *end)
{
sp_variable *spv;
if (spcont && (spv= spcont->find_variable(a, false)) &&
(spv->field_def.is_row() ||
spv->field_def.is_table_rowtype_ref() ||
spv->field_def.is_cursor_rowtype_ref()))
return create_item_spvar_row_field(thd, a, b, spv, pos_in_q, length_in_q);
return create_item_spvar_row_field(thd, a, b, spv, start, end);
if ((thd->variables.sql_mode & MODE_ORACLE) && b->length == 7)
{
@@ -6524,7 +6521,7 @@ Item *LEX::create_item_ident(THD *thd,
Item *LEX::create_item_limit(THD *thd,
const LEX_CSTRING *a,
uint pos_in_q, uint length_in_q)
const char *start, const char *end)
{
sp_variable *spv;
if (!spcont || !(spv= spcont->find_variable(a, false)))
@@ -6533,10 +6530,11 @@ Item *LEX::create_item_limit(THD *thd,
return NULL;
}
Query_fragment pos(thd, sphead, start, end);
Item_splocal *item;
if (!(item= new (thd->mem_root) Item_splocal(thd, a,
spv->offset, spv->sql_type(),
pos_in_q, length_in_q)))
pos.pos(), pos.length())))
return NULL;
#ifdef DBUG_ASSERT_EXISTS
item->m_sp= sphead;
@@ -6556,7 +6554,7 @@ Item *LEX::create_item_limit(THD *thd,
Item *LEX::create_item_limit(THD *thd,
const LEX_CSTRING *a,
const LEX_CSTRING *b,
uint pos_in_q, uint length_in_q)
const char *start, const char *end)
{
sp_variable *spv;
if (!spcont || !(spv= spcont->find_variable(a, false)))
@@ -6567,8 +6565,7 @@ Item *LEX::create_item_limit(THD *thd,
// Qualified %TYPE variables are not possible
DBUG_ASSERT(!spv->field_def.column_type_ref());
Item_splocal *item;
if (!(item= create_item_spvar_row_field(thd, a, b, spv,
pos_in_q, length_in_q)))
if (!(item= create_item_spvar_row_field(thd, a, b, spv, start, end)))
return NULL;
if (item->type() != Item::INT_ITEM)
{
@@ -6634,11 +6631,12 @@ Item *LEX::create_item_ident_nosp(THD *thd, LEX_CSTRING *name)
Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name,
uint start_in_q,
uint length_in_q)
const char *start,
const char *end)
{
sp_variable *spv;
DBUG_ASSERT(spcont);
DBUG_ASSERT(sphead);
if ((spv= spcont->find_variable(name, false)))
{
/* We're compiling a stored procedure and found a variable */
@@ -6648,17 +6646,18 @@ Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name,
return NULL;
}
Query_fragment pos(thd, sphead, start, end);
Item_splocal *splocal= spv->field_def.is_column_type_ref() ?
new (thd->mem_root) Item_splocal_with_delayed_data_type(thd, name,
spv->offset,
start_in_q,
length_in_q) :
pos.pos(),
pos.length()) :
spv->field_def.is_row() || spv->field_def.is_table_rowtype_ref() ?
new (thd->mem_root) Item_splocal_row(thd, name, spv->offset,
start_in_q, length_in_q) :
pos.pos(), pos.length()) :
new (thd->mem_root) Item_splocal(thd, name,
spv->offset, spv->sql_type(),
start_in_q, length_in_q);
pos.pos(), pos.length());
if (splocal == NULL)
return NULL;
#ifdef DBUG_ASSERT_EXISTS
@@ -6679,16 +6678,6 @@ Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name,
}
Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name,
const char *start_in_q,
const char *end_in_q)
{
DBUG_ASSERT(sphead);
return create_item_ident_sp(thd, name, start_in_q - sphead->m_tmp_query,
end_in_q - start_in_q);
}
/**
Generate instructions for:
SET x.y= expr;

View File

@@ -2975,8 +2975,6 @@ public:
void start(THD *thd);
const char *substatement_query(THD *thd) const;
inline bool is_ps_or_view_context_analysis()
{
return (context_analysis_only &
@@ -3207,22 +3205,16 @@ public:
bool sp_open_cursor(THD *thd, const LEX_CSTRING *name,
List<sp_assignment_lex> *parameters);
Item_splocal *create_item_for_sp_var(LEX_CSTRING *name, sp_variable *spvar,
const char *start_in_q,
const char *end_in_q);
const char *start, const char *end);
Item *create_item_ident_nosp(THD *thd, LEX_CSTRING *name);
Item *create_item_ident_sp(THD *thd, LEX_CSTRING *name,
uint start_in_q,
uint length_in_q);
Item *create_item_ident_sp(THD *thd, LEX_CSTRING *name,
const char *start_in_q,
const char *end_in_q);
const char *start, const char *end);
Item *create_item_ident(THD *thd, LEX_CSTRING *name,
const char *start_in_q,
const char *end_in_q)
const char *start, const char *end)
{
return sphead ?
create_item_ident_sp(thd, name, start_in_q, end_in_q) :
create_item_ident_sp(thd, name, start, end) :
create_item_ident_nosp(thd, name);
}
@@ -3249,15 +3241,15 @@ public:
@param field - the ROW variable field name
@param spvar - the variable that was previously found by name
using "var_name".
@pos_in_q - position in the query (for binary log)
@length_in_q - length in the query (for binary log)
@param start - position in the query (for binary log)
@param end - end in the query (for binary log)
*/
Item_splocal *create_item_spvar_row_field(THD *thd,
const LEX_CSTRING *var,
const LEX_CSTRING *field,
sp_variable *spvar,
uint pos_in_q,
uint length_in_q);
const char *start,
const char *end);
/*
Create an item from its qualified name.
Depending on context, it can be either a ROW variable field,
@@ -3267,15 +3259,15 @@ public:
@param thd - THD, for mem_root
@param a - the first name
@param b - the second name
@param pos_in_q - position in the query (for binary log)
@param length_in_q - length in the query (for binary log)
@param start - position in the query (for binary log)
@param end - end in the query (for binary log)
@retval - NULL on error, or a pointer to a new Item.
*/
Item *create_item_ident(THD *thd,
const LEX_CSTRING *a,
const LEX_CSTRING *b,
uint pos_in_q, uint length_in_q);
const char *start,
const char *end);
/*
Create an item from its qualified name.
Depending on context, it can be a table field, a table field reference,
@@ -3314,23 +3306,24 @@ public:
Create an item for a name in LIMIT clause: LIMIT var
@param THD - THD, for mem_root
@param var_name - the variable name
@param pos_in_q - position in the query (for binary log)
@param length_in_q - length in the query (for binary log)
@param start - position in the query (for binary log)
@param end - end in the query (for binary log)
@retval - a new Item corresponding to the SP variable,
or NULL on error
(non in SP, unknown variable, wrong data type).
*/
Item *create_item_limit(THD *thd,
const LEX_CSTRING *var_name,
uint pos_in_q, uint length_in_q);
const char *start,
const char *end);
/*
Create an item for a qualified name in LIMIT clause: LIMIT var.field
@param THD - THD, for mem_root
@param var_name - the variable name
@param field_name - the variable field name
@param pos_in_q - position in the query (for binary log)
@param length_in_q - length in the query (for binary log)
@param start - start in the query (for binary log)
@param end - end in the query (for binary log)
@retval - a new Item corresponding to the SP variable,
or NULL on error
(non in SP, unknown variable, unknown ROW field,
@@ -3339,7 +3332,8 @@ public:
Item *create_item_limit(THD *thd,
const LEX_CSTRING *var_name,
const LEX_CSTRING *field_name,
uint pos_in_q, uint length_in_q);
const char *start,
const char *end);
Item *make_item_func_replace(THD *thd, Item *org, Item *find, Item *replace);
@@ -3422,16 +3416,7 @@ public:
bool sp_push_goto_label(THD *thd, const LEX_CSTRING *label_name);
Item_param *add_placeholder(THD *thd, const LEX_CSTRING *name,
uint pos_in_query, uint len_in_query);
Item_param *add_placeholder(THD *thd, const LEX_CSTRING *name,
const char *start, const char *end)
{
size_t pos= start - substatement_query(thd);
size_t len= end - start;
DBUG_ASSERT(pos < UINT_MAX32);
DBUG_ASSERT(len < UINT_MAX32);
return add_placeholder(thd, name, (uint) pos, (uint) len);
}
const char *start, const char *end);
/* Integer range FOR LOOP methods */
sp_variable *sp_add_for_loop_variable(THD *thd, const LEX_CSTRING *name,

View File

@@ -2423,6 +2423,31 @@ Field *Type_handler_set::make_table_field(const LEX_CSTRING *name,
/*************************************************************************/
/*
If length is not specified for a varchar parameter, set length to the
maximum length of the actual argument. Goals are:
- avoid to allocate too much unused memory for m_var_table
- allow length check inside the callee rather than during copy of
returned values in output variables.
- allow varchar parameter size greater than 4000
Default length has been stored in "decimal" member during parse.
*/
bool Type_handler_varchar::adjust_spparam_type(Spvar_definition *def,
Item *from) const
{
if (def->decimals)
{
uint def_max_char_length= MAX_FIELD_VARCHARLENGTH / def->charset->mbmaxlen;
uint arg_max_length= from->max_char_length();
set_if_smaller(arg_max_length, def_max_char_length);
def->length= arg_max_length > 0 ? arg_max_length : def->decimals;
def->create_length_to_internal_length_string();
}
return false;
}
/*************************************************************************/
uint32 Type_handler_decimal_result::max_display_length(const Item *item) const
{
return item->max_length;

View File

@@ -65,6 +65,7 @@ class in_vector;
class Type_handler_hybrid_field_type;
class Sort_param;
class Arg_comparator;
class Spvar_definition;
struct st_value;
class Protocol;
class handler;
@@ -688,6 +689,10 @@ public:
type_handler_adjusted_to_max_octet_length(uint max_octet_length,
CHARSET_INFO *cs) const
{ return this; }
virtual bool adjust_spparam_type(Spvar_definition *def, Item *from) const
{
return false;
}
virtual ~Type_handler() {}
/**
Determines MariaDB traditional data types that always present
@@ -2523,6 +2528,7 @@ public:
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
bool adjust_spparam_type(Spvar_definition *def, Item *from) const;
};

View File

@@ -11938,9 +11938,7 @@ limit_option:
LEX *lex= thd->lex;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
if (!($$= lex->create_item_limit(thd, &$1,
$1.m_pos -
lex->substatement_query(thd),
lip->get_tok_end() - $1.m_pos)))
$1.m_pos, lip->get_tok_end())))
MYSQL_YYABORT;
}
| ident_with_tok_start '.' ident
@@ -11948,9 +11946,7 @@ limit_option:
LEX *lex= thd->lex;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
if (!($$= lex->create_item_limit(thd, &$1, &$3,
$1.m_pos -
lex->substatement_query(thd),
lip->get_ptr() - $1.m_pos)))
$1.m_pos, lip->get_ptr())))
MYSQL_YYABORT;
}
| param_marker
@@ -14257,9 +14253,7 @@ simple_ident:
{
LEX *lex= thd->lex;
if (!($$= lex->create_item_ident(thd, &$1, &$3,
$1.m_pos -
lex->substatement_query(thd),
YYLIP->get_tok_end() - $1.m_pos)))
$1.m_pos, YYLIP->get_tok_end())))
MYSQL_YYABORT;
}
;

View File

@@ -1055,8 +1055,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <const_simple_string>
field_length opt_field_length opt_field_length_default_1
opt_field_length_default_sp_param_varchar
opt_field_length_default_sp_param_char
%type <string>
text_string hex_or_bin_String opt_gconcat_separator
@@ -1220,6 +1218,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <Lex_cast_type> cast_type cast_type_numeric cast_type_temporal
%type <Lex_length_and_dec> precision opt_precision float_options
opt_field_length_default_sp_param_varchar
opt_field_length_default_sp_param_char
%type <symbol> keyword keyword_sp
keyword_directly_assignable
@@ -6550,9 +6550,11 @@ opt_field_length_default_1:
/*
In sql_mode=ORACLE, a VARCHAR with no length is used
in SP parameters and return values and it's translated to VARCHAR(4000),
where 4000 is the maximum possible size for VARCHAR.
In sql_mode=ORACLE, real size of VARCHAR and CHAR with no length
in SP parameters is fixed at runtime with the length of real args.
Let's translate VARCHAR to VARCHAR(4000) for return value.
Since Oracle 9, maximum size for VARCHAR in PL/SQL is 32767.
In MariaDB the limit for VARCHAR is 65535 bytes.
We could translate VARCHAR with no length to VARCHAR(65535), but
@@ -6563,17 +6565,14 @@ opt_field_length_default_1:
the maximum possible length in characters in case of mbmaxlen=4
(e.g. utf32, utf16, utf8mb4). However, we'll have character sets with
mbmaxlen=5 soon (e.g. gb18030).
Let's translate VARCHAR to VARCHAR(4000), which covert all possible Oracle
values.
*/
opt_field_length_default_sp_param_varchar:
/* empty */ { $$= (char*) "4000"; }
| field_length { $$= $1; }
/* empty */ { $$.set("4000", "4000"); }
| field_length { $$.set($1, NULL); }
opt_field_length_default_sp_param_char:
/* empty */ { $$= (char*) "2000"; }
| field_length { $$= $1; }
/* empty */ { $$.set("2000", "2000"); }
| field_length { $$.set($1, NULL); }
opt_precision:
/* empty */ { $$.set(0, 0); }
@@ -11984,9 +11983,7 @@ limit_option:
LEX *lex= thd->lex;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
if (!($$= lex->create_item_limit(thd, &$1,
$1.m_pos -
lex->substatement_query(thd),
lip->get_tok_end() - $1.m_pos)))
$1.m_pos, lip->get_tok_end())))
MYSQL_YYABORT;
}
| ident_with_tok_start '.' ident
@@ -11994,9 +11991,7 @@ limit_option:
LEX *lex= thd->lex;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
if (!($$= lex->create_item_limit(thd, &$1, &$3,
$1.m_pos -
lex->substatement_query(thd),
lip->get_ptr() - $1.m_pos)))
$1.m_pos, lip->get_ptr())))
MYSQL_YYABORT;
}
| param_marker
@@ -14322,9 +14317,7 @@ simple_ident:
{
LEX *lex= thd->lex;
if (!($$= lex->create_item_ident(thd, &$1, &$3,
$1.m_pos -
lex->substatement_query(thd),
YYLIP->get_tok_end() - $1.m_pos)))
$1.m_pos, YYLIP->get_tok_end())))
MYSQL_YYABORT;
}
;

View File

@@ -2360,10 +2360,10 @@ export sys_var *Sys_old_passwords_ptr= &Sys_old_passwords; // for sql_acl.cc
static Sys_var_ulong Sys_open_files_limit(
"open_files_limit",
"If this is not 0, then mysqld will use this value to reserve file "
"descriptors to use with setrlimit(). If this value is 0 then mysqld "
"will reserve max_connections*5 or max_connections + table_cache*2 "
"(whichever is larger) number of file descriptors",
READ_ONLY GLOBAL_VAR(open_files_limit), CMD_LINE(REQUIRED_ARG),
"descriptors to use with setrlimit(). If this value is 0 or autoset "
"then mysqld will reserve max_connections*5 or max_connections + "
"table_cache*2 (whichever is larger) number of file descriptors",
AUTO_SET READ_ONLY GLOBAL_VAR(open_files_limit), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, OS_FILE_LIMIT), DEFAULT(0), BLOCK_SIZE(1));
/// @todo change to enum

View File

@@ -1569,7 +1569,7 @@ page_dir_balance_slot(
/* The last directory slot cannot be balanced with the upper
neighbor, as there is none. */
if (UNIV_UNLIKELY(slot_no == page_dir_get_n_slots(page) - 1)) {
if (UNIV_UNLIKELY(slot_no + 1 == page_dir_get_n_slots(page))) {
return;
}

View File

@@ -49,14 +49,7 @@ my_bool srv_sync_debug;
/** The global mutex which protects debug info lists of all rw-locks.
To modify the debug info list of an rw-lock, this mutex has to be
acquired in addition to the mutex protecting the lock. */
static ib_mutex_t rw_lock_debug_mutex;
/** If deadlock detection does not get immediately the mutex,
it may wait for this event */
static os_event_t rw_lock_debug_event;
/** This is set to true, if there may be waiters for the event */
static bool rw_lock_debug_waiters;
static SysMutex rw_lock_debug_mutex;
/** The latch held by a thread */
struct Latched {
@@ -1240,13 +1233,7 @@ void
LatchDebug::init()
UNIV_NOTHROW
{
ut_a(rw_lock_debug_event == NULL);
mutex_create(LATCH_ID_RW_LOCK_DEBUG, &rw_lock_debug_mutex);
rw_lock_debug_event = os_event_create("rw_lock_debug_event");
rw_lock_debug_waiters = FALSE;
}
/** Shutdown the latch debug checking
@@ -1257,12 +1244,6 @@ void
LatchDebug::shutdown()
UNIV_NOTHROW
{
ut_a(rw_lock_debug_event != NULL);
os_event_destroy(rw_lock_debug_event);
rw_lock_debug_event = NULL;
mutex_free(&rw_lock_debug_mutex);
ut_a(s_initialized);
@@ -1282,22 +1263,7 @@ mutex. */
void
rw_lock_debug_mutex_enter()
{
for (;;) {
if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) {
return;
}
os_event_reset(rw_lock_debug_event);
rw_lock_debug_waiters = TRUE;
if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) {
return;
}
os_event_wait(rw_lock_debug_event);
}
mutex_enter(&rw_lock_debug_mutex);
}
/** Releases the debug mutex. */
@@ -1305,11 +1271,6 @@ void
rw_lock_debug_mutex_exit()
{
mutex_exit(&rw_lock_debug_mutex);
if (rw_lock_debug_waiters) {
rw_lock_debug_waiters = FALSE;
os_event_set(rw_lock_debug_event);
}
}
#endif /* UNIV_DEBUG */

View File

@@ -57,7 +57,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
char kfilename[FN_REFLEN], klinkname[FN_REFLEN], *klinkname_ptr;
char dfilename[FN_REFLEN], dlinkname[FN_REFLEN], *dlinkname_ptr= 0;
ulong pack_reclength;
ulonglong tot_length,max_rows, tmp;
ulonglong tot_length,max_rows, tmp, tot_length_part;
enum en_fieldtype type;
enum data_file_type org_datafile_type= datafile_type;
MARIA_SHARE share;
@@ -664,10 +664,10 @@ int maria_create(const char *name, enum data_file_type datafile_type,
if (tot_length == ULLONG_MAX)
continue;
ulonglong tot_length_part= (max_rows/(ulong) (((uint) maria_block_size -
MAX_KEYPAGE_HEADER_SIZE -
KEYPAGE_CHECKSUM_SIZE)/
(length*2)));
tot_length_part= (max_rows/(ulong) (((uint) maria_block_size -
MAX_KEYPAGE_HEADER_SIZE -
KEYPAGE_CHECKSUM_SIZE)/
(length*2)));
if (tot_length_part >= (ULLONG_MAX / maria_block_size +
ULLONG_MAX % maria_block_size))
tot_length= ULLONG_MAX;

View File

@@ -918,6 +918,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
if (internal_table)
set_if_smaller(share->base.max_data_file_length,
max_data_file_length);
if (share->now_transactional)
{
/* Setup initial state that is visible for all */
MARIA_STATE_HISTORY_CLOSED *history;