mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge mskold@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/usr/local/home/marty/MySQL/mysql-5.0
This commit is contained in:
@ -87,6 +87,7 @@ hf@deer.mysql.r18.ru
|
||||
hf@genie.(none)
|
||||
holyfoot@mysql.com
|
||||
igor@hundin.mysql.fi
|
||||
igor@igor-inspiron.creware.com
|
||||
igor@linux.local
|
||||
igor@rurik.mysql.com
|
||||
ingo@mysql.com
|
||||
@ -236,6 +237,7 @@ rburnett@bk-internal.mysql.com
|
||||
rburnett@build.mysql.com
|
||||
reggie@bob.(none)
|
||||
reggie@mdk10.(none)
|
||||
reggie@monster.
|
||||
root@home.(none)
|
||||
root@mc04.(none)
|
||||
root@x3.internalnet
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include "handshake.hpp"
|
||||
#include "yassl_int.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "runtime.hpp"
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
@ -74,7 +74,7 @@ extern char *mysql_unix_port;
|
||||
#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG)
|
||||
#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG)
|
||||
#define IS_BLOB(n) ((n) & BLOB_FLAG)
|
||||
#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR)
|
||||
#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR || (t) == FIELD_TYPE_NEWDECIMAL)
|
||||
#define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG)
|
||||
#define INTERNAL_NUM_FIELD(f) (((f)->type <= FIELD_TYPE_INT24 && ((f)->type != FIELD_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == FIELD_TYPE_YEAR)
|
||||
|
||||
|
@ -160,3 +160,20 @@ t1 CREATE TABLE `t1` (
|
||||
`COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default ''
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (EMPNUM INT);
|
||||
INSERT INTO t1 VALUES (0), (2);
|
||||
CREATE TABLE t2 (EMPNUM DECIMAL (4, 2));
|
||||
INSERT INTO t2 VALUES (0.0), (9.0);
|
||||
SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
|
||||
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
|
||||
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
|
||||
CEMPNUM EMPMUM1 EMPNUM2
|
||||
0.00 0 0.00
|
||||
2.00 2 NULL
|
||||
SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
|
||||
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
|
||||
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
|
||||
CEMPNUM EMPMUM1 EMPNUM2
|
||||
0.00 0 0.00
|
||||
2.00 2 NULL
|
||||
DROP TABLE t1,t2;
|
||||
|
@ -110,3 +110,22 @@ explain extended SELECT
|
||||
COALESCE('a' COLLATE latin1_bin,'b');
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Tests for bug #9939: conversion of the arguments for COALESCE and IFNULL
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (EMPNUM INT);
|
||||
INSERT INTO t1 VALUES (0), (2);
|
||||
CREATE TABLE t2 (EMPNUM DECIMAL (4, 2));
|
||||
INSERT INTO t2 VALUES (0.0), (9.0);
|
||||
|
||||
SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
|
||||
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
|
||||
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
|
||||
|
||||
SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
|
||||
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
|
||||
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
@ -44,7 +44,7 @@ int my_access(const char *path, int amode)
|
||||
|
||||
result= GetFileAttributesEx(path, GetFileExInfoStandard, &fileinfo);
|
||||
if (! result ||
|
||||
(fileinfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) && (amode & W_OK))
|
||||
(fileinfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) && (amode & F_OK))
|
||||
{
|
||||
my_errno= errno= EACCES;
|
||||
return -1;
|
||||
|
@ -5963,11 +5963,14 @@ ha_innobase::external_lock(
|
||||
TABLES if AUTOCOMMIT=1. It does not make much sense to acquire
|
||||
an InnoDB table lock if it is released immediately at the end
|
||||
of LOCK TABLES, and InnoDB's table locks in that case cause
|
||||
VERY easily deadlocks. */
|
||||
VERY easily deadlocks. We do not set InnoDB table locks when
|
||||
MySQL sets them at the start of a stored procedure call
|
||||
(MySQL does have thd->in_lock_tables TRUE there). */
|
||||
|
||||
if (prebuilt->select_lock_type != LOCK_NONE) {
|
||||
|
||||
if (thd->in_lock_tables &&
|
||||
thd->lex->sql_command != SQLCOM_CALL &&
|
||||
thd->variables.innodb_table_locks &&
|
||||
(thd->options & OPTION_NOT_AUTOCOMMIT)) {
|
||||
|
||||
@ -6478,11 +6481,21 @@ ha_innobase::store_lock(
|
||||
|
||||
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
|
||||
|
||||
/* Starting from 5.0.7, we weaken also the table locks
|
||||
set at the start of a MySQL stored procedure call, just like
|
||||
we weaken the locks set at the start of an SQL statement.
|
||||
MySQL does set thd->in_lock_tables TRUE there, but in reality
|
||||
we do not need table locks to make the execution of a
|
||||
single transaction stored procedure call deterministic
|
||||
(if it does not use a consistent read). */
|
||||
|
||||
/* If we are not doing a LOCK TABLE or DISCARD/IMPORT
|
||||
TABLESPACE or TRUNCATE TABLE, then allow multiple writers */
|
||||
|
||||
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
|
||||
lock_type <= TL_WRITE) && !thd->in_lock_tables
|
||||
lock_type <= TL_WRITE)
|
||||
&& (!thd->in_lock_tables
|
||||
|| thd->lex->sql_command == SQLCOM_CALL)
|
||||
&& !thd->tablespace_op
|
||||
&& thd->lex->sql_command != SQLCOM_TRUNCATE
|
||||
&& thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
|
||||
@ -6496,7 +6509,10 @@ ha_innobase::store_lock(
|
||||
to t2. Convert the lock to a normal read lock to allow
|
||||
concurrent inserts to t2. */
|
||||
|
||||
if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) {
|
||||
if (lock_type == TL_READ_NO_INSERT
|
||||
&& (!thd->in_lock_tables
|
||||
|| thd->lex->sql_command == SQLCOM_CALL)) {
|
||||
|
||||
lock_type = TL_READ;
|
||||
}
|
||||
|
||||
|
@ -1116,8 +1116,8 @@ Item_func_ifnull::fix_length_and_dec()
|
||||
max_length= (max(args[0]->max_length - args[0]->decimals,
|
||||
args[1]->max_length - args[1]->decimals) +
|
||||
decimals);
|
||||
agg_result_type(&cached_result_type, args, 2);
|
||||
switch (cached_result_type) {
|
||||
agg_result_type(&hybrid_type, args, 2);
|
||||
switch (hybrid_type) {
|
||||
case STRING_RESULT:
|
||||
agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV);
|
||||
break;
|
||||
@ -1155,7 +1155,7 @@ Field *Item_func_ifnull::tmp_table_field(TABLE *table)
|
||||
}
|
||||
|
||||
double
|
||||
Item_func_ifnull::val_real()
|
||||
Item_func_ifnull::real_op()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
double value= args[0]->val_real();
|
||||
@ -1171,7 +1171,7 @@ Item_func_ifnull::val_real()
|
||||
}
|
||||
|
||||
longlong
|
||||
Item_func_ifnull::val_int()
|
||||
Item_func_ifnull::int_op()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
longlong value=args[0]->val_int();
|
||||
@ -1187,7 +1187,7 @@ Item_func_ifnull::val_int()
|
||||
}
|
||||
|
||||
|
||||
my_decimal *Item_func_ifnull::val_decimal(my_decimal *decimal_value)
|
||||
my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
my_decimal *value= args[0]->val_decimal(decimal_value);
|
||||
@ -1204,7 +1204,7 @@ my_decimal *Item_func_ifnull::val_decimal(my_decimal *decimal_value)
|
||||
|
||||
|
||||
String *
|
||||
Item_func_ifnull::val_str(String *str)
|
||||
Item_func_ifnull::str_op(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String *res =args[0]->val_str(str);
|
||||
@ -1685,7 +1685,7 @@ void Item_func_case::print(String *str)
|
||||
Coalesce - return first not NULL argument.
|
||||
*/
|
||||
|
||||
String *Item_func_coalesce::val_str(String *str)
|
||||
String *Item_func_coalesce::str_op(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
null_value=0;
|
||||
@ -1699,7 +1699,7 @@ String *Item_func_coalesce::val_str(String *str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
longlong Item_func_coalesce::val_int()
|
||||
longlong Item_func_coalesce::int_op()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
null_value=0;
|
||||
@ -1713,7 +1713,7 @@ longlong Item_func_coalesce::val_int()
|
||||
return 0;
|
||||
}
|
||||
|
||||
double Item_func_coalesce::val_real()
|
||||
double Item_func_coalesce::real_op()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
null_value=0;
|
||||
@ -1728,7 +1728,7 @@ double Item_func_coalesce::val_real()
|
||||
}
|
||||
|
||||
|
||||
my_decimal *Item_func_coalesce::val_decimal(my_decimal *decimal_value)
|
||||
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
null_value= 0;
|
||||
@ -1745,8 +1745,8 @@ my_decimal *Item_func_coalesce::val_decimal(my_decimal *decimal_value)
|
||||
|
||||
void Item_func_coalesce::fix_length_and_dec()
|
||||
{
|
||||
agg_result_type(&cached_result_type, args, arg_count);
|
||||
switch (cached_result_type) {
|
||||
agg_result_type(&hybrid_type, args, arg_count);
|
||||
switch (hybrid_type) {
|
||||
case STRING_RESULT:
|
||||
count_only_length();
|
||||
decimals= NOT_FIXED_DEC;
|
||||
|
@ -453,23 +453,19 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class Item_func_coalesce :public Item_func
|
||||
class Item_func_coalesce :public Item_func_numhybrid
|
||||
{
|
||||
protected:
|
||||
enum Item_result cached_result_type;
|
||||
Item_func_coalesce(Item *a, Item *b)
|
||||
:Item_func(a, b), cached_result_type(INT_RESULT)
|
||||
{}
|
||||
Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
|
||||
public:
|
||||
Item_func_coalesce(List<Item> &list)
|
||||
:Item_func(list),cached_result_type(INT_RESULT)
|
||||
{}
|
||||
double val_real();
|
||||
longlong val_int();
|
||||
String *val_str(String *);
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
|
||||
double real_op();
|
||||
longlong int_op();
|
||||
String *str_op(String *);
|
||||
my_decimal *decimal_op(my_decimal *);
|
||||
void fix_length_and_dec();
|
||||
enum Item_result result_type () const { return cached_result_type; }
|
||||
void find_num_type() {}
|
||||
enum Item_result result_type () const { return hybrid_type; }
|
||||
const char *func_name() const { return "coalesce"; }
|
||||
table_map not_null_tables() const { return 0; }
|
||||
};
|
||||
@ -482,10 +478,10 @@ protected:
|
||||
bool field_type_defined;
|
||||
public:
|
||||
Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
|
||||
double val_real();
|
||||
longlong val_int();
|
||||
String *val_str(String *str);
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
double real_op();
|
||||
longlong int_op();
|
||||
String *str_op(String *str);
|
||||
my_decimal *decimal_op(my_decimal *);
|
||||
enum_field_types field_type() const;
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "ifnull"; }
|
||||
|
@ -817,6 +817,8 @@ String *Item_func_numhybrid::val_str(String *str)
|
||||
str->set(nr,decimals,&my_charset_bin);
|
||||
break;
|
||||
}
|
||||
case STRING_RESULT:
|
||||
return str_op(&str_value);
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
@ -841,6 +843,14 @@ double Item_func_numhybrid::val_real()
|
||||
return (double)int_op();
|
||||
case REAL_RESULT:
|
||||
return real_op();
|
||||
case STRING_RESULT:
|
||||
{
|
||||
char *end_not_used;
|
||||
int err_not_used;
|
||||
String *res= str_op(&str_value);
|
||||
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
|
||||
&end_not_used, &err_not_used) : 0.0);
|
||||
}
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
@ -865,6 +875,15 @@ longlong Item_func_numhybrid::val_int()
|
||||
return int_op();
|
||||
case REAL_RESULT:
|
||||
return (longlong)real_op();
|
||||
case STRING_RESULT:
|
||||
{
|
||||
char *end_not_used;
|
||||
int err_not_used;
|
||||
String *res= str_op(&str_value);
|
||||
CHARSET_INFO *cs= str_value.charset();
|
||||
return (res ? (*(cs->cset->strtoll10))(cs, res->ptr(), &end_not_used,
|
||||
&err_not_used) : 0);
|
||||
}
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
@ -893,6 +912,12 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
|
||||
break;
|
||||
}
|
||||
case STRING_RESULT:
|
||||
{
|
||||
String *res= str_op(&str_value);
|
||||
str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
|
||||
res->length(), res->charset(), decimal_value);
|
||||
break;
|
||||
}
|
||||
case ROW_RESULT:
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
@ -2325,9 +2350,6 @@ longlong Item_func_field::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
||||
if (args[0]->is_null())
|
||||
return 0;
|
||||
|
||||
if (cmp_type == STRING_RESULT)
|
||||
{
|
||||
String *field;
|
||||
@ -2343,6 +2365,8 @@ longlong Item_func_field::val_int()
|
||||
else if (cmp_type == INT_RESULT)
|
||||
{
|
||||
longlong val= args[0]->val_int();
|
||||
if (args[0]->null_value)
|
||||
return 0;
|
||||
for (uint i=1; i < arg_count ; i++)
|
||||
{
|
||||
if (!args[i]->is_null() && val == args[i]->val_int())
|
||||
@ -2353,6 +2377,8 @@ longlong Item_func_field::val_int()
|
||||
{
|
||||
my_decimal dec_arg_buf, *dec_arg,
|
||||
dec_buf, *dec= args[0]->val_decimal(&dec_buf);
|
||||
if (args[0]->null_value)
|
||||
return 0;
|
||||
for (uint i=1; i < arg_count; i++)
|
||||
{
|
||||
dec_arg= args[i]->val_decimal(&dec_arg_buf);
|
||||
@ -2363,6 +2389,8 @@ longlong Item_func_field::val_int()
|
||||
else
|
||||
{
|
||||
double val= args[0]->val_real();
|
||||
if (args[0]->null_value)
|
||||
return 0;
|
||||
for (uint i=1; i < arg_count ; i++)
|
||||
{
|
||||
if (!args[i]->is_null() && val == args[i]->val_real())
|
||||
|
@ -189,10 +189,13 @@ class Item_func_numhybrid: public Item_func
|
||||
protected:
|
||||
Item_result hybrid_type;
|
||||
public:
|
||||
Item_func_numhybrid(Item *a) :Item_func(a),hybrid_type(REAL_RESULT)
|
||||
Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT)
|
||||
{}
|
||||
Item_func_numhybrid(Item *a,Item *b)
|
||||
:Item_func(a,b),hybrid_type(REAL_RESULT)
|
||||
:Item_func(a,b), hybrid_type(REAL_RESULT)
|
||||
{}
|
||||
Item_func_numhybrid(List<Item> &list)
|
||||
:Item_func(list), hybrid_type(REAL_RESULT)
|
||||
{}
|
||||
|
||||
enum Item_result result_type () const { return hybrid_type; }
|
||||
@ -208,6 +211,7 @@ public:
|
||||
virtual longlong int_op()= 0;
|
||||
virtual double real_op()= 0;
|
||||
virtual my_decimal *decimal_op(my_decimal *)= 0;
|
||||
virtual String *str_op(String *)= 0;
|
||||
bool is_null() { (void) val_real(); return null_value; }
|
||||
};
|
||||
|
||||
@ -220,6 +224,7 @@ public:
|
||||
|
||||
void fix_num_length_and_dec();
|
||||
void find_num_type();
|
||||
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
|
||||
};
|
||||
|
||||
|
||||
@ -231,6 +236,7 @@ class Item_num_op :public Item_func_numhybrid
|
||||
virtual void result_precision()= 0;
|
||||
void print(String *str) { print_op(str); }
|
||||
void find_num_type();
|
||||
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@ template <uint default_width> class Bitmap
|
||||
uchar buffer[(default_width+7)/8];
|
||||
public:
|
||||
Bitmap() { init(); }
|
||||
Bitmap(Bitmap& from) { *this=from; }
|
||||
Bitmap(const Bitmap& from) { *this=from; }
|
||||
explicit Bitmap(uint prefix_to_set) { init(prefix_to_set); }
|
||||
void init() { bitmap_init(&map, buffer, default_width, 0); }
|
||||
void init(uint prefix_to_set) { init(); set_prefix(prefix_to_set); }
|
||||
@ -61,18 +61,17 @@ public:
|
||||
my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
|
||||
char *print(char *buf) const
|
||||
{
|
||||
char *s=buf; int i;
|
||||
for (i=sizeof(buffer)-1; i>=0 ; i--)
|
||||
char *s=buf;
|
||||
const uchar *e=buffer, *b=e+sizeof(buffer)-1;
|
||||
while (!*b && b>e)
|
||||
b--;
|
||||
if ((*s=_dig_vec_upper[*b >> 4]) != '0')
|
||||
s++;
|
||||
*s++=_dig_vec_upper[*b & 15];
|
||||
while (--b>=e)
|
||||
{
|
||||
if ((*s=_dig_vec_upper[buffer[i] >> 4]) != '0')
|
||||
break;
|
||||
if ((*s=_dig_vec_upper[buffer[i] & 15]) != '0')
|
||||
break;
|
||||
}
|
||||
for (s++, i-- ; i>=0 ; i--)
|
||||
{
|
||||
*s++=_dig_vec_upper[buffer[i] >> 4];
|
||||
*s++=_dig_vec_upper[buffer[i] & 15];
|
||||
*s++=_dig_vec_upper[*b >> 4];
|
||||
*s++=_dig_vec_upper[*b & 15];
|
||||
}
|
||||
*s=0;
|
||||
return buf;
|
||||
|
@ -5799,6 +5799,7 @@ make_join_readinfo(JOIN *join, uint options)
|
||||
if (!table->no_keyread)
|
||||
{
|
||||
if (tab->select && tab->select->quick &&
|
||||
tab->select->quick->index != MAX_KEY && //not index_merge
|
||||
table->used_keys.is_set(tab->select->quick->index))
|
||||
{
|
||||
table->key_read=1;
|
||||
|
@ -7455,12 +7455,16 @@ static void test_explain_bug()
|
||||
verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING,
|
||||
"", "", "", NAME_LEN, 0);
|
||||
|
||||
verify_prepare_field(result, 6, "key_len", "",
|
||||
(mysql_get_server_version(mysql) <= 50000 ?
|
||||
MYSQL_TYPE_LONGLONG : MYSQL_TYPE_VAR_STRING),
|
||||
"", "", "",
|
||||
(mysql_get_server_version(mysql) <= 50000 ? 3 : 4096),
|
||||
0);
|
||||
if (mysql_get_server_version(mysql) <= 50000)
|
||||
{
|
||||
verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_LONGLONG, "",
|
||||
"", "", 3, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_VAR_STRING, "",
|
||||
"", "", NAME_LEN*MAX_KEY, 0);
|
||||
}
|
||||
|
||||
verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
|
||||
"", "", "", NAME_LEN*16, 0);
|
||||
|
Reference in New Issue
Block a user