diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_create.cc | 4 | ||||
-rw-r--r-- | sql/item_create.h | 1 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 53 | ||||
-rw-r--r-- | sql/item_strfunc.h | 9 | ||||
-rw-r--r-- | sql/lex.h | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 3 |
6 files changed, 71 insertions, 0 deletions
diff --git a/sql/item_create.cc b/sql/item_create.cc index e75c7049a74..f28e3248c61 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -440,3 +440,7 @@ Item *create_func_is_free_lock(Item* a) return new Item_func_is_free_lock(a); } +Item *create_func_quote(Item* a) +{ + return new Item_func_quote(a); +} diff --git a/sql/item_create.h b/sql/item_create.h index 730a1510988..28fbd61df8f 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -93,3 +93,4 @@ Item *create_func_weekday(Item* a); Item *create_load_file(Item* a); Item *create_wait_for_master_pos(Item* a, Item* b); Item *create_func_is_free_lock(Item* a); +Item *create_func_quote(Item* a); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index f074629e376..30968faa9b8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2070,3 +2070,56 @@ String* Item_func_inet_ntoa::val_str(String* str) str->length(str->length()-1); // Remove last '.'; return str; } + +String *Item_func_quote::val_str(String *str) +{ + String *arg= args[0]->val_str(str); + char *strptr, *argptr, *end, *arglast; + uint delta= 2; /* for beginning and ending ' signs */ + + for (argptr= (char*) arg->ptr(), end= argptr + arg->length(); argptr < end; + argptr++) + { + switch (*argptr) { + case '\'': + case '\\': + case 0: + case '\032': + delta++; + } + } + if (str->alloc(arg->length() + delta)) + { + null_value= 1; + return 0; + } + strptr= (char*) str->ptr() + arg->length() + delta - 1; + *strptr= '\''; + for (end= (char*) arg->ptr(), arglast= end + arg->length(), + argptr= arglast - 1; argptr >= end; argptr--) + { + switch (*argptr) { + case '\'': + case '\\': + case 0: + case '\032': + strptr-= arglast - argptr; + memmove(strptr, argptr, arglast - argptr); + arglast= argptr; + *--strptr= '\\'; + } + } + if (arglast != end) + { + strptr-= arglast - end; + memmove(strptr, end, arglast - end); + } + *--strptr= '\''; + str->length(arg->length() + delta); + return str; +} + +void Item_func_quote::fix_length_and_dec() +{ + max_length= args[0]->max_length * 2 + 2; +} diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 835b1c7547d..b64c7c2587c 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -535,3 +535,12 @@ public: const char *func_name() const { return "inet_ntoa"; } void fix_length_and_dec() { decimals = 0; max_length=3*8+7; } }; + +class Item_func_quote :public Item_str_func +{ +public: + Item_func_quote(Item *a) :Item_str_func(a) {} + const char *func_name() const { return "quote"; } + String *val_str(String *); + void fix_length_and_dec(); +}; diff --git a/sql/lex.h b/sql/lex.h index c1d647c47aa..0a1505581cd 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -475,6 +475,7 @@ static SYMBOL sql_functions[] = { { "POW", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, { "POWER", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, { "QUARTER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quarter)}, + { "QUOTE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quote)}, { "RADIANS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)}, { "RAND", SYM(RAND),0,0}, { "RELEASE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 97a4c5308ba..547481a2c8b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -283,6 +283,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token PROCESS %token PROCESSLIST_SYM %token QUERY_SYM +%token QUOTE %token RAID_0_SYM %token RAID_STRIPED_SYM %token RAID_TYPE @@ -1815,6 +1816,8 @@ simple_expr: } | POSITION_SYM '(' no_in_expr IN_SYM expr ')' { $$ = new Item_func_locate($5,$3); } + | QUOTE '(' expr ')' + { $$= new Item_func_quote($3); } | RAND '(' expr ')' { $$= new Item_func_rand($3); current_thd->safe_to_cache_query=0;} | RAND '(' ')' |