Cleanup during reviews
Removed some optional arguments Fixed portability problem in federated tests
This commit is contained in:
parent
8e54dece31
commit
594ef41b2d
@ -28,6 +28,11 @@
|
|||||||
#include <floatingpoint.h>
|
#include <floatingpoint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following extern declarations are ok as these are interface functions
|
||||||
|
required by the string function
|
||||||
|
*/
|
||||||
|
|
||||||
extern gptr sql_alloc(unsigned size);
|
extern gptr sql_alloc(unsigned size);
|
||||||
extern void sql_element_free(void *ptr);
|
extern void sql_element_free(void *ptr);
|
||||||
|
|
||||||
@ -97,14 +102,7 @@ bool String::set(longlong num, CHARSET_INFO *cs)
|
|||||||
|
|
||||||
if (alloc(l))
|
if (alloc(l))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (cs->cset->snprintf == my_snprintf_8bit)
|
str_length=(uint32) (cs->cset->longlong10_to_str)(cs,Ptr,l,-10,num);
|
||||||
{
|
|
||||||
str_length=(uint32) (longlong10_to_str(num,Ptr,-10)-Ptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
str_length=cs->cset->snprintf(cs,Ptr,l,"%d",num);
|
|
||||||
}
|
|
||||||
str_charset=cs;
|
str_charset=cs;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -115,14 +113,7 @@ bool String::set(ulonglong num, CHARSET_INFO *cs)
|
|||||||
|
|
||||||
if (alloc(l))
|
if (alloc(l))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (cs->cset->snprintf == my_snprintf_8bit)
|
str_length=(uint32) (cs->cset->longlong10_to_str)(cs,Ptr,l,10,num);
|
||||||
{
|
|
||||||
str_length=(uint32) (longlong10_to_str(num,Ptr,10)-Ptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
str_length=cs->cset->snprintf(cs,Ptr,l,"%d",num);
|
|
||||||
}
|
|
||||||
str_charset=cs;
|
str_charset=cs;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -130,12 +121,13 @@ bool String::set(ulonglong num, CHARSET_INFO *cs)
|
|||||||
bool String::set(double num,uint decimals, CHARSET_INFO *cs)
|
bool String::set(double num,uint decimals, CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
char buff[331];
|
char buff[331];
|
||||||
|
uint dummy_errors;
|
||||||
|
|
||||||
str_charset=cs;
|
str_charset=cs;
|
||||||
if (decimals >= NOT_FIXED_DEC)
|
if (decimals >= NOT_FIXED_DEC)
|
||||||
{
|
{
|
||||||
sprintf(buff,"%.14g",num); // Enough for a DATETIME
|
uint32 len= my_sprintf(buff,(buff, "%.14g",num));// Enough for a DATETIME
|
||||||
return copy(buff, (uint32) strlen(buff), &my_charset_latin1, cs);
|
return copy(buff, len, &my_charset_latin1, cs, &dummy_errors);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_FCONVERT
|
#ifdef HAVE_FCONVERT
|
||||||
int decpt,sign;
|
int decpt,sign;
|
||||||
@ -150,7 +142,8 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs)
|
|||||||
buff[0]='-';
|
buff[0]='-';
|
||||||
pos=buff;
|
pos=buff;
|
||||||
}
|
}
|
||||||
return copy(pos,(uint32) strlen(pos), &my_charset_latin1, cs);
|
uint dummy_errors;
|
||||||
|
return copy(pos,(uint32) strlen(pos), &my_charset_latin1, cs, &dummy_errors);
|
||||||
}
|
}
|
||||||
if (alloc((uint32) ((uint32) decpt+3+decimals)))
|
if (alloc((uint32) ((uint32) decpt+3+decimals)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -200,7 +193,8 @@ end:
|
|||||||
#else
|
#else
|
||||||
sprintf(buff,"%.*f",(int) decimals,num);
|
sprintf(buff,"%.*f",(int) decimals,num);
|
||||||
#endif
|
#endif
|
||||||
return copy(buff,(uint32) strlen(buff), &my_charset_latin1, cs);
|
return copy(buff,(uint32) strlen(buff), &my_charset_latin1, cs,
|
||||||
|
&dummy_errors);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,55 +231,163 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy with charset convertion */
|
|
||||||
bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *from, CHARSET_INFO *to)
|
/*
|
||||||
|
Checks that the source string can be just copied to the destination string
|
||||||
|
without conversion.
|
||||||
|
|
||||||
|
SYNPOSIS
|
||||||
|
|
||||||
|
needs_conversion()
|
||||||
|
arg_length Length of string to copy.
|
||||||
|
from_cs Character set to copy from
|
||||||
|
to_cs Character set to copy to
|
||||||
|
uint32 *offset Returns number of unaligned characters.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 No conversion needed
|
||||||
|
1 Either character set conversion or adding leading zeros
|
||||||
|
(e.g. for UCS-2) must be done
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool String::needs_conversion(uint32 arg_length,
|
||||||
|
CHARSET_INFO *from_cs,
|
||||||
|
CHARSET_INFO *to_cs,
|
||||||
|
uint32 *offset)
|
||||||
{
|
{
|
||||||
uint32 new_length=to->mbmaxlen*arg_length;
|
*offset= 0;
|
||||||
int cnvres;
|
if ((to_cs == &my_charset_bin) ||
|
||||||
my_wc_t wc;
|
(to_cs == from_cs) ||
|
||||||
const uchar *s=(const uchar *)str;
|
my_charset_same(from_cs, to_cs) ||
|
||||||
const uchar *se=s+arg_length;
|
((from_cs == &my_charset_bin) &&
|
||||||
uchar *d, *de;
|
(!(*offset=(arg_length % to_cs->mbminlen)))))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (alloc(new_length))
|
|
||||||
|
/*
|
||||||
|
Copy a multi-byte character sets with adding leading zeros.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
|
||||||
|
copy_aligned()
|
||||||
|
str String to copy
|
||||||
|
arg_length Length of string. This should NOT be dividable with
|
||||||
|
cs->mbminlen.
|
||||||
|
offset arg_length % cs->mb_minlength
|
||||||
|
cs Character set for 'str'
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
For real multi-byte, ascii incompatible charactser sets,
|
||||||
|
like UCS-2, add leading zeros if we have an incomplete character.
|
||||||
|
Thus,
|
||||||
|
SELECT _ucs2 0xAA
|
||||||
|
will automatically be converted into
|
||||||
|
SELECT _ucs2 0x00AA
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset,
|
||||||
|
CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
/* How many bytes are in incomplete character */
|
||||||
|
offset= cs->mbmaxlen - offset; /* How many zeros we should prepend */
|
||||||
|
DBUG_ASSERT(offset && offset != cs->mbmaxlen);
|
||||||
|
|
||||||
|
uint32 aligned_length= arg_length + offset;
|
||||||
|
if (alloc(aligned_length))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
d=(uchar *)Ptr;
|
|
||||||
de=d+new_length;
|
|
||||||
|
|
||||||
for (str_length=new_length ; s < se && d < de ; )
|
/*
|
||||||
{
|
Note, this is only safe for little-endian UCS-2.
|
||||||
if ((cnvres=from->cset->mb_wc(from,&wc,s,se)) > 0 )
|
If we add big-endian UCS-2 sometimes, this code
|
||||||
{
|
will be more complicated. But it's OK for now.
|
||||||
s+=cnvres;
|
*/
|
||||||
}
|
bzero((char*) Ptr, offset);
|
||||||
else if (cnvres==MY_CS_ILSEQ)
|
memcpy(Ptr + offset, str, arg_length);
|
||||||
{
|
Ptr[aligned_length]=0;
|
||||||
s++;
|
/* str_length is always >= 0 as arg_length is != 0 */
|
||||||
wc='?';
|
str_length= aligned_length;
|
||||||
}
|
str_charset= cs;
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
outp:
|
|
||||||
if((cnvres=to->cset->wc_mb(to,wc,d,de)) >0 )
|
|
||||||
{
|
|
||||||
d+=cnvres;
|
|
||||||
}
|
|
||||||
else if (cnvres==MY_CS_ILUNI && wc!='?')
|
|
||||||
{
|
|
||||||
wc='?';
|
|
||||||
goto outp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Ptr[new_length]=0;
|
|
||||||
length((uint32) (d-(uchar *)Ptr));
|
|
||||||
str_charset=to;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
|
||||||
|
CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
/* How many bytes are in incomplete character */
|
||||||
|
uint32 offset= (arg_length % cs->mbminlen);
|
||||||
|
|
||||||
|
if (!offset) /* All characters are complete, just copy */
|
||||||
|
{
|
||||||
|
set(str, arg_length, cs);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return copy_aligned(str, arg_length, offset, cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy with charset convertion */
|
||||||
|
|
||||||
|
bool String::copy(const char *str, uint32 arg_length,
|
||||||
|
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors)
|
||||||
|
{
|
||||||
|
uint32 offset;
|
||||||
|
if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
|
||||||
|
{
|
||||||
|
*errors= 0;
|
||||||
|
return copy(str, arg_length, to_cs);
|
||||||
|
}
|
||||||
|
if ((from_cs == &my_charset_bin) && offset)
|
||||||
|
{
|
||||||
|
*errors= 0;
|
||||||
|
return copy_aligned(str, arg_length, offset, to_cs);
|
||||||
|
}
|
||||||
|
uint32 new_length= to_cs->mbmaxlen*arg_length;
|
||||||
|
if (alloc(new_length))
|
||||||
|
return TRUE;
|
||||||
|
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
|
||||||
|
str, arg_length, from_cs, errors);
|
||||||
|
str_charset=to_cs;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set a string to the value of a latin1-string, keeping the original charset
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
copy_or_set()
|
||||||
|
str String of a simple charset (latin1)
|
||||||
|
arg_length Length of string
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
If string object is of a simple character set, set it to point to the
|
||||||
|
given string.
|
||||||
|
If not, make a copy and convert it to the new character set.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 Could not allocate result buffer
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool String::set_ascii(const char *str, uint32 arg_length)
|
||||||
|
{
|
||||||
|
if (str_charset->mbminlen == 1)
|
||||||
|
{
|
||||||
|
set(str, arg_length, str_charset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint dummy_errors;
|
||||||
|
return copy(str, arg_length, &my_charset_latin1, str_charset, &dummy_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is used by mysql.cc */
|
/* This is used by mysql.cc */
|
||||||
|
|
||||||
bool String::fill(uint32 max_length,char fill_char)
|
bool String::fill(uint32 max_length,char fill_char)
|
||||||
@ -320,11 +422,34 @@ bool String::append(const String &s)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Append an ASCII string to the a string of the current character set
|
||||||
|
*/
|
||||||
|
|
||||||
bool String::append(const char *s,uint32 arg_length)
|
bool String::append(const char *s,uint32 arg_length)
|
||||||
{
|
{
|
||||||
if (!arg_length) // Default argument
|
if (!arg_length)
|
||||||
if (!(arg_length= (uint32) strlen(s)))
|
return FALSE;
|
||||||
return FALSE;
|
|
||||||
|
/*
|
||||||
|
For an ASCII incompatible string, e.g. UCS-2, we need to convert
|
||||||
|
*/
|
||||||
|
if (str_charset->mbminlen > 1)
|
||||||
|
{
|
||||||
|
uint32 add_length=arg_length * str_charset->mbmaxlen;
|
||||||
|
uint dummy_errors;
|
||||||
|
if (realloc(str_length+ add_length))
|
||||||
|
return TRUE;
|
||||||
|
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
|
||||||
|
s, arg_length, &my_charset_latin1,
|
||||||
|
&dummy_errors);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
For an ASCII compatinble string we can just append.
|
||||||
|
*/
|
||||||
if (realloc(str_length+arg_length))
|
if (realloc(str_length+arg_length))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
memcpy(Ptr+str_length,s,arg_length);
|
memcpy(Ptr+str_length,s,arg_length);
|
||||||
@ -332,6 +457,46 @@ bool String::append(const char *s,uint32 arg_length)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Append a 0-terminated ASCII string
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool String::append(const char *s)
|
||||||
|
{
|
||||||
|
return append(s, strlen(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Append a string in the given charset to the string
|
||||||
|
with character set recoding
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
uint32 dummy_offset;
|
||||||
|
|
||||||
|
if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
|
||||||
|
{
|
||||||
|
uint32 add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
|
||||||
|
uint dummy_errors;
|
||||||
|
if (realloc(str_length + add_length))
|
||||||
|
return TRUE;
|
||||||
|
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
|
||||||
|
s, arg_length, cs, &dummy_errors);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (realloc(str_length + arg_length))
|
||||||
|
return TRUE;
|
||||||
|
memcpy(Ptr + str_length, s, arg_length);
|
||||||
|
str_length+= arg_length;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TO_BE_REMOVED
|
#ifdef TO_BE_REMOVED
|
||||||
bool String::append(FILE* file, uint32 arg_length, myf my_flags)
|
bool String::append(FILE* file, uint32 arg_length, myf my_flags)
|
||||||
{
|
{
|
||||||
@ -360,48 +525,33 @@ bool String::append(IO_CACHE* file, uint32 arg_length)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool String::append_with_prefill(const char *s,uint32 arg_length,
|
||||||
|
uint32 full_length, char fill_char)
|
||||||
|
{
|
||||||
|
int t_length= arg_length > full_length ? arg_length : full_length;
|
||||||
|
|
||||||
|
if (realloc(str_length + t_length))
|
||||||
|
return TRUE;
|
||||||
|
t_length= full_length - arg_length;
|
||||||
|
if (t_length > 0)
|
||||||
|
{
|
||||||
|
bfill(Ptr+str_length, t_length, fill_char);
|
||||||
|
str_length=str_length + t_length;
|
||||||
|
}
|
||||||
|
append(s, arg_length);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 String::numchars()
|
uint32 String::numchars()
|
||||||
{
|
{
|
||||||
#ifdef USE_MB
|
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
|
||||||
register uint32 n=0,mblen;
|
|
||||||
register const char *mbstr=Ptr;
|
|
||||||
register const char *end=mbstr+str_length;
|
|
||||||
if (use_mb(str_charset))
|
|
||||||
{
|
|
||||||
while (mbstr < end) {
|
|
||||||
if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen;
|
|
||||||
else ++mbstr;
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
return str_length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int String::charpos(int i,uint32 offset)
|
int String::charpos(int i,uint32 offset)
|
||||||
{
|
{
|
||||||
#ifdef USE_MB
|
if (i <= 0)
|
||||||
register uint32 mblen;
|
|
||||||
register const char *mbstr=Ptr+offset;
|
|
||||||
register const char *end=Ptr+str_length;
|
|
||||||
if (use_mb(str_charset))
|
|
||||||
{
|
|
||||||
if (i<=0) return i;
|
|
||||||
while (i && mbstr < end) {
|
|
||||||
if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen;
|
|
||||||
else ++mbstr;
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
if ( INT_MAX32-i <= (int) (mbstr-Ptr-offset))
|
|
||||||
return INT_MAX32;
|
|
||||||
else
|
|
||||||
return (int) ((mbstr-Ptr-offset)+i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
return i;
|
return i;
|
||||||
|
return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
|
||||||
}
|
}
|
||||||
|
|
||||||
int String::strstr(const String &s,uint32 offset)
|
int String::strstr(const String &s,uint32 offset)
|
||||||
@ -431,40 +581,6 @@ skip:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Search after a string without regarding to case
|
|
||||||
This needs to be replaced when we have character sets per string
|
|
||||||
*/
|
|
||||||
|
|
||||||
int String::strstr_case(const String &s,uint32 offset)
|
|
||||||
{
|
|
||||||
if (s.length()+offset <= str_length)
|
|
||||||
{
|
|
||||||
if (!s.length())
|
|
||||||
return ((int) offset); // Empty string is always found
|
|
||||||
|
|
||||||
register const char *str = Ptr+offset;
|
|
||||||
register const char *search=s.ptr();
|
|
||||||
const char *end=Ptr+str_length-s.length()+1;
|
|
||||||
const char *search_end=s.ptr()+s.length();
|
|
||||||
skip:
|
|
||||||
while (str != end)
|
|
||||||
{
|
|
||||||
if (str_charset->sort_order[*str++] == str_charset->sort_order[*search])
|
|
||||||
{
|
|
||||||
register char *i,*j;
|
|
||||||
i=(char*) str; j=(char*) search+1;
|
|
||||||
while (j != search_end)
|
|
||||||
if (str_charset->sort_order[*i++] !=
|
|
||||||
str_charset->sort_order[*j++])
|
|
||||||
goto skip;
|
|
||||||
return (int) (str-Ptr) -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Search string from end. Offset is offset to the end of string
|
** Search string from end. Offset is offset to the end of string
|
||||||
*/
|
*/
|
||||||
@ -504,14 +620,20 @@ skip:
|
|||||||
|
|
||||||
bool String::replace(uint32 offset,uint32 arg_length,const String &to)
|
bool String::replace(uint32 offset,uint32 arg_length,const String &to)
|
||||||
{
|
{
|
||||||
long diff = (long) to.length()-(long) arg_length;
|
return replace(offset,arg_length,to.ptr(),to.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool String::replace(uint32 offset,uint32 arg_length,
|
||||||
|
const char *to,uint32 length)
|
||||||
|
{
|
||||||
|
long diff = (long) length-(long) arg_length;
|
||||||
if (offset+arg_length <= str_length)
|
if (offset+arg_length <= str_length)
|
||||||
{
|
{
|
||||||
if (diff < 0)
|
if (diff < 0)
|
||||||
{
|
{
|
||||||
if (to.length())
|
if (length)
|
||||||
memcpy(Ptr+offset,to.ptr(),to.length());
|
memcpy(Ptr+offset,to,length);
|
||||||
bmove(Ptr+offset+to.length(),Ptr+offset+arg_length,
|
bmove(Ptr+offset+length,Ptr+offset+arg_length,
|
||||||
str_length-offset-arg_length);
|
str_length-offset-arg_length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -523,14 +645,15 @@ bool String::replace(uint32 offset,uint32 arg_length,const String &to)
|
|||||||
bmove_upp(Ptr+str_length+diff,Ptr+str_length,
|
bmove_upp(Ptr+str_length+diff,Ptr+str_length,
|
||||||
str_length-offset-arg_length);
|
str_length-offset-arg_length);
|
||||||
}
|
}
|
||||||
if (to.length())
|
if (length)
|
||||||
memcpy(Ptr+offset,to.ptr(),to.length());
|
memcpy(Ptr+offset,to,length);
|
||||||
}
|
}
|
||||||
str_length+=(uint32) diff;
|
str_length+=(uint32) diff;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// added by Holyfoot for "geometry" needs
|
// added by Holyfoot for "geometry" needs
|
||||||
int String::reserve(uint32 space_needed, uint32 grow_by)
|
int String::reserve(uint32 space_needed, uint32 grow_by)
|
||||||
{
|
{
|
||||||
@ -542,9 +665,8 @@ int String::reserve(uint32 space_needed, uint32 grow_by)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void String::qs_append(const char *str)
|
void String::qs_append(const char *str, uint32 len)
|
||||||
{
|
{
|
||||||
int len = (int)strlen(str);
|
|
||||||
memcpy(Ptr + str_length, str, len + 1);
|
memcpy(Ptr + str_length, str, len + 1);
|
||||||
str_length += len;
|
str_length += len;
|
||||||
}
|
}
|
||||||
@ -552,8 +674,7 @@ void String::qs_append(const char *str)
|
|||||||
void String::qs_append(double d)
|
void String::qs_append(double d)
|
||||||
{
|
{
|
||||||
char *buff = Ptr + str_length;
|
char *buff = Ptr + str_length;
|
||||||
sprintf(buff,"%.14g", d);
|
str_length+= my_sprintf(buff, (buff, "%.14g", d));
|
||||||
str_length += (int)strlen(buff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void String::qs_append(double *d)
|
void String::qs_append(double *d)
|
||||||
@ -563,90 +684,70 @@ void String::qs_append(double *d)
|
|||||||
qs_append(ld);
|
qs_append(ld);
|
||||||
}
|
}
|
||||||
|
|
||||||
void String::qs_append(const char &c)
|
void String::qs_append(int i)
|
||||||
{
|
{
|
||||||
Ptr[str_length] = c;
|
char *buff= Ptr + str_length;
|
||||||
str_length += sizeof(c);
|
char *end= int10_to_str(i, buff, -10);
|
||||||
|
str_length+= (int) (end-buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::qs_append(uint i)
|
||||||
|
{
|
||||||
|
char *buff= Ptr + str_length;
|
||||||
|
char *end= int10_to_str(i, buff, 10);
|
||||||
|
str_length+= (int) (end-buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare strings according to collation, without end space.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
sortcmp()
|
||||||
|
s First string
|
||||||
|
t Second string
|
||||||
|
cs Collation
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
Normally this is case sensitive comparison
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
< 0 s < t
|
||||||
|
0 s == t
|
||||||
|
> 0 s > t
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int sortcmp(const String *s,const String *t, CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
return cs->coll->strnncollsp(cs,
|
||||||
|
(unsigned char *) s->ptr(),s->length(),
|
||||||
|
(unsigned char *) t->ptr(),t->length(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int sortcmp(const String *x,const String *y)
|
/*
|
||||||
|
Compare strings byte by byte. End spaces are also compared.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
stringcmp()
|
||||||
|
s First string
|
||||||
|
t Second string
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
Strings are compared as a stream of unsigned chars
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
< 0 s < t
|
||||||
|
0 s == t
|
||||||
|
> 0 s > t
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int stringcmp(const String *s,const String *t)
|
||||||
{
|
{
|
||||||
const char *s= x->ptr();
|
uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
|
||||||
const char *t= y->ptr();
|
int cmp= memcmp(s->ptr(), t->ptr(), len);
|
||||||
uint32 x_len=x->length(),y_len=y->length(),len=min(x_len,y_len);
|
return (cmp) ? cmp : (int) (s_len - t_len);
|
||||||
|
|
||||||
if (use_strnxfrm(x->str_charset))
|
|
||||||
{
|
|
||||||
#ifndef CMP_ENDSPACE
|
|
||||||
while (x_len && my_isspace(x->str_charset,s[x_len-1]))
|
|
||||||
x_len--;
|
|
||||||
while (y_len && my_isspace(x->str_charset,t[y_len-1]))
|
|
||||||
y_len--;
|
|
||||||
#endif
|
|
||||||
return my_strnncoll(x->str_charset,
|
|
||||||
(unsigned char *)s,x_len,(unsigned char *)t,y_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x_len-=len; // For easy end space test
|
|
||||||
y_len-=len;
|
|
||||||
if (x->str_charset->sort_order)
|
|
||||||
{
|
|
||||||
while (len--)
|
|
||||||
{
|
|
||||||
if (x->str_charset->sort_order[(uchar) *s++] !=
|
|
||||||
x->str_charset->sort_order[(uchar) *t++])
|
|
||||||
return ((int) x->str_charset->sort_order[(uchar) s[-1]] -
|
|
||||||
(int) x->str_charset->sort_order[(uchar) t[-1]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (len--)
|
|
||||||
{
|
|
||||||
if (*s++ != *t++)
|
|
||||||
return ((int) s[-1] - (int) t[-1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifndef CMP_ENDSPACE
|
|
||||||
/* Don't compare end space in strings */
|
|
||||||
{
|
|
||||||
if (y_len)
|
|
||||||
{
|
|
||||||
const char *end=t+y_len;
|
|
||||||
for (; t != end ; t++)
|
|
||||||
if (!my_isspace(x->str_charset,*t))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char *end=s+x_len;
|
|
||||||
for (; s != end ; s++)
|
|
||||||
if (!my_isspace(x->str_charset,*s))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return (int) (x_len-y_len);
|
|
||||||
#endif /* CMP_ENDSPACE */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int stringcmp(const String *x,const String *y)
|
|
||||||
{
|
|
||||||
const char *s= x->ptr();
|
|
||||||
const char *t= y->ptr();
|
|
||||||
uint32 x_len=x->length(),y_len=y->length(),len=min(x_len,y_len);
|
|
||||||
|
|
||||||
while (len--)
|
|
||||||
{
|
|
||||||
if (*s++ != *t++)
|
|
||||||
return ((int) (uchar) s[-1] - (int) (uchar) t[-1]);
|
|
||||||
}
|
|
||||||
return (int) (x_len-y_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -668,4 +769,124 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
Help functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
copy a string from one character set to another
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
copy_and_convert()
|
||||||
|
to Store result here
|
||||||
|
to_cs Character set of result string
|
||||||
|
from Copy from here
|
||||||
|
from_length Length of from string
|
||||||
|
from_cs From character set
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
'to' must be big enough as form_length * to_cs->mbmaxlen
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
length of bytes copied to 'to'
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
|
||||||
|
const char *from, uint32 from_length, CHARSET_INFO *from_cs,
|
||||||
|
uint *errors)
|
||||||
|
{
|
||||||
|
int cnvres;
|
||||||
|
my_wc_t wc;
|
||||||
|
const uchar *from_end= (const uchar*) from+from_length;
|
||||||
|
char *to_start= to;
|
||||||
|
uchar *to_end= (uchar*) to+to_length;
|
||||||
|
int (*mb_wc)(struct charset_info_st *, my_wc_t *, const uchar *,
|
||||||
|
const uchar *) = from_cs->cset->mb_wc;
|
||||||
|
int (*wc_mb)(struct charset_info_st *, my_wc_t, uchar *s, uchar *e)=
|
||||||
|
to_cs->cset->wc_mb;
|
||||||
|
uint error_count= 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from,
|
||||||
|
from_end)) > 0)
|
||||||
|
from+= cnvres;
|
||||||
|
else if (cnvres == MY_CS_ILSEQ)
|
||||||
|
{
|
||||||
|
error_count++;
|
||||||
|
from++;
|
||||||
|
wc= '?';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break; // Impossible char.
|
||||||
|
|
||||||
|
outp:
|
||||||
|
if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0)
|
||||||
|
to+= cnvres;
|
||||||
|
else if (cnvres == MY_CS_ILUNI && wc != '?')
|
||||||
|
{
|
||||||
|
error_count++;
|
||||||
|
wc= '?';
|
||||||
|
goto outp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*errors= error_count;
|
||||||
|
return (uint32) (to - to_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void String::print(String *str)
|
||||||
|
{
|
||||||
|
char *st= (char*)Ptr, *end= st+str_length;
|
||||||
|
for (; st < end; st++)
|
||||||
|
{
|
||||||
|
uchar c= *st;
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '\\':
|
||||||
|
str->append("\\\\", 2);
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
str->append("\\0", 2);
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
str->append("\\'", 2);
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
str->append("\\n", 2);
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
str->append("\\r", 2);
|
||||||
|
break;
|
||||||
|
case 26: //Ctrl-Z
|
||||||
|
str->append("\\z", 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
str->append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Exchange state of this object and argument.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
String::swap()
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
Target string will contain state of this object and vice versa.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void String::swap(String &s)
|
||||||
|
{
|
||||||
|
swap_variables(char *, Ptr, s.Ptr);
|
||||||
|
swap_variables(uint32, str_length, s.str_length);
|
||||||
|
swap_variables(uint32, Alloced_length, s.Alloced_length);
|
||||||
|
swap_variables(bool, alloced, s.alloced);
|
||||||
|
swap_variables(CHARSET_INFO*, str_charset, s.str_charset);
|
||||||
|
}
|
||||||
|
@ -25,9 +25,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
class String;
|
class String;
|
||||||
int sortcmp(const String *a,const String *b);
|
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
|
||||||
int stringcmp(const String *a,const String *b);
|
|
||||||
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
||||||
|
uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
|
||||||
|
const char *from, uint32 from_length,
|
||||||
|
CHARSET_INFO *from_cs, uint *errors);
|
||||||
|
|
||||||
class String
|
class String
|
||||||
{
|
{
|
||||||
@ -39,12 +41,12 @@ public:
|
|||||||
String()
|
String()
|
||||||
{
|
{
|
||||||
Ptr=0; str_length=Alloced_length=0; alloced=0;
|
Ptr=0; str_length=Alloced_length=0; alloced=0;
|
||||||
str_charset= &my_charset_latin1;
|
str_charset= &my_charset_bin;
|
||||||
}
|
}
|
||||||
String(uint32 length_arg)
|
String(uint32 length_arg)
|
||||||
{
|
{
|
||||||
alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
|
alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
|
||||||
str_charset= &my_charset_latin1;
|
str_charset= &my_charset_bin;
|
||||||
}
|
}
|
||||||
String(const char *str, CHARSET_INFO *cs)
|
String(const char *str, CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
@ -67,12 +69,15 @@ public:
|
|||||||
Alloced_length=str.Alloced_length; alloced=0;
|
Alloced_length=str.Alloced_length; alloced=0;
|
||||||
str_charset=str.str_charset;
|
str_charset=str.str_charset;
|
||||||
}
|
}
|
||||||
static void *operator new(size_t size) { return (void*) sql_alloc((uint) size); }
|
static void *operator new(size_t size, MEM_ROOT *mem_root)
|
||||||
static void operator delete(void *ptr_arg,size_t size) /*lint -e715 */
|
{ return (void*) alloc_root(mem_root, (uint) size); }
|
||||||
{ sql_element_free(ptr_arg); }
|
static void operator delete(void *ptr_arg,size_t size)
|
||||||
|
{ TRASH(ptr_arg, size); }
|
||||||
|
static void operator delete(void *ptr_arg, MEM_ROOT *mem_root)
|
||||||
|
{ /* never called */ }
|
||||||
~String() { free(); }
|
~String() { free(); }
|
||||||
|
|
||||||
inline void set_charset(CHARSET_INFO *charset) { str_charset=charset; }
|
inline void set_charset(CHARSET_INFO *charset) { str_charset= charset; }
|
||||||
inline CHARSET_INFO *charset() const { return str_charset; }
|
inline CHARSET_INFO *charset() const { return str_charset; }
|
||||||
inline uint32 length() const { return str_length;}
|
inline uint32 length() const { return str_length;}
|
||||||
inline uint32 alloced_length() const { return Alloced_length;}
|
inline uint32 alloced_length() const { return Alloced_length;}
|
||||||
@ -103,6 +108,7 @@ public:
|
|||||||
|
|
||||||
void set(String &str,uint32 offset,uint32 arg_length)
|
void set(String &str,uint32 offset,uint32 arg_length)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(&str != this);
|
||||||
free();
|
free();
|
||||||
Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0;
|
Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0;
|
||||||
if (str.Alloced_length)
|
if (str.Alloced_length)
|
||||||
@ -123,6 +129,7 @@ public:
|
|||||||
Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
|
Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
|
||||||
str_charset=cs;
|
str_charset=cs;
|
||||||
}
|
}
|
||||||
|
bool set_ascii(const char *str, uint32 arg_length);
|
||||||
inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs)
|
inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
if (!alloced)
|
if (!alloced)
|
||||||
@ -134,6 +141,34 @@ public:
|
|||||||
bool set(longlong num, CHARSET_INFO *cs);
|
bool set(longlong num, CHARSET_INFO *cs);
|
||||||
bool set(ulonglong num, CHARSET_INFO *cs);
|
bool set(ulonglong num, CHARSET_INFO *cs);
|
||||||
bool set(double num,uint decimals, CHARSET_INFO *cs);
|
bool set(double num,uint decimals, CHARSET_INFO *cs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
PMG 2004.11.12
|
||||||
|
This is a method that works the same as perl's "chop". It simply
|
||||||
|
drops the last character of a string. This is useful in the case
|
||||||
|
of the federated storage handler where I'm building a unknown
|
||||||
|
number, list of values and fields to be used in a sql insert
|
||||||
|
statement to be run on the remote server, and have a comma after each.
|
||||||
|
When the list is complete, I "chop" off the trailing comma
|
||||||
|
|
||||||
|
ex.
|
||||||
|
String stringobj;
|
||||||
|
stringobj.append("VALUES ('foo', 'fi', 'fo',");
|
||||||
|
stringobj.chop();
|
||||||
|
stringobj.append(")");
|
||||||
|
|
||||||
|
In this case, the value of string was:
|
||||||
|
|
||||||
|
VALUES ('foo', 'fi', 'fo',
|
||||||
|
VALUES ('foo', 'fi', 'fo'
|
||||||
|
VALUES ('foo', 'fi', 'fo')
|
||||||
|
|
||||||
|
*/
|
||||||
|
inline void chop()
|
||||||
|
{
|
||||||
|
Ptr[str_length--]= '\0';
|
||||||
|
}
|
||||||
|
|
||||||
inline void free()
|
inline void free()
|
||||||
{
|
{
|
||||||
if (alloced)
|
if (alloced)
|
||||||
@ -175,6 +210,11 @@ public:
|
|||||||
{
|
{
|
||||||
if (&s != this)
|
if (&s != this)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
It is forbidden to do assignments like
|
||||||
|
some_string = substring_of_that_string
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(!s.uses_buffer_owned_by(this));
|
||||||
free();
|
free();
|
||||||
Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
|
Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
|
||||||
alloced=0;
|
alloced=0;
|
||||||
@ -185,13 +225,24 @@ public:
|
|||||||
bool copy(); // Alloc string if not alloced
|
bool copy(); // Alloc string if not alloced
|
||||||
bool copy(const String &s); // Allocate new string
|
bool copy(const String &s); // Allocate new string
|
||||||
bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string
|
bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string
|
||||||
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, CHARSET_INFO *csto);
|
static bool needs_conversion(uint32 arg_length,
|
||||||
|
CHARSET_INFO *cs_from, CHARSET_INFO *cs_to,
|
||||||
|
uint32 *offset);
|
||||||
|
bool copy_aligned(const char *s, uint32 arg_length, uint32 offset,
|
||||||
|
CHARSET_INFO *cs);
|
||||||
|
bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
|
||||||
|
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
|
||||||
|
CHARSET_INFO *csto, uint *errors);
|
||||||
bool append(const String &s);
|
bool append(const String &s);
|
||||||
bool append(const char *s,uint32 arg_length=0);
|
bool append(const char *s);
|
||||||
|
bool append(const char *s,uint32 arg_length);
|
||||||
|
bool append(const char *s,uint32 arg_length, CHARSET_INFO *cs);
|
||||||
bool append(IO_CACHE* file, uint32 arg_length);
|
bool append(IO_CACHE* file, uint32 arg_length);
|
||||||
|
bool append_with_prefill(const char *s, uint32 arg_length,
|
||||||
|
uint32 full_length, char fill_char);
|
||||||
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
||||||
int strstr_case(const String &s,uint32 offset=0);
|
|
||||||
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
||||||
|
bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length);
|
||||||
bool replace(uint32 offset,uint32 arg_length,const String &to);
|
bool replace(uint32 offset,uint32 arg_length,const String &to);
|
||||||
inline bool append(char chr)
|
inline bool append(char chr)
|
||||||
{
|
{
|
||||||
@ -211,7 +262,7 @@ public:
|
|||||||
void strip_sp();
|
void strip_sp();
|
||||||
inline void caseup() { my_caseup(str_charset,Ptr,str_length); }
|
inline void caseup() { my_caseup(str_charset,Ptr,str_length); }
|
||||||
inline void casedn() { my_casedn(str_charset,Ptr,str_length); }
|
inline void casedn() { my_casedn(str_charset,Ptr,str_length); }
|
||||||
friend int sortcmp(const String *a,const String *b);
|
friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
|
||||||
friend int stringcmp(const String *a,const String *b);
|
friend int stringcmp(const String *a,const String *b);
|
||||||
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
||||||
uint32 numchars();
|
uint32 numchars();
|
||||||
@ -228,11 +279,11 @@ public:
|
|||||||
q_*** methods writes values of parameters itself
|
q_*** methods writes values of parameters itself
|
||||||
qs_*** methods writes string representation of value
|
qs_*** methods writes string representation of value
|
||||||
*/
|
*/
|
||||||
void q_append(const char &c)
|
void q_append(const char c)
|
||||||
{
|
{
|
||||||
Ptr[str_length++] = c;
|
Ptr[str_length++] = c;
|
||||||
}
|
}
|
||||||
void q_append(const uint32 &n)
|
void q_append(const uint32 n)
|
||||||
{
|
{
|
||||||
int4store(Ptr + str_length, n);
|
int4store(Ptr + str_length, n);
|
||||||
str_length += 4;
|
str_length += 4;
|
||||||
@ -253,13 +304,53 @@ public:
|
|||||||
str_length += data_len;
|
str_length += data_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteAtPosition(int position, uint32 value)
|
void write_at_position(int position, uint32 value)
|
||||||
{
|
{
|
||||||
int4store(Ptr + position,value);
|
int4store(Ptr + position,value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qs_append(const char *str);
|
void qs_append(const char *str, uint32 len);
|
||||||
void qs_append(double d);
|
void qs_append(double d);
|
||||||
void qs_append(double *d);
|
void qs_append(double *d);
|
||||||
void qs_append(const char &c);
|
inline void qs_append(const char c)
|
||||||
|
{
|
||||||
|
Ptr[str_length]= c;
|
||||||
|
str_length++;
|
||||||
|
}
|
||||||
|
void qs_append(int i);
|
||||||
|
void qs_append(uint i);
|
||||||
|
|
||||||
|
/* Inline (general) functions used by the protocol functions */
|
||||||
|
|
||||||
|
inline char *prep_append(uint32 arg_length, uint32 step_alloc)
|
||||||
|
{
|
||||||
|
uint32 new_length= arg_length + str_length;
|
||||||
|
if (new_length > Alloced_length)
|
||||||
|
{
|
||||||
|
if (realloc(new_length + step_alloc))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint32 old_length= str_length;
|
||||||
|
str_length+= arg_length;
|
||||||
|
return Ptr+ old_length; /* Area to use */
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool append(const char *s, uint32 arg_length, uint32 step_alloc)
|
||||||
|
{
|
||||||
|
uint32 new_length= arg_length + str_length;
|
||||||
|
if (new_length > Alloced_length && realloc(new_length + step_alloc))
|
||||||
|
return TRUE;
|
||||||
|
memcpy(Ptr+str_length, s, arg_length);
|
||||||
|
str_length+= arg_length;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
void print(String *print);
|
||||||
|
|
||||||
|
/* Swap two string objects. Efficient way to exchange data without memcpy. */
|
||||||
|
void swap(String &s);
|
||||||
|
|
||||||
|
inline bool uses_buffer_owned_by(const String *s) const
|
||||||
|
{
|
||||||
|
return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -20,16 +20,14 @@ CREATE TABLE federated.t1 (
|
|||||||
)
|
)
|
||||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||||
COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1';
|
COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1';
|
||||||
ERROR HY000: Can't create table 'this connection string is not in the correct format!
|
ERROR HY000: Can't create table 'connection string is not in the correct format' (errno: 0)
|
||||||
' (errno: 0)
|
|
||||||
CREATE TABLE federated.t1 (
|
CREATE TABLE federated.t1 (
|
||||||
`id` int(20) NOT NULL,
|
`id` int(20) NOT NULL,
|
||||||
`name` varchar(32) NOT NULL default ''
|
`name` varchar(32) NOT NULL default ''
|
||||||
)
|
)
|
||||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||||
COMMENT='mysql://root@127.0.0.1';
|
COMMENT='mysql://root@127.0.0.1';
|
||||||
ERROR HY000: Can't create table 'this connection string is not in the correct format!
|
ERROR HY000: Can't create table 'connection string is not in the correct format' (errno: 0)
|
||||||
' (errno: 0)
|
|
||||||
CREATE TABLE federated.t1 (
|
CREATE TABLE federated.t1 (
|
||||||
`id` int(20) NOT NULL,
|
`id` int(20) NOT NULL,
|
||||||
`name` varchar(32) NOT NULL default ''
|
`name` varchar(32) NOT NULL default ''
|
||||||
|
38
sql/field.cc
38
sql/field.cc
@ -5328,11 +5328,11 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table)
|
|||||||
|
|
||||||
int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
|
int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
int error= 0;
|
|
||||||
uint32 not_used, copy_length;
|
uint32 not_used, copy_length;
|
||||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||||
String tmpstr(buff,sizeof(buff), &my_charset_bin);
|
String tmpstr(buff,sizeof(buff), &my_charset_bin);
|
||||||
bool lost_only_spaces= FALSE;
|
int error_code= 0;
|
||||||
|
enum MYSQL_ERROR::enum_warning_level level= MYSQL_ERROR::WARN_LEVEL_WARN;
|
||||||
|
|
||||||
/* Convert character set if necessary */
|
/* Convert character set if necessary */
|
||||||
if (String::needs_conversion(length, cs, field_charset, ¬_used))
|
if (String::needs_conversion(length, cs, field_charset, ¬_used))
|
||||||
@ -5342,7 +5342,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
from= tmpstr.ptr();
|
from= tmpstr.ptr();
|
||||||
length= tmpstr.length();
|
length= tmpstr.length();
|
||||||
if (conv_errors)
|
if (conv_errors)
|
||||||
error= 1;
|
error_code= WARN_DATA_TRUNCATED;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Make sure we don't break a multibyte sequence
|
Make sure we don't break a multibyte sequence
|
||||||
@ -5359,30 +5359,26 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
int2store(ptr, copy_length);
|
int2store(ptr, copy_length);
|
||||||
|
|
||||||
// Check if we lost something other than just trailing spaces
|
// Check if we lost something other than just trailing spaces
|
||||||
if ((copy_length < length) && table->in_use->count_cuted_fields)
|
if ((copy_length < length) && table->in_use->count_cuted_fields &&
|
||||||
|
!error_code)
|
||||||
{
|
{
|
||||||
const char *end= from + length;
|
const char *end= from + length;
|
||||||
from+= copy_length;
|
from+= copy_length;
|
||||||
from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES);
|
from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES);
|
||||||
/*
|
/* If we lost only spaces then produce a NOTE, not a WARNING */
|
||||||
If we lost only spaces then produce a NOTE, not a WARNING.
|
if (from == end)
|
||||||
But if we have already had errors (e.g with charset conversion),
|
level= MYSQL_ERROR::WARN_LEVEL_NOTE;
|
||||||
then don't reset level to NOTE.
|
error_code= WARN_DATA_TRUNCATED;
|
||||||
*/
|
|
||||||
if (from == end && !error)
|
|
||||||
lost_only_spaces= TRUE;
|
|
||||||
error= 1;
|
|
||||||
}
|
}
|
||||||
if (error)
|
if (error_code)
|
||||||
{
|
{
|
||||||
if (lost_only_spaces)
|
if (level == MYSQL_ERROR::WARN_LEVEL_WARN &&
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
table->in_use->abort_on_warning)
|
||||||
else if (table->in_use->abort_on_warning)
|
error_code= ER_DATA_TOO_LONG;
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
|
set_warning(level, error_code, 1);
|
||||||
else
|
return 1;
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
|
||||||
}
|
}
|
||||||
return error;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -7562,7 +7558,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
|
|||||||
false - otherwise
|
false - otherwise
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
Field::set_warning(const uint level, const uint code, int cuted_increment)
|
Field::set_warning(uint level, uint code, int cuted_increment)
|
||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
THD *thd= table->in_use;
|
||||||
if (thd->count_cuted_fields)
|
if (thd->count_cuted_fields)
|
||||||
|
@ -279,7 +279,7 @@ public:
|
|||||||
virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
|
virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
|
||||||
virtual bool has_charset(void) const { return FALSE; }
|
virtual bool has_charset(void) const { return FALSE; }
|
||||||
virtual void set_charset(CHARSET_INFO *charset) { }
|
virtual void set_charset(CHARSET_INFO *charset) { }
|
||||||
bool set_warning(const unsigned int level, const unsigned int code,
|
bool set_warning(unsigned int level, unsigned int code,
|
||||||
int cuted_increment);
|
int cuted_increment);
|
||||||
bool check_int(const char *str, int length, const char *int_end,
|
bool check_int(const char *str, int length, const char *int_end,
|
||||||
CHARSET_INFO *cs);
|
CHARSET_INFO *cs);
|
||||||
|
@ -662,7 +662,7 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
my_error(error_num, MYF(0),
|
my_error(error_num, MYF(0),
|
||||||
"this connection string is not in the correct format!\n");
|
"connection string is not in the correct format",0);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -834,7 +834,7 @@ int ha_recover(HASH *commit_list)
|
|||||||
for now, only InnoDB supports 2pc. It means we can always safely
|
for now, only InnoDB supports 2pc. It means we can always safely
|
||||||
rollback all pending transactions, without risking inconsistent data
|
rollback all pending transactions, without risking inconsistent data
|
||||||
*/
|
*/
|
||||||
DBUG_ASSERT(total_ha_2pc == opt_bin_log+1); // only InnoDB and binlog
|
DBUG_ASSERT(total_ha_2pc == (ulong) opt_bin_log+1); // only InnoDB and binlog
|
||||||
tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK
|
tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK
|
||||||
dry_run=FALSE;
|
dry_run=FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
@ -4370,19 +4370,19 @@ Item_func_sp::Item_func_sp(sp_name *name)
|
|||||||
{
|
{
|
||||||
maybe_null= 1;
|
maybe_null= 1;
|
||||||
m_name->init_qname(current_thd);
|
m_name->init_qname(current_thd);
|
||||||
dummy_table= (TABLE *)sql_alloc(sizeof(TABLE));
|
dummy_table= (TABLE*) sql_calloc(sizeof(TABLE));
|
||||||
bzero(dummy_table, sizeof(TABLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list)
|
Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list)
|
||||||
:Item_func(list), m_name(name), m_sp(NULL)
|
:Item_func(list), m_name(name), m_sp(NULL)
|
||||||
{
|
{
|
||||||
maybe_null= 1;
|
maybe_null= 1;
|
||||||
m_name->init_qname(current_thd);
|
m_name->init_qname(current_thd);
|
||||||
dummy_table= (TABLE *)sql_alloc(sizeof(TABLE));
|
dummy_table= (TABLE*) sql_calloc(sizeof(TABLE));
|
||||||
bzero(dummy_table, sizeof(TABLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
Item_func_sp::func_name() const
|
Item_func_sp::func_name() const
|
||||||
{
|
{
|
||||||
|
@ -727,7 +727,7 @@ Item_sum_avg_distinct::fix_length_and_dec()
|
|||||||
AVG() will divide val by count. We need to reserve digits
|
AVG() will divide val by count. We need to reserve digits
|
||||||
after decimal point as the result can be fractional.
|
after decimal point as the result can be fractional.
|
||||||
*/
|
*/
|
||||||
decimals+= 4;
|
decimals= min(decimals + 4, NOT_FIXED_DEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -927,7 +927,7 @@ void Item_sum_variance::fix_length_and_dec()
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("Item_sum_variance::fix_length_and_dec");
|
DBUG_ENTER("Item_sum_variance::fix_length_and_dec");
|
||||||
maybe_null= null_value= 1;
|
maybe_null= null_value= 1;
|
||||||
decimals= args[0]->decimals + 4;
|
decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
|
||||||
switch (args[0]->result_type()) {
|
switch (args[0]->result_type()) {
|
||||||
case REAL_RESULT:
|
case REAL_RESULT:
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
|
@ -562,7 +562,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
|
|||||||
my_free((gptr) table,MYF(0));
|
my_free((gptr) table,MYF(0));
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
if (remove_table_from_cache(thd, db, table_list->table_name))
|
if (remove_table_from_cache(thd, db, table_list->table_name, 0))
|
||||||
DBUG_RETURN(1); // Table is in use
|
DBUG_RETURN(1); // Table is in use
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
@ -2575,7 +2575,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
|
|||||||
"data truncated" warning but which is absorbed and never gets to the
|
"data truncated" warning but which is absorbed and never gets to the
|
||||||
error log); still we init it to avoid a Valgrind message.
|
error log); still we init it to avoid a Valgrind message.
|
||||||
*/
|
*/
|
||||||
mysql_reset_errors(thd);
|
mysql_reset_errors(thd, 0);
|
||||||
|
|
||||||
TABLE_LIST tables;
|
TABLE_LIST tables;
|
||||||
bzero((char*) &tables,sizeof(tables));
|
bzero((char*) &tables,sizeof(tables));
|
||||||
|
@ -632,10 +632,11 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t);
|
|||||||
int mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
|
int mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
|
||||||
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||||
Item ***copy_func, Field **from_field,
|
Item ***copy_func, Field **from_field,
|
||||||
bool group, bool modify_item, uint convert_blob_length);
|
bool group, bool modify_item,
|
||||||
|
uint convert_blob_length);
|
||||||
int prepare_create_field(create_field *sql_field,
|
int prepare_create_field(create_field *sql_field,
|
||||||
uint &blob_columns,
|
uint *blob_columns,
|
||||||
int ×tamps, int ×tamps_with_niladic,
|
int *timestamps, int *timestamps_with_niladic,
|
||||||
uint table_flags);
|
uint table_flags);
|
||||||
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||||
List<create_field> &fields,
|
List<create_field> &fields,
|
||||||
@ -661,7 +662,7 @@ bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
|
|||||||
uint order_num, ORDER *order,
|
uint order_num, ORDER *order,
|
||||||
enum enum_duplicates handle_duplicates,
|
enum enum_duplicates handle_duplicates,
|
||||||
bool ignore,
|
bool ignore,
|
||||||
ALTER_INFO *alter_info, bool do_send_ok=1);
|
ALTER_INFO *alter_info, bool do_send_ok);
|
||||||
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
|
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
|
||||||
bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
|
bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
|
||||||
HA_CREATE_INFO *create_info,
|
HA_CREATE_INFO *create_info,
|
||||||
@ -705,7 +706,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT* mem,
|
|||||||
bool *refresh);
|
bool *refresh);
|
||||||
TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table);
|
TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table);
|
||||||
TABLE *find_locked_table(THD *thd, const char *db,const char *table_name);
|
TABLE *find_locked_table(THD *thd, const char *db,const char *table_name);
|
||||||
bool reopen_table(TABLE *table,bool locked=0);
|
bool reopen_table(TABLE *table,bool locked);
|
||||||
bool reopen_tables(THD *thd,bool get_locks,bool in_refresh);
|
bool reopen_tables(THD *thd,bool get_locks,bool in_refresh);
|
||||||
void close_old_data_files(THD *thd, TABLE *table, bool abort_locks,
|
void close_old_data_files(THD *thd, TABLE *table, bool abort_locks,
|
||||||
bool send_refresh);
|
bool send_refresh);
|
||||||
@ -769,7 +770,7 @@ void append_identifier(THD *thd, String *packet, const char *name,
|
|||||||
uint length);
|
uint length);
|
||||||
int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
|
int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
|
||||||
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
|
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
|
||||||
int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd = -1);
|
int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd);
|
||||||
bool mysqld_show_create(THD *thd, TABLE_LIST *table_list);
|
bool mysqld_show_create(THD *thd, TABLE_LIST *table_list);
|
||||||
bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create);
|
bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create);
|
||||||
|
|
||||||
@ -790,7 +791,7 @@ void calc_sum_of_all_status(STATUS_VAR *to);
|
|||||||
extern LEX_STRING information_schema_name;
|
extern LEX_STRING information_schema_name;
|
||||||
LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
|
LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
|
||||||
const char* str, uint length,
|
const char* str, uint length,
|
||||||
bool allocate_lex_string= 0);
|
bool allocate_lex_string);
|
||||||
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name);
|
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name);
|
||||||
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx);
|
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx);
|
||||||
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
||||||
@ -806,7 +807,7 @@ bool get_schema_tables_result(JOIN *join);
|
|||||||
|
|
||||||
/* sql_prepare.cc */
|
/* sql_prepare.cc */
|
||||||
bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
|
bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
|
||||||
LEX_STRING *name=NULL);
|
LEX_STRING *name);
|
||||||
void mysql_stmt_execute(THD *thd, char *packet, uint packet_length);
|
void mysql_stmt_execute(THD *thd, char *packet, uint packet_length);
|
||||||
void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name);
|
void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name);
|
||||||
void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length);
|
void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length);
|
||||||
@ -821,11 +822,11 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint
|
|||||||
const char *msg);
|
const char *msg);
|
||||||
void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
||||||
uint code, const char *format, ...);
|
uint code, const char *format, ...);
|
||||||
void mysql_reset_errors(THD *thd, bool force= false);
|
void mysql_reset_errors(THD *thd, bool force);
|
||||||
bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
|
bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
|
||||||
|
|
||||||
/* sql_handler.cc */
|
/* sql_handler.cc */
|
||||||
bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen= 0);
|
bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen);
|
||||||
bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
|
bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
|
||||||
bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
|
bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
|
||||||
List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
|
List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
|
||||||
@ -854,15 +855,15 @@ create_field * new_create_field(THD *thd, char *field_name, enum_field_types typ
|
|||||||
List<String> *interval_list, CHARSET_INFO *cs,
|
List<String> *interval_list, CHARSET_INFO *cs,
|
||||||
uint uint_geom_type);
|
uint uint_geom_type);
|
||||||
void store_position_for_column(const char *name);
|
void store_position_for_column(const char *name);
|
||||||
bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc=0);
|
bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc);
|
||||||
void add_join_on(TABLE_LIST *b,Item *expr);
|
void add_join_on(TABLE_LIST *b,Item *expr);
|
||||||
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b);
|
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b);
|
||||||
bool add_proc_to_list(THD *thd, Item *item);
|
bool add_proc_to_list(THD *thd, Item *item);
|
||||||
TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
|
TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
|
||||||
|
|
||||||
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
||||||
table_map read_tables, COND *conds, int *error,
|
table_map read_tables, COND *conds,
|
||||||
bool allow_null_cond= false);
|
bool allow_null_cond, int *error);
|
||||||
extern Item **not_found_item;
|
extern Item **not_found_item;
|
||||||
Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
|
Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
|
||||||
find_item_error_report_type report_error,
|
find_item_error_report_type report_error,
|
||||||
@ -905,13 +906,13 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
|
|||||||
TABLE_LIST *unique_table(TABLE_LIST *table, TABLE_LIST *table_list);
|
TABLE_LIST *unique_table(TABLE_LIST *table, TABLE_LIST *table_list);
|
||||||
TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name);
|
TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name);
|
||||||
bool close_temporary_table(THD *thd, const char *db, const char *table_name);
|
bool close_temporary_table(THD *thd, const char *db, const char *table_name);
|
||||||
void close_temporary(TABLE *table, bool delete_table=1);
|
void close_temporary(TABLE *table, bool delete_table);
|
||||||
bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
|
bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
|
||||||
const char *table_name);
|
const char *table_name);
|
||||||
void remove_db_from_cache(const char *db);
|
void remove_db_from_cache(const char *db);
|
||||||
void flush_tables();
|
void flush_tables();
|
||||||
bool remove_table_from_cache(THD *thd, const char *db, const char *table,
|
bool remove_table_from_cache(THD *thd, const char *db, const char *table,
|
||||||
bool return_if_owned_by_thd=0);
|
bool return_if_owned_by_thd);
|
||||||
bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables);
|
bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables);
|
||||||
void copy_field_from_tmp_record(Field *field,int offset);
|
void copy_field_from_tmp_record(Field *field,int offset);
|
||||||
bool fill_record(THD *thd, List<Item> &fields, List<Item> &values,
|
bool fill_record(THD *thd, List<Item> &fields, List<Item> &values,
|
||||||
@ -1170,7 +1171,7 @@ void unlock_table_name(THD *thd, TABLE_LIST *table_list);
|
|||||||
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
|
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
|
||||||
bool lock_table_names(THD *thd, TABLE_LIST *table_list);
|
bool lock_table_names(THD *thd, TABLE_LIST *table_list);
|
||||||
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
|
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
|
||||||
TABLE_LIST *last_table= 0);
|
TABLE_LIST *last_table);
|
||||||
|
|
||||||
|
|
||||||
/* old unireg functions */
|
/* old unireg functions */
|
||||||
|
@ -650,8 +650,10 @@ int imerge_list_or_tree(PARAM *param,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
||||||
table_map read_tables, COND *conds, int *error,
|
table_map read_tables, COND *conds,
|
||||||
bool allow_null_cond)
|
bool allow_null_cond,
|
||||||
|
int *error)
|
||||||
|
|
||||||
{
|
{
|
||||||
SQL_SELECT *select;
|
SQL_SELECT *select;
|
||||||
DBUG_ENTER("make_select");
|
DBUG_ENTER("make_select");
|
||||||
|
@ -633,7 +633,7 @@ void close_temporary_tables(THD *thd)
|
|||||||
table->s->table_name,"`,", NullS);
|
table->s->table_name,"`,", NullS);
|
||||||
}
|
}
|
||||||
next=table->next;
|
next=table->next;
|
||||||
close_temporary(table);
|
close_temporary(table, 1);
|
||||||
}
|
}
|
||||||
if (query && found_user_tables && mysql_bin_log.is_open())
|
if (query && found_user_tables && mysql_bin_log.is_open())
|
||||||
{
|
{
|
||||||
@ -798,7 +798,7 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name)
|
|||||||
return 1;
|
return 1;
|
||||||
table= *prev;
|
table= *prev;
|
||||||
*prev= table->next;
|
*prev= table->next;
|
||||||
close_temporary(table);
|
close_temporary(table, 1);
|
||||||
if (thd->slave_thread)
|
if (thd->slave_thread)
|
||||||
--slave_open_temp_tables;
|
--slave_open_temp_tables;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1606,7 +1606,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
|
|||||||
if (ha_create_table_from_engine(thd, db, name, TRUE) != 0)
|
if (ha_create_table_from_engine(thd, db, name, TRUE) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
mysql_reset_errors(thd, true); // Clear warnings
|
mysql_reset_errors(thd, 1); // Clear warnings
|
||||||
thd->clear_error(); // Clear error message
|
thd->clear_error(); // Clear error message
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
|
|
||||||
table->used_keys.clear_all();
|
table->used_keys.clear_all();
|
||||||
table->quick_keys.clear_all(); // Can't use 'only index'
|
table->quick_keys.clear_all(); // Can't use 'only index'
|
||||||
select=make_select(table,0,0,conds,&error);
|
select=make_select(table, 0, 0, conds, 0, &error);
|
||||||
if (error)
|
if (error)
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
|
if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
|
||||||
|
@ -80,7 +80,8 @@ void mysql_reset_errors(THD *thd, bool force)
|
|||||||
thd->warn_id= thd->query_id;
|
thd->warn_id= thd->query_id;
|
||||||
free_root(&thd->warn_root,MYF(0));
|
free_root(&thd->warn_root,MYF(0));
|
||||||
bzero((char*) thd->warn_count, sizeof(thd->warn_count));
|
bzero((char*) thd->warn_count, sizeof(thd->warn_count));
|
||||||
if (force) thd->total_warn_count= 0;
|
if (force)
|
||||||
|
thd->total_warn_count= 0;
|
||||||
thd->warn_list.empty();
|
thd->warn_list.empty();
|
||||||
thd->row_count= 1; // by default point to row 1
|
thd->row_count= 1; // by default point to row 1
|
||||||
}
|
}
|
||||||
@ -113,7 +114,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
if (thd->query_id != thd->warn_id)
|
if (thd->query_id != thd->warn_id)
|
||||||
mysql_reset_errors(thd);
|
mysql_reset_errors(thd, 0);
|
||||||
thd->got_warning= 1;
|
thd->got_warning= 1;
|
||||||
if (thd->spcont &&
|
if (thd->spcont &&
|
||||||
thd->spcont->find_handler(code,
|
thd->spcont->find_handler(code,
|
||||||
|
@ -562,7 +562,7 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
|
|||||||
/* Assume that no indexes cover all required fields */
|
/* Assume that no indexes cover all required fields */
|
||||||
table->used_keys.clear_all();
|
table->used_keys.clear_all();
|
||||||
|
|
||||||
SQL_SELECT *res= make_select(table,0,0,cond,error);
|
SQL_SELECT *res= make_select(table, 0, 0, cond, 0, error);
|
||||||
if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) ||
|
if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) ||
|
||||||
(res->quick && res->quick->reset()))
|
(res->quick && res->quick->reset()))
|
||||||
{
|
{
|
||||||
|
@ -1623,7 +1623,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
}
|
}
|
||||||
case COM_PREPARE:
|
case COM_PREPARE:
|
||||||
{
|
{
|
||||||
mysql_stmt_prepare(thd, packet, packet_length);
|
mysql_stmt_prepare(thd, packet, packet_length, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COM_CLOSE_STMT:
|
case COM_CLOSE_STMT:
|
||||||
@ -2261,7 +2261,7 @@ mysql_execute_command(THD *thd)
|
|||||||
*/
|
*/
|
||||||
if (all_tables || &lex->select_lex != lex->all_selects_list ||
|
if (all_tables || &lex->select_lex != lex->all_selects_list ||
|
||||||
lex->spfuns.records || lex->spprocs.records)
|
lex->spfuns.records || lex->spprocs.records)
|
||||||
mysql_reset_errors(thd);
|
mysql_reset_errors(thd, 0);
|
||||||
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
if (thd->slave_thread)
|
if (thd->slave_thread)
|
||||||
@ -2935,7 +2935,8 @@ unsent_create_error:
|
|||||||
lex->key_list,
|
lex->key_list,
|
||||||
select_lex->order_list.elements,
|
select_lex->order_list.elements,
|
||||||
(ORDER *) select_lex->order_list.first,
|
(ORDER *) select_lex->order_list.first,
|
||||||
lex->duplicates, lex->ignore, &lex->alter_info);
|
lex->duplicates, lex->ignore, &lex->alter_info,
|
||||||
|
1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3764,7 +3765,7 @@ unsent_create_error:
|
|||||||
if (check_db_used(thd, all_tables) ||
|
if (check_db_used(thd, all_tables) ||
|
||||||
check_table_access(thd, SELECT_ACL, all_tables, 0))
|
check_table_access(thd, SELECT_ACL, all_tables, 0))
|
||||||
goto error;
|
goto error;
|
||||||
res= mysql_ha_open(thd, first_table);
|
res= mysql_ha_open(thd, first_table, 0);
|
||||||
break;
|
break;
|
||||||
case SQLCOM_HA_CLOSE:
|
case SQLCOM_HA_CLOSE:
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
@ -4109,7 +4110,7 @@ unsent_create_error:
|
|||||||
sp= sp_find_procedure(thd, lex->spname);
|
sp= sp_find_procedure(thd, lex->spname);
|
||||||
else
|
else
|
||||||
sp= sp_find_function(thd, lex->spname);
|
sp= sp_find_function(thd, lex->spname);
|
||||||
mysql_reset_errors(thd);
|
mysql_reset_errors(thd, 0);
|
||||||
if (! sp)
|
if (! sp)
|
||||||
result= SP_KEY_NOT_FOUND;
|
result= SP_KEY_NOT_FOUND;
|
||||||
else
|
else
|
||||||
@ -4150,7 +4151,7 @@ unsent_create_error:
|
|||||||
sp= sp_find_procedure(thd, lex->spname);
|
sp= sp_find_procedure(thd, lex->spname);
|
||||||
else
|
else
|
||||||
sp= sp_find_function(thd, lex->spname);
|
sp= sp_find_function(thd, lex->spname);
|
||||||
mysql_reset_errors(thd);
|
mysql_reset_errors(thd, 0);
|
||||||
if (sp)
|
if (sp)
|
||||||
{
|
{
|
||||||
db= thd->strdup(sp->m_db.str);
|
db= thd->strdup(sp->m_db.str);
|
||||||
@ -6491,7 +6492,7 @@ bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
|
|||||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name,
|
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name,
|
||||||
&create_info, table_list,
|
&create_info, table_list,
|
||||||
fields, keys, 0, (ORDER*)0,
|
fields, keys, 0, (ORDER*)0,
|
||||||
DUP_ERROR, 0, &alter_info));
|
DUP_ERROR, 0, &alter_info, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6509,7 +6510,7 @@ bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info)
|
|||||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name,
|
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name,
|
||||||
&create_info, table_list,
|
&create_info, table_list,
|
||||||
fields, keys, 0, (ORDER*)0,
|
fields, keys, 0, (ORDER*)0,
|
||||||
DUP_ERROR, 0, alter_info));
|
DUP_ERROR, 0, alter_info, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1782,7 +1782,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
|
|||||||
thd->current_arena= stmt;
|
thd->current_arena= stmt;
|
||||||
mysql_init_query(thd, (uchar *) thd->query, thd->query_length);
|
mysql_init_query(thd, (uchar *) thd->query, thd->query_length);
|
||||||
/* Reset warnings from previous command */
|
/* Reset warnings from previous command */
|
||||||
mysql_reset_errors(thd);
|
mysql_reset_errors(thd, 0);
|
||||||
lex= thd->lex;
|
lex= thd->lex;
|
||||||
lex->safe_to_cache_query= 0;
|
lex->safe_to_cache_query= 0;
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
|
|||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_table_names(thd, table_list);
|
unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
@ -675,8 +675,8 @@ JOIN::optimize()
|
|||||||
/* Handle the case where we have an OUTER JOIN without a WHERE */
|
/* Handle the case where we have an OUTER JOIN without a WHERE */
|
||||||
conds=new Item_int((longlong) 1,1); // Always true
|
conds=new Item_int((longlong) 1,1); // Always true
|
||||||
}
|
}
|
||||||
select=make_select(*table, const_table_map,
|
select= make_select(*table, const_table_map,
|
||||||
const_table_map, conds, &error, true);
|
const_table_map, conds, 1, &error);
|
||||||
if (error)
|
if (error)
|
||||||
{ /* purecov: inspected */
|
{ /* purecov: inspected */
|
||||||
error= -1; /* purecov: inspected */
|
error= -1; /* purecov: inspected */
|
||||||
@ -2398,7 +2398,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||||||
select= make_select(s->table, found_const_table_map,
|
select= make_select(s->table, found_const_table_map,
|
||||||
found_const_table_map,
|
found_const_table_map,
|
||||||
*s->on_expr_ref ? *s->on_expr_ref : conds,
|
*s->on_expr_ref ? *s->on_expr_ref : conds,
|
||||||
&error, true);
|
1, &error);
|
||||||
if (!select)
|
if (!select)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
records= get_quick_record_count(join->thd, select, s->table,
|
records= get_quick_record_count(join->thd, select, s->table,
|
||||||
@ -12495,7 +12495,8 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
|
|||||||
error=(int) cond->add(join_tab->select->cond);
|
error=(int) cond->add(join_tab->select->cond);
|
||||||
join_tab->select_cond=join_tab->select->cond=cond;
|
join_tab->select_cond=join_tab->select->cond=cond;
|
||||||
}
|
}
|
||||||
else if ((join_tab->select=make_select(join_tab->table, 0, 0, cond,&error)))
|
else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
|
||||||
|
&error)))
|
||||||
join_tab->select_cond=cond;
|
join_tab->select_cond=cond;
|
||||||
|
|
||||||
DBUG_RETURN(error ? TRUE : FALSE);
|
DBUG_RETURN(error ? TRUE : FALSE);
|
||||||
|
@ -704,14 +704,17 @@ static void append_directory(THD *thd, String *packet, const char *dir_type,
|
|||||||
packet->append(dir_type);
|
packet->append(dir_type);
|
||||||
packet->append(" DIRECTORY='", 12);
|
packet->append(" DIRECTORY='", 12);
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
char *winfilename = thd->memdup(filename, length);
|
/* Convert \ to / to be able to create table on unix */
|
||||||
for (uint i=0; i < length; i++)
|
char *winfilename= (char*) thd->memdup(filename, length);
|
||||||
if (winfilename[i] == '\\')
|
char *pos, *end;
|
||||||
winfilename[i] = '/';
|
for (pos= winfilename, end= pos+length ; pos < end ; pos++)
|
||||||
packet->append(winfilename, length);
|
{
|
||||||
#else
|
if (*pos == '\\')
|
||||||
packet->append(filename, length);
|
*pos = '/';
|
||||||
|
}
|
||||||
|
filename= winfilename;
|
||||||
#endif
|
#endif
|
||||||
|
packet->append(filename, length);
|
||||||
packet->append('\'');
|
packet->append('\'');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -686,16 +686,16 @@ void String::qs_append(double *d)
|
|||||||
|
|
||||||
void String::qs_append(int i)
|
void String::qs_append(int i)
|
||||||
{
|
{
|
||||||
char *buff = Ptr + str_length;
|
char *buff= Ptr + str_length;
|
||||||
sprintf(buff,"%d", i);
|
char *end= int10_to_str(i, buff, -10);
|
||||||
str_length += strlen(buff);
|
str_length+= (int) (end-buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void String::qs_append(uint i)
|
void String::qs_append(uint i)
|
||||||
{
|
{
|
||||||
char *buff = Ptr + str_length;
|
char *buff= Ptr + str_length;
|
||||||
sprintf(buff,"%u", i);
|
char *end= int10_to_str(i, buff, 10);
|
||||||
str_length += strlen(buff);
|
str_length+= (int) (end-buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
280
sql/sql_table.cc
280
sql/sql_table.cc
@ -208,7 +208,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
if (!drop_temporary)
|
if (!drop_temporary)
|
||||||
{
|
{
|
||||||
abort_locked_tables(thd,db,table->table_name);
|
abort_locked_tables(thd,db,table->table_name);
|
||||||
while (remove_table_from_cache(thd,db,table->table_name) && !thd->killed)
|
while (remove_table_from_cache(thd, db, table->table_name, 0) &&
|
||||||
|
!thd->killed)
|
||||||
{
|
{
|
||||||
dropping_tables++;
|
dropping_tables++;
|
||||||
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
||||||
@ -291,7 +292,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_table_names(thd, tables);
|
unlock_table_names(thd, tables, (TABLE_LIST*) 0);
|
||||||
thd->no_warnings_for_error= 0;
|
thd->no_warnings_for_error= 0;
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
@ -451,150 +452,151 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int prepare_create_field(create_field *sql_field,
|
int prepare_create_field(create_field *sql_field,
|
||||||
uint &blob_columns,
|
uint *blob_columns,
|
||||||
int ×tamps, int ×tamps_with_niladic,
|
int *timestamps, int *timestamps_with_niladic,
|
||||||
uint table_flags)
|
uint table_flags)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("prepare_field");
|
DBUG_ENTER("prepare_field");
|
||||||
{
|
|
||||||
/* This code came from mysql_prepare_table.
|
|
||||||
Indent preserved to make patching easier */
|
|
||||||
DBUG_ASSERT(sql_field->charset);
|
|
||||||
|
|
||||||
switch (sql_field->sql_type) {
|
/*
|
||||||
case FIELD_TYPE_BLOB:
|
This code came from mysql_prepare_table.
|
||||||
case FIELD_TYPE_MEDIUM_BLOB:
|
Indent preserved to make patching easier
|
||||||
case FIELD_TYPE_TINY_BLOB:
|
*/
|
||||||
case FIELD_TYPE_LONG_BLOB:
|
DBUG_ASSERT(sql_field->charset);
|
||||||
sql_field->pack_flag=FIELDFLAG_BLOB |
|
|
||||||
pack_length_to_packflag(sql_field->pack_length -
|
switch (sql_field->sql_type) {
|
||||||
portable_sizeof_char_ptr);
|
case FIELD_TYPE_BLOB:
|
||||||
if (sql_field->charset->state & MY_CS_BINSORT)
|
case FIELD_TYPE_MEDIUM_BLOB:
|
||||||
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
case FIELD_TYPE_TINY_BLOB:
|
||||||
sql_field->length=8; // Unireg field length
|
case FIELD_TYPE_LONG_BLOB:
|
||||||
sql_field->unireg_check=Field::BLOB_FIELD;
|
sql_field->pack_flag=FIELDFLAG_BLOB |
|
||||||
blob_columns++;
|
pack_length_to_packflag(sql_field->pack_length -
|
||||||
break;
|
portable_sizeof_char_ptr);
|
||||||
case FIELD_TYPE_GEOMETRY:
|
if (sql_field->charset->state & MY_CS_BINSORT)
|
||||||
|
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
||||||
|
sql_field->length=8; // Unireg field length
|
||||||
|
sql_field->unireg_check=Field::BLOB_FIELD;
|
||||||
|
blob_columns++;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_GEOMETRY:
|
||||||
#ifdef HAVE_SPATIAL
|
#ifdef HAVE_SPATIAL
|
||||||
if (!(table_flags & HA_CAN_GEOMETRY))
|
if (!(table_flags & HA_CAN_GEOMETRY))
|
||||||
{
|
{
|
||||||
my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
|
my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
|
||||||
MYF(0), "GEOMETRY");
|
MYF(0), "GEOMETRY");
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
sql_field->pack_flag=FIELDFLAG_GEOM |
|
|
||||||
pack_length_to_packflag(sql_field->pack_length -
|
|
||||||
portable_sizeof_char_ptr);
|
|
||||||
if (sql_field->charset->state & MY_CS_BINSORT)
|
|
||||||
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
|
||||||
sql_field->length=8; // Unireg field length
|
|
||||||
sql_field->unireg_check=Field::BLOB_FIELD;
|
|
||||||
blob_columns++;
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
|
|
||||||
sym_group_geom.name, sym_group_geom.needed_define);
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
sql_field->pack_flag=FIELDFLAG_GEOM |
|
||||||
|
pack_length_to_packflag(sql_field->pack_length -
|
||||||
|
portable_sizeof_char_ptr);
|
||||||
|
if (sql_field->charset->state & MY_CS_BINSORT)
|
||||||
|
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
||||||
|
sql_field->length=8; // Unireg field length
|
||||||
|
sql_field->unireg_check=Field::BLOB_FIELD;
|
||||||
|
blob_columns++;
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
|
||||||
|
sym_group_geom.name, sym_group_geom.needed_define);
|
||||||
|
DBUG_RETURN(1);
|
||||||
#endif /*HAVE_SPATIAL*/
|
#endif /*HAVE_SPATIAL*/
|
||||||
case MYSQL_TYPE_VARCHAR:
|
case MYSQL_TYPE_VARCHAR:
|
||||||
#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
|
#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
|
||||||
if (table_flags & HA_NO_VARCHAR)
|
if (table_flags & HA_NO_VARCHAR)
|
||||||
|
{
|
||||||
|
/* convert VARCHAR to CHAR because handler is not yet up to date */
|
||||||
|
sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
|
||||||
|
sql_field->pack_length= calc_pack_length(sql_field->sql_type,
|
||||||
|
(uint) sql_field->length);
|
||||||
|
if ((sql_field->length / sql_field->charset->mbmaxlen) >
|
||||||
|
MAX_FIELD_CHARLENGTH)
|
||||||
{
|
{
|
||||||
/* convert VARCHAR to CHAR because handler is not yet up to date */
|
my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
|
||||||
sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
|
MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
|
||||||
sql_field->pack_length= calc_pack_length(sql_field->sql_type,
|
|
||||||
(uint) sql_field->length);
|
|
||||||
if ((sql_field->length / sql_field->charset->mbmaxlen) >
|
|
||||||
MAX_FIELD_CHARLENGTH)
|
|
||||||
{
|
|
||||||
my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
|
|
||||||
MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* fall through */
|
|
||||||
case FIELD_TYPE_STRING:
|
|
||||||
sql_field->pack_flag=0;
|
|
||||||
if (sql_field->charset->state & MY_CS_BINSORT)
|
|
||||||
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_ENUM:
|
|
||||||
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
|
|
||||||
FIELDFLAG_INTERVAL;
|
|
||||||
if (sql_field->charset->state & MY_CS_BINSORT)
|
|
||||||
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
|
||||||
sql_field->unireg_check=Field::INTERVAL_FIELD;
|
|
||||||
check_duplicates_in_interval("ENUM",sql_field->field_name,
|
|
||||||
sql_field->interval,
|
|
||||||
sql_field->charset);
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_SET:
|
|
||||||
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
|
|
||||||
FIELDFLAG_BITFIELD;
|
|
||||||
if (sql_field->charset->state & MY_CS_BINSORT)
|
|
||||||
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
|
||||||
sql_field->unireg_check=Field::BIT_FIELD;
|
|
||||||
check_duplicates_in_interval("SET",sql_field->field_name,
|
|
||||||
sql_field->interval,
|
|
||||||
sql_field->charset);
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_DATE: // Rest of string types
|
|
||||||
case FIELD_TYPE_NEWDATE:
|
|
||||||
case FIELD_TYPE_TIME:
|
|
||||||
case FIELD_TYPE_DATETIME:
|
|
||||||
case FIELD_TYPE_NULL:
|
|
||||||
sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_BIT:
|
|
||||||
if (!(table_flags & HA_CAN_BIT_FIELD))
|
|
||||||
{
|
|
||||||
my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "BIT FIELD");
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
sql_field->pack_flag= FIELDFLAG_NUMBER;
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_NEWDECIMAL:
|
|
||||||
sql_field->pack_flag=(FIELDFLAG_NUMBER |
|
|
||||||
(sql_field->flags & UNSIGNED_FLAG ? 0 :
|
|
||||||
FIELDFLAG_DECIMAL) |
|
|
||||||
(sql_field->flags & ZEROFILL_FLAG ?
|
|
||||||
FIELDFLAG_ZEROFILL : 0) |
|
|
||||||
(sql_field->decimals << FIELDFLAG_DEC_SHIFT));
|
|
||||||
break;
|
|
||||||
case FIELD_TYPE_TIMESTAMP:
|
|
||||||
/* We should replace old TIMESTAMP fields with their newer analogs */
|
|
||||||
if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
|
|
||||||
{
|
|
||||||
if (!timestamps)
|
|
||||||
{
|
|
||||||
sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
|
|
||||||
timestamps_with_niladic++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sql_field->unireg_check= Field::NONE;
|
|
||||||
}
|
|
||||||
else if (sql_field->unireg_check != Field::NONE)
|
|
||||||
timestamps_with_niladic++;
|
|
||||||
|
|
||||||
timestamps++;
|
|
||||||
/* fall-through */
|
|
||||||
default:
|
|
||||||
sql_field->pack_flag=(FIELDFLAG_NUMBER |
|
|
||||||
(sql_field->flags & UNSIGNED_FLAG ? 0 :
|
|
||||||
FIELDFLAG_DECIMAL) |
|
|
||||||
(sql_field->flags & ZEROFILL_FLAG ?
|
|
||||||
FIELDFLAG_ZEROFILL : 0) |
|
|
||||||
f_settype((uint) sql_field->sql_type) |
|
|
||||||
(sql_field->decimals << FIELDFLAG_DEC_SHIFT));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (!(sql_field->flags & NOT_NULL_FLAG))
|
#endif
|
||||||
sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
|
/* fall through */
|
||||||
if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
|
case FIELD_TYPE_STRING:
|
||||||
sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
|
sql_field->pack_flag=0;
|
||||||
|
if (sql_field->charset->state & MY_CS_BINSORT)
|
||||||
|
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_ENUM:
|
||||||
|
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
|
||||||
|
FIELDFLAG_INTERVAL;
|
||||||
|
if (sql_field->charset->state & MY_CS_BINSORT)
|
||||||
|
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
||||||
|
sql_field->unireg_check=Field::INTERVAL_FIELD;
|
||||||
|
check_duplicates_in_interval("ENUM",sql_field->field_name,
|
||||||
|
sql_field->interval,
|
||||||
|
sql_field->charset);
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_SET:
|
||||||
|
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
|
||||||
|
FIELDFLAG_BITFIELD;
|
||||||
|
if (sql_field->charset->state & MY_CS_BINSORT)
|
||||||
|
sql_field->pack_flag|=FIELDFLAG_BINARY;
|
||||||
|
sql_field->unireg_check=Field::BIT_FIELD;
|
||||||
|
check_duplicates_in_interval("SET",sql_field->field_name,
|
||||||
|
sql_field->interval,
|
||||||
|
sql_field->charset);
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_DATE: // Rest of string types
|
||||||
|
case FIELD_TYPE_NEWDATE:
|
||||||
|
case FIELD_TYPE_TIME:
|
||||||
|
case FIELD_TYPE_DATETIME:
|
||||||
|
case FIELD_TYPE_NULL:
|
||||||
|
sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_BIT:
|
||||||
|
if (!(table_flags & HA_CAN_BIT_FIELD))
|
||||||
|
{
|
||||||
|
my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "BIT FIELD");
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
sql_field->pack_flag= FIELDFLAG_NUMBER;
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_NEWDECIMAL:
|
||||||
|
sql_field->pack_flag=(FIELDFLAG_NUMBER |
|
||||||
|
(sql_field->flags & UNSIGNED_FLAG ? 0 :
|
||||||
|
FIELDFLAG_DECIMAL) |
|
||||||
|
(sql_field->flags & ZEROFILL_FLAG ?
|
||||||
|
FIELDFLAG_ZEROFILL : 0) |
|
||||||
|
(sql_field->decimals << FIELDFLAG_DEC_SHIFT));
|
||||||
|
break;
|
||||||
|
case FIELD_TYPE_TIMESTAMP:
|
||||||
|
/* We should replace old TIMESTAMP fields with their newer analogs */
|
||||||
|
if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
|
||||||
|
{
|
||||||
|
if (!timestamps)
|
||||||
|
{
|
||||||
|
sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
|
||||||
|
timestamps_with_niladic++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sql_field->unireg_check= Field::NONE;
|
||||||
|
}
|
||||||
|
else if (sql_field->unireg_check != Field::NONE)
|
||||||
|
timestamps_with_niladic++;
|
||||||
|
|
||||||
|
timestamps++;
|
||||||
|
/* fall-through */
|
||||||
|
default:
|
||||||
|
sql_field->pack_flag=(FIELDFLAG_NUMBER |
|
||||||
|
(sql_field->flags & UNSIGNED_FLAG ? 0 :
|
||||||
|
FIELDFLAG_DECIMAL) |
|
||||||
|
(sql_field->flags & ZEROFILL_FLAG ?
|
||||||
|
FIELDFLAG_ZEROFILL : 0) |
|
||||||
|
f_settype((uint) sql_field->sql_type) |
|
||||||
|
(sql_field->decimals << FIELDFLAG_DEC_SHIFT));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (!(sql_field->flags & NOT_NULL_FLAG))
|
||||||
|
sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
|
||||||
|
if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
|
||||||
|
sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,8 +859,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(sql_field->charset != 0);
|
DBUG_ASSERT(sql_field->charset != 0);
|
||||||
|
|
||||||
if (prepare_create_field(sql_field, blob_columns,
|
if (prepare_create_field(sql_field, &blob_columns,
|
||||||
timestamps, timestamps_with_niladic,
|
×tamps, ×tamps_with_niladic,
|
||||||
file->table_flags()))
|
file->table_flags()))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if (sql_field->sql_type == FIELD_TYPE_BLOB ||
|
if (sql_field->sql_type == FIELD_TYPE_BLOB ||
|
||||||
@ -1765,7 +1767,7 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
|
|||||||
mysql_lock_abort(thd, table); // end threads waiting on lock
|
mysql_lock_abort(thd, table); // end threads waiting on lock
|
||||||
|
|
||||||
/* Wait until all there are no other threads that has this table open */
|
/* Wait until all there are no other threads that has this table open */
|
||||||
while (remove_table_from_cache(thd, table->s->db, table->s->table_name))
|
while (remove_table_from_cache(thd, table->s->db, table->s->table_name, 0))
|
||||||
{
|
{
|
||||||
dropping_tables++;
|
dropping_tables++;
|
||||||
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
||||||
@ -2134,7 +2136,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
"Waiting to get writelock");
|
"Waiting to get writelock");
|
||||||
mysql_lock_abort(thd,table->table);
|
mysql_lock_abort(thd,table->table);
|
||||||
while (remove_table_from_cache(thd, table->table->s->db,
|
while (remove_table_from_cache(thd, table->table->s->db,
|
||||||
table->table->s->table_name) &&
|
table->table->s->table_name, 0) &&
|
||||||
! thd->killed)
|
! thd->killed)
|
||||||
{
|
{
|
||||||
dropping_tables++;
|
dropping_tables++;
|
||||||
@ -2249,7 +2251,7 @@ send_result_message:
|
|||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
remove_table_from_cache(thd, table->table->s->db,
|
remove_table_from_cache(thd, table->table->s->db,
|
||||||
table->table->s->table_name);
|
table->table->s->table_name, 0);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
/* May be something modified consequently we have to invalidate cache */
|
/* May be something modified consequently we have to invalidate cache */
|
||||||
query_cache_invalidate3(thd, table->table, 0);
|
query_cache_invalidate3(thd, table->table, 0);
|
||||||
@ -3558,7 +3560,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file
|
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file
|
||||||
remove_table_from_cache(thd,db,table_name); // Mark all in-use copies old
|
remove_table_from_cache(thd,db,table_name, 0); // Mark in-use copies old
|
||||||
mysql_lock_abort(thd,table); // end threads waiting on lock
|
mysql_lock_abort(thd,table); // end threads waiting on lock
|
||||||
}
|
}
|
||||||
VOID(quick_rm_table(old_db_type,db,old_name));
|
VOID(quick_rm_table(old_db_type,db,old_name));
|
||||||
|
@ -229,7 +229,7 @@ int mysql_update(THD *thd,
|
|||||||
|
|
||||||
// Don't count on usage of 'only index' when calculating which key to use
|
// Don't count on usage of 'only index' when calculating which key to use
|
||||||
table->used_keys.clear_all();
|
table->used_keys.clear_all();
|
||||||
select=make_select(table,0,0,conds,&error);
|
select= make_select(table, 0, 0, conds, 0, &error);
|
||||||
if (error ||
|
if (error ||
|
||||||
(select && select->check_quick(thd, safe_update, limit)) || !limit)
|
(select && select->check_quick(thd, safe_update, limit)) || !limit)
|
||||||
{
|
{
|
||||||
|
@ -1386,14 +1386,18 @@ create_function_tail:
|
|||||||
uint unused1= 0;
|
uint unused1= 0;
|
||||||
int unused2= 0;
|
int unused2= 0;
|
||||||
|
|
||||||
if (!(new_field= new_create_field(YYTHD, "", (enum enum_field_types)$8,
|
if (!(new_field= new_create_field(YYTHD, "",
|
||||||
lex->length, lex->dec, lex->type,
|
(enum enum_field_types)$8,
|
||||||
(Item *)0, (Item *) 0, &cmt, 0, &lex->interval_list,
|
lex->length, lex->dec, lex->type,
|
||||||
(lex->charset ? lex->charset : default_charset_info),
|
(Item *)0, (Item *) 0, &cmt, 0,
|
||||||
lex->uint_geom_type)))
|
&lex->interval_list,
|
||||||
|
(lex->charset ? lex->charset :
|
||||||
|
default_charset_info),
|
||||||
|
lex->uint_geom_type)))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
|
|
||||||
if (prepare_create_field(new_field, unused1, unused2, unused2, 0))
|
if (prepare_create_field(new_field, &unused1, &unused2, &unused2,
|
||||||
|
0))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
|
|
||||||
sp->m_returns= new_field->sql_type;
|
sp->m_returns= new_field->sql_type;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user