mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
90104181f9
Fixes for RENAME TABLE Portability fixes Docs/manual.texi: FLUSH TABLES table_list client/mysql.cc: Ia64 port client/mysqladmin.c: Ia64 port client/mysqldump.c: Ia64 port client/mysqlimport.c: Ia64 port client/mysqlshow.c: Ia64 port client/readline.cc: Ia64 port configure.in: Ia64 port include/config-win.h: Ia64 port include/thr_alarm.h: Ia64 port myisam/myisamdef.h: Ia64 port myisammrg/myrg_rkey.c: Ia64 port mysys/thr_alarm.c: Easier compile of non threaded client mysys/thr_lock.c: Easier compile of non threaded client mysys/thr_mutex.c: Easier compile of non threaded client sql-bench/crash-me.sh: Added test for RENAME + some ANSI SQL99 group functions sql-bench/limits/mysql.cfg: New run sql-bench/server-cfg.sh: Fix sql-bench/test-insert.sh: Fix sql/field.cc: Port to Ia64 sql/ha_berkeley.cc: Port to Ia64 sql/ha_myisam.cc: cleanup sql/handler.cc: Port to Ia64 sql/hostname.cc: Port to Ia64 sql/item.cc: Port to Ia64 sql/item_create.cc: Port to Ia64 sql/item_func.cc: Port to Ia64 sql/item_strfunc.cc: Port to Ia64 sql/item_timefunc.cc: Port to Ia64 sql/lock.cc: Fix for RENAME sql/log.cc: Port to Ia64 sql/log_event.h: Port to Ia64 sql/mini_client.cc: Port to Ia64 sql/mysql_priv.h: Port to Ia64 sql/mysqlbinlog.cc: Port to Ia64 sql/mysqld.cc: FLUSH TABLES table_list sql/net_pkg.cc: Port to Ia64 sql/procedure.h: Port to Ia64 sql/share/swedish/errmsg.OLD: FLUSH TABLES table_list sql/slave.cc: Port to Ia64 sql/sql_acl.cc: Port to Ia64 sql/sql_analyse.cc: Port to Ia64 sql/sql_analyse.h: Port to Ia64 sql/sql_base.cc: FLUSH TABLES table_list sql/sql_class.cc: Port to Ia64 sql/sql_class.h: Port to Ia64 sql/sql_parse.cc: Port to Ia64 sql/sql_rename.cc: Fix of RENAME sql/sql_show.cc: Port to Ia64 sql/sql_string.cc: Port to Ia64 sql/sql_string.h: Port to Ia64 sql/sql_table.cc: Fix of RENAME sql/sql_udf.cc: Port to Ia64 sql/sql_yacc.yy: FLUSH TABLES table_list sql/table.cc: Port to Ia64 sql/thr_malloc.cc: Port to Ia64 sql/time.cc: Port to Ia64 sql/unireg.cc: Port to Ia64
329 lines
7.8 KiB
C++
329 lines
7.8 KiB
C++
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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 */
|
|
|
|
|
|
#include "mysql_priv.h"
|
|
#include <stdarg.h>
|
|
|
|
/* Send a error string to client */
|
|
|
|
void send_error(NET *net, uint sql_errno, const char *err)
|
|
{
|
|
uint length;
|
|
char buff[MYSQL_ERRMSG_SIZE+2];
|
|
THD *thd=current_thd;
|
|
DBUG_ENTER("send_error");
|
|
DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno,
|
|
err ? err : net->last_error[0] ?
|
|
net->last_error : "NULL"));
|
|
|
|
if (thd)
|
|
thd->query_error = 1; // needed to catch query errors during replication
|
|
if (!err)
|
|
{
|
|
if (sql_errno)
|
|
err=ER(sql_errno);
|
|
else if (!err)
|
|
{
|
|
if ((err=net->last_error)[0])
|
|
sql_errno=net->last_errno;
|
|
else
|
|
{
|
|
sql_errno=ER_UNKNOWN_ERROR;
|
|
err=ER(sql_errno); /* purecov: inspected */
|
|
}
|
|
}
|
|
}
|
|
if (net->vio == 0)
|
|
{
|
|
if (thd && thd->bootstrap)
|
|
{
|
|
fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
|
|
}
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
if (net->return_errno)
|
|
{ // new client code; Add errno before message
|
|
int2store(buff,sql_errno);
|
|
length= (uint) (strmake(buff+2,err,MYSQL_ERRMSG_SIZE-1) - buff);
|
|
err=buff;
|
|
}
|
|
else
|
|
{
|
|
length=(uint) strlen(err);
|
|
set_if_smaller(length,MYSQL_ERRMSG_SIZE);
|
|
}
|
|
VOID(net_write_command(net,(uchar) 255,(char*) err,length));
|
|
if (thd)
|
|
thd->fatal_error=0; // Error message is given
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
/**
|
|
** write error package and flush to client
|
|
** It's a little too low level, but I don't want to allow another buffer
|
|
*/
|
|
/* VARARGS3 */
|
|
|
|
void
|
|
net_printf(NET *net, uint errcode, ...)
|
|
{
|
|
va_list args;
|
|
uint length,offset;
|
|
const char *format,*text_pos;
|
|
int head_length= NET_HEADER_SIZE;
|
|
THD *thd=current_thd;
|
|
DBUG_ENTER("net_printf");
|
|
DBUG_PRINT("enter",("message: %u",errcode));
|
|
|
|
if(thd) thd->query_error = 1;
|
|
// if we are here, something is wrong :-)
|
|
|
|
va_start(args,errcode);
|
|
format=ER(errcode);
|
|
offset= net->return_errno ? 2 : 0;
|
|
text_pos=(char*) net->buff+head_length+offset+1;
|
|
(void) vsprintf(my_const_cast(char*) (text_pos),format,args);
|
|
length=(uint) strlen((char*) text_pos);
|
|
if (length >= sizeof(net->last_error))
|
|
length=sizeof(net->last_error)-1; /* purecov: inspected */
|
|
va_end(args);
|
|
|
|
if (net->vio == 0)
|
|
{
|
|
if (thd && thd->bootstrap)
|
|
{
|
|
fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos);
|
|
thd->fatal_error=1;
|
|
}
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
int3store(net->buff,length+1+offset);
|
|
net->buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
|
net->buff[head_length]=(uchar) 255; // Error package
|
|
if (offset)
|
|
int2store(text_pos-2, errcode);
|
|
VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset));
|
|
if (thd)
|
|
thd->fatal_error=0; // Error message is given
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
|
|
void
|
|
send_ok(NET *net,ha_rows affected_rows,ulonglong id,const char *message)
|
|
{
|
|
if(net->no_send_ok)
|
|
return;
|
|
|
|
char buff[MYSQL_ERRMSG_SIZE+10],*pos;
|
|
DBUG_ENTER("send_ok");
|
|
buff[0]=0; // No fields
|
|
pos=net_store_length(buff+1,(ulonglong) affected_rows);
|
|
pos=net_store_length(pos, (ulonglong) id);
|
|
if (net->return_status)
|
|
{
|
|
int2store(pos,*net->return_status);
|
|
pos+=2;
|
|
}
|
|
if (message)
|
|
pos=net_store_data((char*) pos,message);
|
|
if (net->vio != 0)
|
|
{
|
|
VOID(my_net_write(net,buff,(uint) (pos-buff)));
|
|
VOID(net_flush(net));
|
|
}
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
void
|
|
send_eof(NET *net,bool no_flush)
|
|
{
|
|
static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
|
|
DBUG_ENTER("send_eof");
|
|
if (net->vio != 0)
|
|
{
|
|
VOID(my_net_write(net,eof_buff,1));
|
|
if (!no_flush)
|
|
VOID(net_flush(net));
|
|
}
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
** Store a field length in logical packet
|
|
****************************************************************************/
|
|
|
|
char *
|
|
net_store_length(char *pkg, ulonglong length)
|
|
{
|
|
uchar *packet=(uchar*) pkg;
|
|
if (length < LL(251))
|
|
{
|
|
*packet=(uchar) length;
|
|
return (char*) packet+1;
|
|
}
|
|
/* 251 is reserved for NULL */
|
|
if (length < LL(65536))
|
|
{
|
|
*packet++=252;
|
|
int2store(packet,(uint) length);
|
|
return (char*) packet+2;
|
|
}
|
|
if (length < LL(16777216))
|
|
{
|
|
*packet++=253;
|
|
int3store(packet,(ulong) length);
|
|
return (char*) packet+3;
|
|
}
|
|
*packet++=254;
|
|
int8store(packet,length);
|
|
return (char*) packet+9;
|
|
}
|
|
|
|
char *
|
|
net_store_length(char *pkg, uint length)
|
|
{
|
|
uchar *packet=(uchar*) pkg;
|
|
if (length < 251)
|
|
{
|
|
*packet=(uchar) length;
|
|
return (char*) packet+1;
|
|
}
|
|
*packet++=252;
|
|
int2store(packet,(uint) length);
|
|
return (char*) packet+2;
|
|
}
|
|
|
|
/* The following will only be used for short strings < 65K */
|
|
char *
|
|
net_store_data(char *to,const char *from)
|
|
{
|
|
uint length=(uint) strlen(from);
|
|
to=net_store_length(to,length);
|
|
memcpy(to,from,length);
|
|
return to+length;
|
|
}
|
|
|
|
|
|
char *
|
|
net_store_data(char *to,int32 from)
|
|
{
|
|
char buff[20];
|
|
uint length=(uint) (int10_to_str(from,buff,10)-buff);
|
|
to=net_store_length(to,length);
|
|
memcpy(to,buff,length);
|
|
return to+length;
|
|
}
|
|
|
|
char *
|
|
net_store_data(char *to,longlong from)
|
|
{
|
|
char buff[22];
|
|
uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
|
|
to=net_store_length(to,length);
|
|
memcpy(to,buff,length);
|
|
return to+length;
|
|
}
|
|
|
|
|
|
bool net_store_null(String *packet)
|
|
{
|
|
return packet->append((char) 251);
|
|
}
|
|
|
|
bool
|
|
net_store_data(String *packet,const char *from,uint length)
|
|
{
|
|
ulong packet_length=packet->length();
|
|
if (packet_length+5+length > packet->alloced_length() &&
|
|
packet->realloc(packet_length+5+length))
|
|
return 1;
|
|
char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
|
|
(ulonglong) length);
|
|
memcpy(to,from,length);
|
|
packet->length((uint) (to+length-packet->ptr()));
|
|
return 0;
|
|
}
|
|
|
|
/* The following is only used at short, null terminated data */
|
|
|
|
bool
|
|
net_store_data(String *packet,const char *from)
|
|
{
|
|
uint length=(uint) strlen(from);
|
|
uint packet_length=packet->length();
|
|
if (packet_length+5+length > packet->alloced_length() &&
|
|
packet->realloc(packet_length+5+length))
|
|
return 1;
|
|
char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
|
|
length);
|
|
memcpy(to,from,length);
|
|
packet->length((uint) (to+length-packet->ptr()));
|
|
return 0;
|
|
}
|
|
|
|
|
|
bool
|
|
net_store_data(String *packet,uint32 from)
|
|
{
|
|
char buff[20];
|
|
return net_store_data(packet,(char*) buff,
|
|
(uint) (int10_to_str(from,buff,10)-buff));
|
|
}
|
|
|
|
bool
|
|
net_store_data(String *packet, longlong from)
|
|
{
|
|
char buff[22];
|
|
return net_store_data(packet,(char*) buff,
|
|
(uint) (longlong10_to_str(from,buff,10)-buff));
|
|
}
|
|
|
|
bool
|
|
net_store_data(String *packet,struct tm *tmp)
|
|
{
|
|
char buff[20];
|
|
sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
|
|
((int) (tmp->tm_year+1900)) % 10000,
|
|
(int) tmp->tm_mon+1,
|
|
(int) tmp->tm_mday,
|
|
(int) tmp->tm_hour,
|
|
(int) tmp->tm_min,
|
|
(int) tmp->tm_sec);
|
|
return net_store_data(packet,(char*) buff,19);
|
|
}
|
|
|
|
bool net_store_data(String* packet, I_List<i_string>* str_list)
|
|
{
|
|
char buf[256];
|
|
String tmp(buf, sizeof(buf));
|
|
tmp.length(0);
|
|
I_List_iterator<i_string> it(*str_list);
|
|
i_string* s;
|
|
|
|
while((s=it++))
|
|
{
|
|
if(tmp.length())
|
|
tmp.append(',');
|
|
tmp.append(s->ptr);
|
|
}
|
|
|
|
return net_store_data(packet, (char*)tmp.ptr(), tmp.length());
|
|
}
|