Cleanup during reviews

Removed some optional arguments
Fixed portability problem in federated tests
This commit is contained in:
monty@mysql.com 2005-03-16 16:11:01 +02:00
parent 8e54dece31
commit 594ef41b2d
26 changed files with 795 additions and 474 deletions

View File

@ -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);
}

View File

@ -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);
}
}; };

View File

@ -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 ''

View File

@ -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, &not_used)) if (String::needs_conversion(length, cs, field_charset, &not_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)

View File

@ -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);

View File

@ -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);
} }

View File

@ -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

View File

@ -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
{ {

View File

@ -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:

View File

@ -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);
} }

View File

@ -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));

View File

@ -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 &timestamps, int &timestamps_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 */

View File

@ -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");

View File

@ -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;
} }

View File

@ -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)

View File

@ -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,

View File

@ -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()))
{ {

View File

@ -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));
} }

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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('\'');
} }
} }

View File

@ -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);
} }
/* /*

View File

@ -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 &timestamps, int &timestamps_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, &timestamps, &timestamps_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));

View File

@ -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)
{ {

View File

@ -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;