summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r--sql/item_strfunc.cc372
1 files changed, 146 insertions, 226 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 68d49b90475..0635556be40 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -43,7 +43,6 @@
#include "set_var.h"
#include "sql_base.h"
#include "sql_time.h"
-#include "sql_acl.h" // SUPER_ACL
#include "des_key_file.h" // st_des_keyschedule, st_des_keyblock
#include "password.h" // my_make_scrambled_password,
// my_make_scrambled_password_323
@@ -58,25 +57,21 @@ C_MODE_END
size_t username_char_length= 80;
+/*
+ Calculate max length of string from length argument to LEFT and RIGHT
+*/
-class Repeat_count
+static uint32 max_length_for_string(Item *item)
{
- ulonglong m_count;
-public:
- Repeat_count(Item *item)
- :m_count(0)
+ ulonglong length= item->val_int();
+ /* Note that if value is NULL, val_int() returned 0 */
+ if (length > (ulonglong) INT_MAX32)
{
- Longlong_hybrid nr= item->to_longlong_hybrid();
- if (!item->null_value && !nr.neg())
- {
- // Assume that the maximum length of a String is < INT_MAX32
- m_count= (ulonglong) nr.value();
- if (m_count > (ulonglong) INT_MAX32)
- m_count= (ulonglong) INT_MAX32;
- }
+ /* Limit string length to maxium string length in MariaDB (2G) */
+ length= item->unsigned_flag ? (ulonglong) INT_MAX32 : 0;
}
- ulonglong count() const { return m_count; }
-};
+ return (uint32) length;
+}
/*
@@ -844,7 +839,7 @@ String *Item_func_des_decrypt::val_str(String *str)
{
uint key_number=(uint) (*res)[0] & 127;
// Check if automatic key and that we have privilege to uncompress using it
- if (!(current_thd->security_ctx->master_access & SUPER_ACL) ||
+ if (!(current_thd->security_ctx->master_access & PRIV_DES_DECRYPT_ONE_ARG) ||
key_number > 9)
goto error;
@@ -1105,7 +1100,7 @@ String *Item_func_reverse::val_str(String *str)
end= res->end();
tmp= (char *) str->end();
#ifdef USE_MB
- if (use_mb(res->charset()))
+ if (res->use_mb())
{
uint32 l;
while (ptr < end)
@@ -1178,7 +1173,7 @@ String *Item_func_replace::val_str_internal(String *str,
res->set_charset(collation.collation);
#ifdef USE_MB
- binary_cmp = ((res->charset()->state & MY_CS_BINSORT) || !use_mb(res->charset()));
+ binary_cmp = ((res->charset()->state & MY_CS_BINSORT) || !res->use_mb());
#endif
if (res2->length() == 0)
@@ -1293,10 +1288,10 @@ null:
bool Item_func_replace::fix_length_and_dec()
{
ulonglong char_length= (ulonglong) args[0]->max_char_length();
- int diff=(int) (args[2]->max_char_length() - args[1]->max_char_length());
- if (diff > 0 && args[1]->max_char_length())
+ int diff=(int) (args[2]->max_char_length() - 1);
+ if (diff > 0)
{ // Calculate of maxreplaces
- ulonglong max_substrs= char_length / args[1]->max_char_length();
+ ulonglong max_substrs= char_length;
char_length+= max_substrs * (uint) diff;
}
@@ -1308,13 +1303,6 @@ bool Item_func_replace::fix_length_and_dec()
/*********************************************************************/
-bool Item_func_regexp_replace::fix_fields(THD *thd, Item **ref)
-{
- re.set_recursion_limit(thd);
- return Item_str_func::fix_fields(thd, ref);
-}
-
-
bool Item_func_regexp_replace::fix_length_and_dec()
{
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3))
@@ -1344,8 +1332,8 @@ bool Item_func_regexp_replace::append_replacement(String *str,
my_wc_t wc;
int cnv, n;
- if ((cnv= cs->cset->mb_wc(cs, &wc, (const uchar *) beg,
- (const uchar *) end)) < 1)
+ if ((cnv= cs->mb_wc(&wc, (const uchar *) beg,
+ (const uchar *) end)) < 1)
break; /* End of line */
beg+= cnv;
@@ -1356,8 +1344,8 @@ bool Item_func_regexp_replace::append_replacement(String *str,
continue;
}
- if ((cnv= cs->cset->mb_wc(cs, &wc, (const uchar *) beg,
- (const uchar *) end)) < 1)
+ if ((cnv= cs->mb_wc(&wc, (const uchar *) beg,
+ (const uchar *) end)) < 1)
break; /* End of line */
beg+= cnv;
@@ -1366,7 +1354,7 @@ bool Item_func_regexp_replace::append_replacement(String *str,
if (n < re.nsubpatterns())
{
/* A valid sub-pattern reference found */
- int pbeg= re.subpattern_start(n), plength= re.subpattern_end(n) - pbeg;
+ size_t pbeg= re.subpattern_start(n), plength= re.subpattern_end(n) - pbeg;
if (str->append(source->str + pbeg, plength, cs))
return true;
}
@@ -1395,7 +1383,7 @@ String *Item_func_regexp_replace::val_str(String *str)
String *source= args[0]->val_str(&tmp0);
String *replace= args[2]->val_str(&tmp2);
LEX_CSTRING src, rpl;
- int startoffset= 0;
+ size_t startoffset= 0;
if ((null_value= (args[0]->null_value || args[2]->null_value ||
re.recompile(args[1]))))
@@ -1405,8 +1393,8 @@ String *Item_func_regexp_replace::val_str(String *str)
!(replace= re.convert_if_needed(replace, &re.replace_converter)))
goto err;
- src= source->lex_cstring();
- rpl= replace->lex_cstring();
+ source->get_value(&src);
+ replace->get_value(&rpl);
str->length(0);
str->set_charset(collation.collation);
@@ -1424,7 +1412,8 @@ String *Item_func_regexp_replace::val_str(String *str)
Append the rest of the source string
starting from startoffset until the end of the source.
*/
- if (str->append(src.str + startoffset, src.length - startoffset, re.library_charset()))
+ if (str->append(src.str + startoffset, src.length - startoffset,
+ re.library_charset()))
goto err;
return str;
}
@@ -1433,7 +1422,8 @@ String *Item_func_regexp_replace::val_str(String *str)
Append prefix, the part before the matching pattern.
starting from startoffset until the next match
*/
- if (str->append(src.str + startoffset, re.subpattern_start(0) - startoffset, re.library_charset()))
+ if (str->append(src.str + startoffset,
+ re.subpattern_start(0) - startoffset, re.library_charset()))
goto err;
// Append replacement
@@ -1451,13 +1441,6 @@ err:
}
-bool Item_func_regexp_substr::fix_fields(THD *thd, Item **ref)
-{
- re.set_recursion_limit(thd);
- return Item_str_func::fix_fields(thd, ref);
-}
-
-
bool Item_func_regexp_substr::fix_length_and_dec()
{
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2))
@@ -1492,8 +1475,7 @@ String *Item_func_regexp_substr::val_str(String *str)
return str;
if (str->append(source->ptr() + re.subpattern_start(0),
- re.subpattern_end(0) - re.subpattern_start(0),
- re.library_charset()))
+ re.subpattern_length(0), re.library_charset()))
goto err;
return str;
@@ -1659,8 +1641,8 @@ void Item_str_func::left_right_max_length()
uint32 char_length= args[0]->max_char_length();
if (args[1]->const_item() && !args[1]->is_expensive())
{
- Repeat_count tmp(args[1]);
- set_if_smaller(char_length, (uint) tmp.count());
+ uint32 length= max_length_for_string(args[1]);
+ set_if_smaller(char_length, length);
}
fix_char_length(char_length);
}
@@ -1821,7 +1803,7 @@ String *Item_func_substr_index::val_str(String *str)
res->set_charset(collation.collation);
#ifdef USE_MB
- if (use_mb(res->charset()))
+ if (res->use_mb())
{
const char *ptr= res->ptr();
const char *strend= ptr+res->length();
@@ -2026,7 +2008,7 @@ String *Item_func_rtrim::val_str(String *str)
{
char chr=(*remove_str)[0];
#ifdef USE_MB
- if (use_mb(collation.collation))
+ if (collation.collation->use_mb())
{
while (ptr < end)
{
@@ -2043,7 +2025,7 @@ String *Item_func_rtrim::val_str(String *str)
{
const char *r_ptr=remove_str->ptr();
#ifdef USE_MB
- if (use_mb(collation.collation))
+ if (collation.collation->use_mb())
{
loop:
while (ptr + remove_length < end)
@@ -2102,7 +2084,7 @@ String *Item_func_trim::val_str(String *str)
while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
ptr+=remove_length;
#ifdef USE_MB
- if (use_mb(collation.collation))
+ if (collation.collation->use_mb())
{
char *p=ptr;
uint32 l;
@@ -2575,10 +2557,10 @@ String *Item_func_soundex::val_str(String *str)
for ( ; ; ) /* Skip pre-space */
{
- if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
+ if ((rc= cs->mb_wc(&wc, (uchar*) from, (uchar*) end)) <= 0)
return make_empty_result(str); /* EOL or invalid byte sequence */
-
- if (rc == 1 && cs->ctype)
+
+ if (rc == 1 && cs->m_ctype)
{
/* Single byte letter found */
if (my_isalpha(cs, *from))
@@ -2597,7 +2579,7 @@ String *Item_func_soundex::val_str(String *str)
/* Multibyte letter found */
wc= soundex_toupper(wc);
last_ch= get_scode(wc); // Code of the first letter
- if ((rc= cs->cset->wc_mb(cs, wc, (uchar*) to, (uchar*) to_end)) <= 0)
+ if ((rc= cs->wc_mb(wc, (uchar*) to, (uchar*) to_end)) <= 0)
{
/* Extra safety - should not really happen */
DBUG_ASSERT(false);
@@ -2615,10 +2597,10 @@ String *Item_func_soundex::val_str(String *str)
*/
for (nchars= 1 ; ; )
{
- if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
+ if ((rc= cs->mb_wc(&wc, (uchar*) from, (uchar*) end)) <= 0)
break; /* EOL or invalid byte sequence */
- if (rc == 1 && cs->ctype)
+ if (rc == 1 && cs->m_ctype)
{
if (!my_isalpha(cs, *from++))
continue;
@@ -2634,8 +2616,7 @@ String *Item_func_soundex::val_str(String *str)
if ((ch != '0') && (ch != last_ch)) // if not skipped or double
{
// letter, copy to output
- if ((rc= cs->cset->wc_mb(cs, (my_wc_t) ch,
- (uchar*) to, (uchar*) to_end)) <= 0)
+ if ((rc= cs->wc_mb((my_wc_t) ch, (uchar*) to, (uchar*) to_end)) <= 0)
{
// Extra safety - should not really happen
DBUG_ASSERT(false);
@@ -2651,7 +2632,7 @@ String *Item_func_soundex::val_str(String *str)
if (nchars < 4)
{
uint nbytes= (4 - nchars) * cs->mbminlen;
- cs->cset->fill(cs, to, nbytes, '0');
+ cs->fill(to, nbytes, '0');
to+= nbytes;
}
@@ -3053,8 +3034,8 @@ bool Item_func_repeat::fix_length_and_dec()
DBUG_ASSERT(collation.collation != NULL);
if (args[1]->const_item() && !args[1]->is_expensive())
{
- Repeat_count tmp(args[1]);
- ulonglong char_length= (ulonglong) args[0]->max_char_length() * tmp.count();
+ uint32 length= max_length_for_string(args[1]);
+ ulonglong char_length= (ulonglong) args[0]->max_char_length() * length;
fix_char_length_ulonglong(char_length);
return false;
}
@@ -3127,7 +3108,7 @@ bool Item_func_space::fix_length_and_dec()
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
if (args[0]->const_item() && !args[0]->is_expensive())
{
- fix_char_length_ulonglong(Repeat_count(args[0]).count());
+ fix_char_length_ulonglong(max_length_for_string(args[0]));
return false;
}
max_length= MAX_BLOB_WIDTH;
@@ -3173,7 +3154,7 @@ String *Item_func_space::val_str(String *str)
goto err;
str->length(tot_length);
str->set_charset(cs);
- cs->cset->fill(cs, (char*) str->ptr(), tot_length, ' ');
+ cs->fill((char*) str->ptr(), tot_length, ' ');
return str;
err:
@@ -3252,7 +3233,7 @@ bool Item_func_pad::fix_length_and_dec()
DBUG_ASSERT(collation.collation->mbmaxlen > 0);
if (args[1]->const_item() && !args[1]->is_expensive())
{
- fix_char_length_ulonglong(Repeat_count(args[1]).count());
+ fix_char_length_ulonglong(max_length_for_string(args[1]));
return false;
}
max_length= MAX_BLOB_WIDTH;
@@ -3514,11 +3495,11 @@ String *Item_func_conv::val_str(String *str)
else
{
if (from_base < 0)
- dec= my_strntoll(res->charset(), res->ptr(), res->length(),
- -from_base, &endptr, &err);
+ dec= res->charset()->strntoll(res->ptr(), res->length(),
+ -from_base, &endptr, &err);
else
- dec= (longlong) my_strntoull(res->charset(), res->ptr(), res->length(),
- from_base, &endptr, &err);
+ dec= (longlong) res->charset()->strntoull(res->ptr(), res->length(),
+ from_base, &endptr, &err);
}
if (!(ptr= longlong2str(dec, ans, to_base)) ||
@@ -3573,10 +3554,12 @@ String *Item_func_set_collation::val_str(String *str)
bool Item_func_set_collation::fix_length_and_dec()
{
- if (!my_charset_same(args[0]->collation.collation, m_set_collation))
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return true;
+ if (!my_charset_same(collation.collation, m_set_collation))
{
my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
- m_set_collation->name, args[0]->collation.collation->csname);
+ m_set_collation->name, collation.collation->csname);
return TRUE;
}
collation.set(m_set_collation, DERIVATION_EXPLICIT,
@@ -3640,7 +3623,7 @@ bool Item_func_weight_string::fix_length_and_dec()
size_t char_length;
char_length= ((cs->state & MY_CS_STRNXFRM_BAD_NWEIGHTS) || !nweights) ?
args[0]->max_char_length() : nweights * cs->levels_for_order;
- max_length= (uint32)cs->coll->strnxfrmlen(cs, char_length * cs->mbmaxlen);
+ max_length= (uint32) cs->strnxfrmlen(char_length * cs->mbmaxlen);
}
maybe_null= 1;
return FALSE;
@@ -3691,7 +3674,7 @@ String *Item_func_weight_string::val_str(String *str)
char_length= (flags & MY_STRXFRM_PAD_WITH_SPACE) ?
res->numchars() : (res->length() / cs->mbminlen);
}
- tmp_length= cs->coll->strnxfrmlen(cs, char_length * cs->mbmaxlen);
+ tmp_length= cs->strnxfrmlen(char_length * cs->mbmaxlen);
}
{
@@ -3710,11 +3693,10 @@ String *Item_func_weight_string::val_str(String *str)
if (str->alloc(tmp_length))
goto nl;
- frm_length= cs->coll->strnxfrm(cs,
- (uchar *) str->ptr(), tmp_length,
- nweights ? nweights : (uint)tmp_length,
- (const uchar *) res->ptr(), res->length(),
- flags);
+ frm_length= cs->strnxfrm((char*) str->ptr(), tmp_length,
+ nweights ? nweights : (uint) tmp_length,
+ res->ptr(), res->length(),
+ flags);
DBUG_ASSERT(frm_length <= tmp_length);
str->length(frm_length);
@@ -3833,10 +3815,10 @@ String *Item_func_like_range::val_str(String *str)
goto err;
null_value=0;
- if (cs->coll->like_range(cs, res->ptr(), res->length(),
- '\\', '_', '%', (size_t)nbytes,
- (char*) min_str.ptr(), (char*) max_str.ptr(),
- &min_len, &max_len))
+ if (cs->like_range(res->ptr(), res->length(),
+ '\\', '_', '%', (size_t)nbytes,
+ (char*) min_str.ptr(), (char*) max_str.ptr(),
+ &min_len, &max_len))
goto err;
min_str.set_charset(collation.collation);
@@ -4105,7 +4087,7 @@ String *Item_func_quote::val_str(String *str)
to_end= (uchar*) to + new_length;
/* Put leading quote */
- if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
+ if ((mblen= cs->wc_mb('\'', (uchar *) to, to_end)) <= 0)
goto toolong;
to+= mblen;
@@ -4113,7 +4095,7 @@ String *Item_func_quote::val_str(String *str)
{
my_wc_t wc;
bool escape;
- if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) start, (uchar*) end)) <= 0)
+ if ((mblen= cs->mb_wc(&wc, (uchar*) start, (uchar*) end)) <= 0)
goto null;
start+= mblen;
switch (wc) {
@@ -4125,17 +4107,17 @@ String *Item_func_quote::val_str(String *str)
}
if (escape)
{
- if ((mblen= cs->cset->wc_mb(cs, '\\', (uchar*) to, to_end)) <= 0)
+ if ((mblen= cs->wc_mb('\\', (uchar*) to, to_end)) <= 0)
goto toolong;
to+= mblen;
}
- if ((mblen= cs->cset->wc_mb(cs, wc, (uchar*) to, to_end)) <= 0)
+ if ((mblen= cs->wc_mb(wc, (uchar*) to, to_end)) <= 0)
goto toolong;
to+= mblen;
}
/* Put trailing quote */
- if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
+ if ((mblen= cs->wc_mb('\'', (uchar *) to, to_end)) <= 0)
goto toolong;
to+= mblen;
new_length= (uint)(to - str->ptr());
@@ -4448,24 +4430,7 @@ bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg)
uint valpos= i * 2 + 1;
DYNAMIC_COLUMN_TYPE type= defs[i].type;
if (type == DYN_COL_NULL)
- switch (args[valpos]->field_type())
- {
- case MYSQL_TYPE_VARCHAR:
- case MYSQL_TYPE_ENUM:
- case MYSQL_TYPE_SET:
- case MYSQL_TYPE_TINY_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- case MYSQL_TYPE_LONG_BLOB:
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_VAR_STRING:
- case MYSQL_TYPE_STRING:
- case MYSQL_TYPE_GEOMETRY:
- type= DYN_COL_STRING;
- break;
- default:
- break;
- }
-
+ type= args[valpos]->type_handler()->dyncol_type(args[valpos]);
if (type == DYN_COL_STRING &&
args[valpos]->type() == Item::FUNC_ITEM &&
((Item_func *)args[valpos])->functype() == DYNCOL_FUNC)
@@ -4482,63 +4447,7 @@ bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg)
uint valpos= i * 2 + 1;
DYNAMIC_COLUMN_TYPE type= defs[i].type;
if (type == DYN_COL_NULL) // auto detect
- {
- /*
- We don't have a default here to ensure we get a warning if
- one adds a new not handled MYSQL_TYPE_...
- */
- switch (args[valpos]->field_type()) {
- case MYSQL_TYPE_DECIMAL:
- case MYSQL_TYPE_NEWDECIMAL:
- type= DYN_COL_DECIMAL;
- break;
- case MYSQL_TYPE_TINY:
- case MYSQL_TYPE_SHORT:
- case MYSQL_TYPE_LONG:
- case MYSQL_TYPE_LONGLONG:
- case MYSQL_TYPE_INT24:
- case MYSQL_TYPE_YEAR:
- case MYSQL_TYPE_BIT:
- type= args[valpos]->unsigned_flag ? DYN_COL_UINT : DYN_COL_INT;
- break;
- case MYSQL_TYPE_FLOAT:
- case MYSQL_TYPE_DOUBLE:
- type= DYN_COL_DOUBLE;
- break;
- case MYSQL_TYPE_NULL:
- type= DYN_COL_NULL;
- break;
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_TIMESTAMP2:
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_DATETIME2:
- type= DYN_COL_DATETIME;
- break;
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_NEWDATE:
- type= DYN_COL_DATE;
- break;
- case MYSQL_TYPE_TIME:
- case MYSQL_TYPE_TIME2:
- type= DYN_COL_TIME;
- break;
- case MYSQL_TYPE_VARCHAR:
- case MYSQL_TYPE_ENUM:
- case MYSQL_TYPE_SET:
- case MYSQL_TYPE_TINY_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- case MYSQL_TYPE_LONG_BLOB:
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_VAR_STRING:
- case MYSQL_TYPE_STRING:
- case MYSQL_TYPE_GEOMETRY:
- type= DYN_COL_STRING;
- break;
- case MYSQL_TYPE_VARCHAR_COMPRESSED:
- case MYSQL_TYPE_BLOB_COMPRESSED:
- DBUG_ASSERT(0);
- }
- }
+ type= args[valpos]->type_handler()->dyncol_type(args[valpos]);
if (type == DYN_COL_STRING &&
args[valpos]->type() == Item::FUNC_ITEM &&
((Item_func *)args[valpos])->functype() == DYNCOL_FUNC)
@@ -5116,8 +5025,8 @@ double Item_dyncol_get::val_real()
{
int error;
char *end;
- double res= my_strntod(val.x.string.charset, (char*) val.x.string.value.str,
- val.x.string.value.length, &end, &error);
+ double res= val.x.string.charset->strntod((char*) val.x.string.value.str,
+ val.x.string.value.length, &end, &error);
if (end != (char*) val.x.string.value.str + val.x.string.value.length ||
error)
@@ -5361,28 +5270,33 @@ String *Item_temptable_rowid::val_str(String *str)
str_value.set((char*)(table->file->ref), max_length, &my_charset_bin);
return &str_value;
}
+
#ifdef WITH_WSREP
#include "wsrep_mysqld.h"
+/* Format is %d-%d-%llu */
+#define WSREP_MAX_WSREP_SERVER_GTID_STR_LEN 10+1+10+1+20
String *Item_func_wsrep_last_written_gtid::val_str_ascii(String *str)
{
- wsrep::gtid gtid= current_thd->wsrep_cs().last_written_gtid();
- if (gtid_str.alloc(wsrep::gtid_c_str_len()))
+ if (gtid_str.alloc(WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1))
{
- my_error(ER_OUTOFMEMORY, wsrep::gtid_c_str_len());
- null_value= true;
- return NULL;
+ my_error(ER_OUTOFMEMORY, WSREP_MAX_WSREP_SERVER_GTID_STR_LEN);
+ null_value= TRUE;
+ return 0;
}
- ssize_t gtid_len= gtid_print_to_c_str(gtid, (char*) gtid_str.ptr(),
- wsrep::gtid_c_str_len());
+ ssize_t gtid_len= my_snprintf((char*)gtid_str.ptr(),
+ WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1,
+ "%u-%u-%llu", wsrep_gtid_server.domain_id,
+ wsrep_gtid_server.server_id,
+ current_thd->wsrep_last_written_gtid_seqno);
if (gtid_len < 0)
{
my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), func_name(),
- "wsrep_gtid_print failed");
- null_value= true;
- return NULL;
+ "wsrep_gtid_print failed");
+ null_value= TRUE;
+ return 0;
}
gtid_str.length(gtid_len);
return &gtid_str;
@@ -5390,27 +5304,23 @@ String *Item_func_wsrep_last_written_gtid::val_str_ascii(String *str)
String *Item_func_wsrep_last_seen_gtid::val_str_ascii(String *str)
{
- wsrep::gtid gtid= wsrep::gtid::undefined();
- if (Wsrep_server_state::instance().is_provider_loaded())
- {
- /* TODO: Should call Wsrep_server_state.instance().last_committed_gtid()
- instead. */
- gtid= Wsrep_server_state::instance().provider().last_committed_gtid();
- }
- if (gtid_str.alloc(wsrep::gtid_c_str_len()))
+ if (gtid_str.alloc(WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1))
{
- my_error(ER_OUTOFMEMORY, wsrep::gtid_c_str_len());
- null_value= true;
- return NULL;
+ my_error(ER_OUTOFMEMORY, WSREP_MAX_WSREP_SERVER_GTID_STR_LEN);
+ null_value= TRUE;
+ return 0;
}
- ssize_t gtid_len= wsrep::gtid_print_to_c_str(gtid, (char*) gtid_str.ptr(),
- wsrep::gtid_c_str_len());
+ ssize_t gtid_len= my_snprintf((char*)gtid_str.ptr(),
+ WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1,
+ "%u-%u-%llu", wsrep_gtid_server.domain_id,
+ wsrep_gtid_server.server_id,
+ wsrep_gtid_server.seqno());
if (gtid_len < 0)
{
my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), func_name(),
"wsrep_gtid_print failed");
- null_value= true;
- return NULL;
+ null_value= TRUE;
+ return 0;
}
gtid_str.length(gtid_len);
return &gtid_str;
@@ -5418,49 +5328,59 @@ String *Item_func_wsrep_last_seen_gtid::val_str_ascii(String *str)
longlong Item_func_wsrep_sync_wait_upto::val_int()
{
- int timeout= -1;
- String* gtid_str= args[0]->val_str(&value);
- if (gtid_str == NULL)
- {
- my_error(ER_WRONG_ARGUMENTS, MYF(0), func_name());
- return 0LL;
- }
-
- if (arg_count == 2)
- {
- timeout= args[1]->val_int();
- }
+ String *gtid_str __attribute__((unused)) = args[0]->val_str(&value);
+ null_value=0;
+ uint timeout;
+ rpl_gtid *gtid_list;
+ uint32 count;
+ int wait_gtid_ret= 0;
+ int ret= 1;
- wsrep_gtid_t gtid;
- int gtid_len= wsrep_gtid_scan(gtid_str->ptr(), gtid_str->length(), &gtid);
- if (gtid_len < 0)
+ if (args[0]->null_value)
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), func_name());
- return 0LL;
+ null_value= TRUE;
+ return 0;
}
- if (gtid.seqno == WSREP_SEQNO_UNDEFINED &&
- wsrep_uuid_compare(&gtid.uuid, &WSREP_UUID_UNDEFINED) == 0)
+ if (arg_count==2 && !args[1]->null_value)
+ timeout= (uint)(args[1]->val_real());
+ else
+ timeout= (uint)-1;
+
+ if (!(gtid_list= gtid_parse_string_to_list(gtid_str->ptr(), gtid_str->length(),
+ &count)))
{
- return 1LL;
+ my_error(ER_INCORRECT_GTID_STATE, MYF(0), func_name());
+ null_value= TRUE;
+ return 0;
}
-
- enum wsrep::provider::status status=
- wsrep_sync_wait_upto(current_thd, &gtid, timeout);
-
- if (status)
+ if (count == 1)
{
- int err;
- switch (status) {
- case wsrep::provider::error_transaction_missing:
- err= ER_WRONG_ARGUMENTS;
- break;
- default:
- err= ER_LOCK_WAIT_TIMEOUT;
+ if (wsrep_check_gtid_seqno(gtid_list[0].domain_id, gtid_list[0].server_id,
+ gtid_list[0].seq_no))
+ {
+ wait_gtid_ret= wsrep_gtid_server.wait_gtid_upto(gtid_list[0].seq_no, timeout);
+ if ((wait_gtid_ret == ETIMEDOUT) || (wait_gtid_ret == ETIME))
+ {
+ my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), func_name());
+ ret= 0;
+ }
+ else if (wait_gtid_ret == ENOMEM)
+ {
+ my_error(ER_OUTOFMEMORY, MYF(0), func_name());
+ ret= 0;
+ }
}
- my_error(err, MYF(0), func_name());
- return 0LL;
}
- return 1LL;
+ else
+ {
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), func_name());
+ null_value= TRUE;
+ ret= 0;
+ }
+ my_free(gtid_list);
+ return ret;
}
+
#endif /* WITH_WSREP */