Commit 454b8106 authored by Yuchen Pei's avatar Yuchen Pei

MDEV-34659 Bound check in spider cast function query construction

During spider query construction of certain cast functions, it
locates the last occurrence of a keyword in the output of the
Item::print() function and append from there to the constructed query
so far. For example, consider the following query

SELECT * FROM t2 ORDER BY CAST(c AS INET6);

It constructs the following query and executes it at the data
node (assuming the data node table is called t0).

select cast(t0.`c` as inet6) ``,t0.`c` `c` from `test`.`t1` t0 order by ``

When the construction has completed the initial part

select cast(t0.`c`

It then attempts to construct the " as inet6" part. To that end, it
calls print() on the Item_typecast_fbt corresponding to the cast item,
and obtains

cast(`test`.`t2`.`c` as inet6)

It then looks for " as ", and places cursor there for appending:

cast(`test`.`t2`.`c` as inet6)
                    ^

In this patch, if the search fails, i.e. there's no " as ...", we
make sure that the cursor is not placed before the beginning of the
string (out of bound).

We also relax the search from " as char" to " as " in the case of
CHAR_TYPECAST_FUNC, since there is more than one Item type with this
func type. For example, "AS INET6" is an Item_typecast_fbt which has
this func type.
parent 03807c84
INSTALL SONAME 'ha_spider';
CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS (
HOST 'localhost',
DATABASE 'auto_test_local',
USER 'root',
PASSWORD '',
SOCKET '$MASTER_1_MYSOCK'
);
SET spider_internal_sql_log_off= 0;
SET spider_same_server_link= on;
SET sql_mode='';
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (HOST "127.0.0.1", DATABASE "test", USER "root", PORT 19000);
CREATE TABLE t1 (c INT) ENGINE=MyISAM;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",SRV "srv",TABLE "t1"';
insert into t2 values (456), (123);
SELECT * FROM t2 ORDER BY CAST(c AS char(60));
c
123
456
SELECT * FROM t2 ORDER BY CAST(c AS INET6);
c
456
123
DROP TABLE t1,t2;
DROP FUNCTION spider_flush_table_mon_cache;
DROP FUNCTION spider_copy_tables;
DROP FUNCTION spider_ping_table;
DROP FUNCTION spider_bg_direct_sql;
DROP FUNCTION spider_direct_sql;
UNINSTALL SONAME IF EXISTS 'ha_spider';
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown
DROP TABLE IF EXISTS mysql.spider_xa;
DROP TABLE IF EXISTS mysql.spider_xa_member;
DROP TABLE IF EXISTS mysql.spider_xa_failed_log;
DROP TABLE IF EXISTS mysql.spider_tables;
DROP TABLE IF EXISTS mysql.spider_link_mon_servers;
DROP TABLE IF EXISTS mysql.spider_link_failed_log;
DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery;
DROP TABLE IF EXISTS mysql.spider_table_sts;
DROP TABLE IF EXISTS mysql.spider_table_crd;
DROP SERVER IF EXISTS s_1;
DROP SERVER IF EXISTS s_2_1;
DROP SERVER IF EXISTS s_2_2;
DROP SERVER IF EXISTS s_2_3;
DROP SERVER IF EXISTS s_3_1;
DROP SERVER IF EXISTS s_3_2;
DROP SERVER IF EXISTS s_3_3;
--source ../../include/init_spider.inc
SET spider_same_server_link= on;
SET sql_mode='';
eval CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (HOST "127.0.0.1", DATABASE "test", USER "root", PORT $MASTER_1_MYPORT);
CREATE TABLE t1 (c INT) ENGINE=MyISAM;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",SRV "srv",TABLE "t1"';
insert into t2 values (456), (123);
SELECT * FROM t2 ORDER BY CAST(c AS char(60));
SELECT * FROM t2 ORDER BY CAST(c AS INET6);
# Cleanup
DROP TABLE t1,t2;
--source ../../include/deinit_spider.inc
...@@ -158,8 +158,7 @@ ...@@ -158,8 +158,7 @@
#define SPIDER_SQL_PREV_LEN (sizeof(SPIDER_SQL_PREV_STR) - 1) #define SPIDER_SQL_PREV_LEN (sizeof(SPIDER_SQL_PREV_STR) - 1)
#define SPIDER_SQL_LAST_STR " last " #define SPIDER_SQL_LAST_STR " last "
#define SPIDER_SQL_LAST_LEN (sizeof(SPIDER_SQL_LAST_STR) - 1) #define SPIDER_SQL_LAST_LEN (sizeof(SPIDER_SQL_LAST_STR) - 1)
#define SPIDER_SQL_AS_STR "as " #define SPIDER_SQL_AS_STR " as "
#define SPIDER_SQL_AS_LEN (sizeof(SPIDER_SQL_AS_STR) - 1)
#define SPIDER_SQL_WITH_QUERY_EXPANSION_STR " with query expansion" #define SPIDER_SQL_WITH_QUERY_EXPANSION_STR " with query expansion"
#define SPIDER_SQL_WITH_QUERY_EXPANSION_LEN (sizeof(SPIDER_SQL_WITH_QUERY_EXPANSION_STR) - 1) #define SPIDER_SQL_WITH_QUERY_EXPANSION_LEN (sizeof(SPIDER_SQL_WITH_QUERY_EXPANSION_STR) - 1)
#define SPIDER_SQL_IN_BOOLEAN_MODE_STR " in boolean mode" #define SPIDER_SQL_IN_BOOLEAN_MODE_STR " in boolean mode"
......
...@@ -123,8 +123,6 @@ typedef st_spider_result SPIDER_RESULT; ...@@ -123,8 +123,6 @@ typedef st_spider_result SPIDER_RESULT;
#define SPIDER_SQL_LIKE_LEN (sizeof(SPIDER_SQL_LIKE_STR) - 1) #define SPIDER_SQL_LIKE_LEN (sizeof(SPIDER_SQL_LIKE_STR) - 1)
#define SPIDER_SQL_NOT_LIKE_STR "not like" #define SPIDER_SQL_NOT_LIKE_STR "not like"
#define SPIDER_SQL_NOT_LIKE_LEN (sizeof(SPIDER_SQL_NOT_LIKE_STR) - 1) #define SPIDER_SQL_NOT_LIKE_LEN (sizeof(SPIDER_SQL_NOT_LIKE_STR) - 1)
#define SPIDER_SQL_AS_CHAR_STR " as char"
#define SPIDER_SQL_AS_CHAR_LEN (sizeof(SPIDER_SQL_AS_CHAR_STR) - 1)
#define SPIDER_SQL_CAST_STR "cast(" #define SPIDER_SQL_CAST_STR "cast("
#define SPIDER_SQL_CAST_LEN (sizeof(SPIDER_SQL_CAST_STR) - 1) #define SPIDER_SQL_CAST_LEN (sizeof(SPIDER_SQL_CAST_STR) - 1)
#define SPIDER_SQL_AS_DATETIME_STR " as datetime" #define SPIDER_SQL_AS_DATETIME_STR " as datetime"
......
...@@ -6002,11 +6002,12 @@ int spider_db_mbase_util::print_item_func( ...@@ -6002,11 +6002,12 @@ int spider_db_mbase_util::print_item_func(
tmp_str.mem_calc(); tmp_str.mem_calc();
if (tmp_str.reserve(1)) if (tmp_str.reserve(1))
DBUG_RETURN(HA_ERR_OUT_OF_MEM); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
tmp_ptr = tmp_str.c_ptr_quick(); last_str = tmp_ptr = tmp_str.c_ptr_quick();
DBUG_PRINT("info",("spider tmp_ptr = %s", tmp_ptr)); DBUG_PRINT("info",("spider tmp_ptr = %s", tmp_ptr));
while ((tmp_ptr2 = strstr(tmp_ptr, SPIDER_SQL_AS_BINARY_STR))) while ((tmp_ptr2 = strstr(tmp_ptr, SPIDER_SQL_AS_BINARY_STR)))
tmp_ptr = tmp_ptr2 + 1; tmp_ptr = tmp_ptr2 + 1;
last_str = tmp_ptr - 1; if (tmp_ptr != last_str)
last_str = tmp_ptr - 1;
last_str_length = strlen(last_str) - SPIDER_SQL_CLOSE_PAREN_LEN; last_str_length = strlen(last_str) - SPIDER_SQL_CLOSE_PAREN_LEN;
break; break;
} else if (!strncasecmp("cast_as_signed", func_name, func_name_length)) } else if (!strncasecmp("cast_as_signed", func_name, func_name_length))
...@@ -6127,11 +6128,12 @@ int spider_db_mbase_util::print_item_func( ...@@ -6127,11 +6128,12 @@ int spider_db_mbase_util::print_item_func(
tmp_str.mem_calc(); tmp_str.mem_calc();
if (tmp_str.reserve(1)) if (tmp_str.reserve(1))
DBUG_RETURN(HA_ERR_OUT_OF_MEM); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
tmp_ptr = tmp_str.c_ptr_quick(); last_str = tmp_ptr = tmp_str.c_ptr_quick();
DBUG_PRINT("info",("spider tmp_ptr = %s", tmp_ptr)); DBUG_PRINT("info",("spider tmp_ptr = %s", tmp_ptr));
while ((tmp_ptr2 = strstr(tmp_ptr, SPIDER_SQL_AS_DECIMAL_STR))) while ((tmp_ptr2 = strstr(tmp_ptr, SPIDER_SQL_AS_DECIMAL_STR)))
tmp_ptr = tmp_ptr2 + 1; tmp_ptr = tmp_ptr2 + 1;
last_str = tmp_ptr - 1; if (tmp_ptr != last_str)
last_str = tmp_ptr - 1;
last_str_length = strlen(last_str) - SPIDER_SQL_CLOSE_PAREN_LEN; last_str_length = strlen(last_str) - SPIDER_SQL_CLOSE_PAREN_LEN;
break; break;
} else if (!strncasecmp("cast_as_datetime", func_name, } else if (!strncasecmp("cast_as_datetime", func_name,
...@@ -6264,11 +6266,12 @@ int spider_db_mbase_util::print_item_func( ...@@ -6264,11 +6266,12 @@ int spider_db_mbase_util::print_item_func(
tmp_str.mem_calc(); tmp_str.mem_calc();
if (tmp_str.reserve(1)) if (tmp_str.reserve(1))
DBUG_RETURN(HA_ERR_OUT_OF_MEM); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
tmp_ptr = tmp_str.c_ptr_quick(); last_str = tmp_ptr = tmp_str.c_ptr_quick();
DBUG_PRINT("info",("spider tmp_ptr = %s", tmp_ptr)); DBUG_PRINT("info",("spider tmp_ptr = %s", tmp_ptr));
while ((tmp_ptr2 = strstr(tmp_ptr, SPIDER_SQL_AS_CHAR_STR))) while ((tmp_ptr2 = strstr(tmp_ptr, SPIDER_SQL_AS_STR)))
tmp_ptr = tmp_ptr2 + 1; tmp_ptr = tmp_ptr2 + 1;
last_str = tmp_ptr - 1; if (tmp_ptr != last_str)
last_str = tmp_ptr - 1;
last_str_length = strlen(last_str) - SPIDER_SQL_CLOSE_PAREN_LEN; last_str_length = strlen(last_str) - SPIDER_SQL_CLOSE_PAREN_LEN;
} }
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment