Commit afd8f38f authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Optimized GIS functions

parent 3baf20ab
...@@ -60,9 +60,11 @@ int heap_delete(HP_INFO *info, const byte *record) ...@@ -60,9 +60,11 @@ int heap_delete(HP_INFO *info, const byte *record)
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
} }
/* /*
Remove one key from rb-tree Remove one key from rb-tree
*/ */
int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
const byte *record, byte *recpos, int flag) const byte *record, byte *recpos, int flag)
{ {
...@@ -82,11 +84,25 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, ...@@ -82,11 +84,25 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
return res; return res;
} }
/* Remove one key from hash-table */
/* Flag is set if we want's to correct info->current_ptr */ /*
Remove one key from hash-table
SYNPOSIS
hp_delete_key()
info Hash handler
keyinfo key definition of key that we want to delete
record row data to be deleted
recpos Pointer to heap record in memory
flag Is set if we want's to correct info->current_ptr
RETURN
0 ok
# error number
*/
int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
const byte *record, byte *recpos, int flag) const byte *record, byte *recpos, int flag)
{ {
ulong blength,pos2,pos_hashnr,lastpos_hashnr; ulong blength,pos2,pos_hashnr,lastpos_hashnr;
HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr; HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr;
......
This diff is collapsed.
...@@ -359,9 +359,9 @@ delete from t2 where b=3; ...@@ -359,9 +359,9 @@ delete from t2 where b=3;
delete from t3 where a=3; delete from t3 where a=3;
show table status; show table status;
Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP Fixed 4 5 39904 249415 105 5 NULL NULL NULL NULL latin1_swedish_ci NULL t1 HEAP Fixed 4 5 39904 249415 89 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP Fixed 4 5 39904 249415 39904 5 NULL NULL NULL NULL latin1_swedish_ci NULL t2 HEAP Fixed 4 5 39904 249415 39904 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP Fixed 4 9 33072 248103 22153 9 NULL NULL NULL NULL latin1_swedish_ci NULL t3 HEAP Fixed 4 9 33072 248103 22137 9 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1; delete from t1;
delete from t2; delete from t2;
delete from t3; delete from t3;
...@@ -383,7 +383,7 @@ delete from t2 where b=5; ...@@ -383,7 +383,7 @@ delete from t2 where b=5;
delete from t3 where a=5; delete from t3 where a=5;
show table status; show table status;
Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP Fixed 0 5 39904 249415 21 5 NULL NULL NULL NULL latin1_swedish_ci NULL t1 HEAP Fixed 0 5 39904 249415 5 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP Fixed 0 5 39904 249415 39904 5 NULL NULL NULL NULL latin1_swedish_ci NULL t2 HEAP Fixed 0 5 39904 249415 39904 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP Fixed 0 9 33072 248103 22069 9 NULL NULL NULL NULL latin1_swedish_ci NULL t3 HEAP Fixed 0 9 33072 248103 22053 9 NULL NULL NULL NULL latin1_swedish_ci NULL
drop table t1, t2, t3; drop table t1, t2, t3;
This diff is collapsed.
...@@ -215,9 +215,9 @@ static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length) ...@@ -215,9 +215,9 @@ static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length)
{ {
uint rec_keylength; uint rec_keylength;
byte *rec_key= (byte*) hash_key(hash,pos->data,&rec_keylength,1); byte *rec_key= (byte*) hash_key(hash,pos->data,&rec_keylength,1);
return (length && length != rec_keylength) || return ((length && length != rec_keylength) ||
my_strnncoll(hash->charset, (uchar*) rec_key, rec_keylength, my_strnncoll(hash->charset, (uchar*) rec_key, rec_keylength,
(uchar*) key, length); (uchar*) key, length));
} }
......
...@@ -170,8 +170,8 @@ void delete_tree(TREE* tree) ...@@ -170,8 +170,8 @@ void delete_tree(TREE* tree)
void reset_tree(TREE* tree) void reset_tree(TREE* tree)
{ {
/* do not free mem_root, just mark blocks as free */
free_tree(tree, MYF(MY_MARK_BLOCKS_FREE)); free_tree(tree, MYF(MY_MARK_BLOCKS_FREE));
/* do not my_free() mem_root if applicable, just mark blocks as free */
} }
...@@ -188,10 +188,14 @@ static void delete_tree_element(TREE *tree, TREE_ELEMENT *element) ...@@ -188,10 +188,14 @@ static void delete_tree_element(TREE *tree, TREE_ELEMENT *element)
} }
} }
/* Code for insert, search and delete of elements */
/* parent[0] = & parent[-1][0]->left ||
parent[0] = & parent[-1][0]->right */
/*
insert, search and delete of elements
The following should be true:
parent[0] = & parent[-1][0]->left ||
parent[0] = & parent[-1][0]->right
*/
TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size, TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size,
void* custom_arg) void* custom_arg)
...@@ -232,8 +236,7 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size, ...@@ -232,8 +236,7 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size,
if (tree->with_delete) if (tree->with_delete)
element=(TREE_ELEMENT *) my_malloc(alloc_size, MYF(MY_WME)); element=(TREE_ELEMENT *) my_malloc(alloc_size, MYF(MY_WME));
else else
element=(TREE_ELEMENT *) element=(TREE_ELEMENT *) alloc_root(&tree->mem_root,alloc_size);
alloc_root(&tree->mem_root,alloc_size);
if (!element) if (!element)
return(NULL); return(NULL);
**parent=element; **parent=element;
...@@ -251,9 +254,9 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size, ...@@ -251,9 +254,9 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size,
} }
else else
memcpy((byte*) element+tree->offset_to_key,key,(size_t) key_size); memcpy((byte*) element+tree->offset_to_key,key,(size_t) key_size);
element->count=1; /* May give warning in purify */ element->count=1; /* May give warning in purify */
tree->elements_in_tree++; tree->elements_in_tree++;
rb_insert(tree,parent,element); /* rebalance tree */ rb_insert(tree,parent,element); /* rebalance tree */
} }
else else
{ {
...@@ -320,6 +323,8 @@ int tree_delete(TREE *tree, void *key, void *custom_arg) ...@@ -320,6 +323,8 @@ int tree_delete(TREE *tree, void *key, void *custom_arg)
rb_delete_fixup(tree,parent); rb_delete_fixup(tree,parent);
if (tree->free) if (tree->free)
(*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg); (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
/* This doesn't include key_size, but better than nothing */
tree->allocated-= sizeof(TREE_ELEMENT)+tree->size_of_element;
my_free((gptr) element,MYF(0)); my_free((gptr) element,MYF(0));
tree->elements_in_tree--; tree->elements_in_tree--;
return 0; return 0;
......
...@@ -4715,18 +4715,26 @@ void Field_blob::get_key_image(char *buff,uint length, ...@@ -4715,18 +4715,26 @@ void Field_blob::get_key_image(char *buff,uint length,
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
if (type == itMBR) if (type == itMBR)
{ {
if (!blob_length) const char *dummy;
return;
get_ptr(&blob);
MBR mbr; MBR mbr;
Geometry gobj; Geometry gobj;
if (blob_length < SRID_SIZE)
{
bzero(buff, SIZEOF_STORED_DOUBLE*4);
return;
}
get_ptr(&blob);
gobj.create_from_wkb(blob + SRID_SIZE, blob_length - SRID_SIZE); gobj.create_from_wkb(blob + SRID_SIZE, blob_length - SRID_SIZE);
gobj.get_mbr(&mbr); if (gobj.get_mbr(&mbr, &dummy))
float8store(buff, mbr.xmin); bzero(buff, SIZEOF_STORED_DOUBLE*4);
float8store(buff+8, mbr.xmax); else
float8store(buff+16, mbr.ymin); {
float8store(buff+24, mbr.ymax); float8store(buff, mbr.xmin);
float8store(buff+8, mbr.xmax);
float8store(buff+16, mbr.ymin);
float8store(buff+24, mbr.ymax);
}
return; return;
} }
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
...@@ -4939,6 +4947,7 @@ uint Field_blob::max_packed_col_length(uint max_length) ...@@ -4939,6 +4947,7 @@ uint Field_blob::max_packed_col_length(uint max_length)
return (max_length > 255 ? 2 : 1)+max_length; return (max_length > 255 ? 2 : 1)+max_length;
} }
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs, void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
...@@ -4947,17 +4956,26 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs, ...@@ -4947,17 +4956,26 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
length-= HA_KEY_BLOB_LENGTH; length-= HA_KEY_BLOB_LENGTH;
ulong blob_length= get_length(ptr); ulong blob_length= get_length(ptr);
char *blob; char *blob;
get_ptr(&blob); const char *dummy;
MBR mbr; MBR mbr;
if (blob_length < SRID_SIZE)
{
bzero(buff, SIZEOF_STORED_DOUBLE*4);
return;
}
get_ptr(&blob);
Geometry gobj; Geometry gobj;
gobj.create_from_wkb(blob + SRID_SIZE, blob_length - SRID_SIZE); gobj.create_from_wkb(blob + SRID_SIZE, blob_length - SRID_SIZE);
gobj.get_mbr(&mbr); if (gobj.get_mbr(&mbr, &dummy))
float8store(buff, mbr.xmin); bzero(buff, SIZEOF_STORED_DOUBLE*4);
float8store(buff + 8, mbr.xmax); else
float8store(buff + 16, mbr.ymin); {
float8store(buff + 24, mbr.ymax); float8store(buff, mbr.xmin);
return; float8store(buff + 8, mbr.xmax);
float8store(buff + 16, mbr.ymin);
float8store(buff + 24, mbr.ymax);
}
} }
...@@ -5001,16 +5019,16 @@ void Field_geom::sql_type(String &res) const ...@@ -5001,16 +5019,16 @@ void Field_geom::sql_type(String &res) const
int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
{ {
if (!length) if (!length)
{
bzero(ptr, Field_blob::pack_length()); bzero(ptr, Field_blob::pack_length());
}
else else
{ {
// Should check given WKB // Check given WKB
if (length < 4 + 1 + 4 + 8 + 8) // SRID + WKB_HEADER + X + Y uint32 wkb_type;
return 1; if (length < SRID_SIZE + WKB_HEADER_SIZE + SIZEOF_STORED_DOUBLE*2)
uint32 wkb_type= uint4korr(from + 5); goto err;
if (wkb_type < 1 || wkb_type > 7) wkb_type= uint4korr(from + WKB_HEADER_SIZE);
if (wkb_type < (uint32) Geometry::wkbPoint ||
wkb_type > (uint32) Geometry::wkb_end)
return 1; return 1;
Field_blob::store_length(length); Field_blob::store_length(length);
if (table->copy_blobs || length <= MAX_FIELD_WIDTH) if (table->copy_blobs || length <= MAX_FIELD_WIDTH)
...@@ -5021,6 +5039,10 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) ...@@ -5021,6 +5039,10 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
bmove(ptr + packlength, (char*) &from, sizeof(char*)); bmove(ptr + packlength, (char*) &from, sizeof(char*));
} }
return 0; return 0;
err:
bzero(ptr, Field_blob::pack_length());
return 1;
} }
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
......
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Functions to read and parse geometrical data.
NOTE: These functions assumes that the string is end \0 terminated!
*/
#include "mysql_priv.h" #include "mysql_priv.h"
int GTextReadStream::get_next_toc_type() const enum Gis_read_stream::enum_tok_types Gis_read_stream::get_next_toc_type()
{ {
const char *cur = m_cur; skip_space();
while ((*cur)&&(strchr(" \t\r\n",*cur))) if (!*m_cur)
{
cur++;
}
if (!(*cur))
{
return eostream; return eostream;
} if (my_isvar_start(&my_charset_bin, *m_cur))
if (((*cur>='a') && (*cur<='z')) || ((*cur>='A') && (*cur<='Z')) ||
(*cur=='_'))
{
return word; return word;
} if ((*m_cur >= '0' && *m_cur <= '9') || *m_cur == '-' || *m_cur == '+')
if (((*cur>='0') && (*cur<='9')) || (*cur=='-') || (*cur=='+') ||
(*cur=='.'))
{
return numeric; return numeric;
} if (*m_cur == '(')
if (*cur == '(')
{
return l_bra; return l_bra;
} if (*m_cur == ')')
if (*cur == ')')
{
return r_bra; return r_bra;
} if (*m_cur == ',')
if (*cur == ',')
{
return comma; return comma;
}
return unknown; return unknown;
} }
const char *GTextReadStream::get_next_word(int *word_len)
{
const char *cur = m_cur;
while ((*cur)&&(strchr(" \t\r\n",*cur)))
{
cur++;
}
m_last_text_position = cur;
if (!(*cur))
{
return 0;
}
const char *wd_start = cur; bool Gis_read_stream::get_next_word(LEX_STRING *res)
{
if (((*cur<'a') || (*cur>'z')) && ((*cur<'A') || (*cur>'Z')) && (*cur!='_')) skip_space();
{ res->str= (char*) m_cur;
return NULL; /* The following will also test for \0 */
} if (!my_isvar_start(&my_charset_bin, *m_cur))
return 1;
++cur; /*
We can't combine the following increment with my_isvar() because
my_isvar() is a macro that would cause side effects
*/
m_cur++;
while (my_isvar(&my_charset_bin, *m_cur))
m_cur++;
while (((*cur>='a') && (*cur<='z')) || ((*cur>='A') && (*cur<='Z')) || res->length= (uint32) (m_cur - res->str);
(*cur=='_') || ((*cur>='0') && (*cur<='9'))) return 0;
{ }
++cur;
}
*word_len = cur - wd_start;
m_cur = cur; /*
Read a floating point number
return wd_start; NOTE: Number must start with a digit or sign. It can't start with a decimal
} point
*/
int GTextReadStream::get_next_number(double *d) bool Gis_read_stream::get_next_number(double *d)
{ {
const char *cur = m_cur; char *endptr;
while ((*cur)&&(strchr(" \t\r\n",*cur)))
{
cur++;
}
m_last_text_position = cur;
if (!(*cur))
{
set_error_msg("Numeric constant expected");
return 1;
}
if (((*cur<'0') || (*cur>'9')) && (*cur!='-') && (*cur!='+') && (*cur!='.')) skip_space();
/* The following will also test for end \0 */
if ((*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+')
{ {
set_error_msg("Numeric constant expected"); set_error_msg("Numeric constant expected");
return 1; return 1;
} }
char *endptr; *d = my_strtod(m_cur, &endptr);
*d = my_strtod(cur, &endptr);
if (endptr) if (endptr)
{
m_cur = endptr; m_cur = endptr;
}
return 0; return 0;
} }
char GTextReadStream::get_next_symbol()
bool Gis_read_stream::check_next_symbol(char symbol)
{ {
const char *cur = m_cur; skip_space();
while ((*cur)&&(strchr(" \t\r\n",*cur))) if (*m_cur != symbol)
{ {
cur++; char buff[32];
} strmov(buff, "'?' expected");
if (!(*cur)) buff[2]= symbol;
{ set_error_msg(buff);
return 0; return 1;
} }
m_cur++;
return 0;
}
m_cur = cur + 1;
m_last_text_position = cur;
return *cur; /*
} Remember error message.
*/
void GTextReadStream::set_error_msg(const char *msg) void Gis_read_stream::set_error_msg(const char *msg)
{ {
size_t len = strlen(msg); size_t len= strlen(msg); // ok in this context
m_err_msg = (char *)my_realloc(m_err_msg, len + 1, MYF(MY_ALLOW_ZERO_PTR)); m_err_msg= (char *) my_realloc(m_err_msg, len + 1, MYF(MY_ALLOW_ZERO_PTR));
memcpy(m_err_msg, msg, len + 1); memcpy(m_err_msg, msg, len + 1);
} }
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
class GTextReadStream class Gis_read_stream
{ {
public: public:
enum TokTypes enum enum_tok_types
{ {
unknown, unknown,
eostream, eostream,
...@@ -29,41 +29,47 @@ class GTextReadStream ...@@ -29,41 +29,47 @@ class GTextReadStream
comma comma
}; };
GTextReadStream(const char *buffer, int size) Gis_read_stream(const char *buffer, int size)
:m_cur(buffer), m_limit(buffer + size), m_last_text_position(buffer), :m_cur(buffer), m_limit(buffer + size), m_err_msg(NULL)
m_err_msg(NULL)
{} {}
GTextReadStream(): m_cur(NULL), m_limit(NULL), m_err_msg(NULL) Gis_read_stream(): m_cur(NullS), m_limit(NullS), m_err_msg(NullS)
{} {}
~Gis_read_stream()
~GTextReadStream()
{ {
my_free(m_err_msg, MYF(MY_ALLOW_ZERO_PTR)); my_free(m_err_msg, MYF(MY_ALLOW_ZERO_PTR));
} }
int get_next_toc_type() const; enum enum_tok_types get_next_toc_type();
const char *get_next_word(int *word_len); bool get_next_word(LEX_STRING *);
int get_next_number(double *d); bool get_next_number(double *);
char get_next_symbol(); bool check_next_symbol(char);
const char *get_last_text_position() const inline void skip_space()
{ {
return m_last_text_position; while (my_isspace(&my_charset_latin1, *m_cur))
m_cur++;
}
/* Skip next character, if match. Return 1 if no match */
inline bool skip_char(char skip)
{
skip_space();
if (*m_cur != skip)
return 1; /* Didn't find char */
m_cur++;
return 0;
} }
void set_error_msg(const char *msg); void set_error_msg(const char *msg);
// caller should free this pointer // caller should free this pointer
char *get_error_msg() char *get_error_msg()
{ {
char *err_msg = m_err_msg; char *err_msg = m_err_msg;
m_err_msg = NULL; m_err_msg= NullS;
return err_msg; return err_msg;
} }
protected: protected:
const char *m_cur; const char *m_cur;
const char *m_limit; const char *m_limit;
const char *m_last_text_position;
char *m_err_msg; char *m_err_msg;
}; };
...@@ -455,6 +455,7 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len, ...@@ -455,6 +455,7 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len,
{ {
Item *res; Item *res;
LINT_INIT(res); LINT_INIT(res);
switch (cast_type) { switch (cast_type) {
case ITEM_CAST_BINARY: res= new Item_func_binary(a); break; case ITEM_CAST_BINARY: res= new Item_func_binary(a); break;
case ITEM_CAST_SIGNED_INT: res= new Item_func_signed(a); break; case ITEM_CAST_SIGNED_INT: res= new Item_func_signed(a); break;
......
This diff is collapsed.
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
#pragma interface /* gcc class implementation */ #pragma interface /* gcc class implementation */
#endif #endif
#define SRID_SIZE sizeof(uint32)
class Item_func_geometry_from_text: public Item_str_func class Item_func_geometry_from_text: public Item_str_func
{ {
public: public:
......
This diff is collapsed.
This diff is collapsed.
...@@ -126,8 +126,8 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs) ...@@ -126,8 +126,8 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs)
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);
} }
#ifdef HAVE_FCONVERT #ifdef HAVE_FCONVERT
int decpt,sign; int decpt,sign;
...@@ -671,9 +671,8 @@ int String::reserve(uint32 space_needed, uint32 grow_by) ...@@ -671,9 +671,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 = strlen(str);
memcpy(Ptr + str_length, str, len + 1); memcpy(Ptr + str_length, str, len + 1);
str_length += len; str_length += len;
} }
...@@ -681,8 +680,7 @@ void String::qs_append(const char *str) ...@@ -681,8 +680,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 += strlen(buff);
} }
void String::qs_append(double *d) void String::qs_append(double *d)
...@@ -692,12 +690,6 @@ void String::qs_append(double *d) ...@@ -692,12 +690,6 @@ void String::qs_append(double *d)
qs_append(ld); qs_append(ld);
} }
void String::qs_append(const char &c)
{
Ptr[str_length] = c;
str_length += sizeof(c);
}
/* /*
Compare strings according to collation, without end space. Compare strings according to collation, without end space.
......
...@@ -237,7 +237,7 @@ class String ...@@ -237,7 +237,7 @@ class String
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;
} }
...@@ -262,15 +262,19 @@ class String ...@@ -262,15 +262,19 @@ class String
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++;
}
/* Inline (general) functions used by the protocol functions */ /* Inline (general) functions used by the protocol functions */
......
...@@ -20,11 +20,21 @@ ...@@ -20,11 +20,21 @@
struct st_table; struct st_table;
class Field; class Field;
typedef struct lex_string { typedef struct st_lex_string
{
char *str; char *str;
uint length; uint length;
} LEX_STRING; } LEX_STRING;
typedef struct st_lex_string_with_init :public st_lex_string
{
st_lex_string_with_init(const char *str_arg, uint length_arg)
{
str= (char*) str_arg;
length= length_arg;
}
} LEX_STRING_WITH_INIT;
typedef struct st_date_time_format { typedef struct st_date_time_format {
uchar positions[8]; uchar positions[8];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment