mariadb/sql/net_pkg.cc
unknown e94b4ebf2b All statements are now run in a sub transaction
Give warning if we are using non transactional tables and do ROLLBACK
Porting of crash-me and benchmarks to FrontBase


Docs/manual.texi:
  Updates for 3.23.29
include/mysqld_error.h:
  New error messages
sql-bench/Data/ATIS/fconnection.txt:
  Name change because 'connection' was a reserved word in FrontBase
sql-bench/bench-init.pl.sh:
  Port to FrontBase
sql-bench/crash-me.sh:
  Port to FrontBase
sql-bench/server-cfg.sh:
  Port to FrontBase
sql-bench/test-ATIS.sh:
  Port to FrontBase
sql-bench/test-alter-table.sh:
  Port to FrontBase
sql-bench/test-big-tables.sh:
  Port to FrontBase
sql-bench/test-connect.sh:
  Port to FrontBase
sql-bench/test-create.sh:
  Port to FrontBase
sql-bench/test-insert.sh:
  Port to FrontBase
sql-bench/test-select.sh:
  Port to FrontBase
sql-bench/test-wisconsin.sh:
  Port to FrontBase
sql/ha_berkeley.cc:
  All statements are now run in a sub transaction
sql/ha_berkeley.h:
  All statements are now run in a sub transaction
sql/handler.cc:
  All statements are now run in a sub transaction
sql/handler.h:
  All statements are now run in a sub transaction
sql/mysql_priv.h:
  Moved QUERY_NO.. flags to unique numbers
sql/mysqld.cc:
  All statements are now run in a sub transaction
sql/net_pkg.cc:
  Added send_warning
sql/share/czech/errmsg.sys:
  New error messages
sql/share/czech/errmsg.txt:
  New error messages
sql/share/danish/errmsg.sys:
  New error messages
sql/share/danish/errmsg.txt:
  New error messages
sql/share/dutch/errmsg.sys:
  New error messages
sql/share/dutch/errmsg.txt:
  New error messages
sql/share/english/errmsg.sys:
  New error messages
sql/share/english/errmsg.txt:
  New error messages
sql/share/estonian/errmsg.sys:
  New error messages
sql/share/estonian/errmsg.txt:
  New error messages
sql/share/french/errmsg.sys:
  New error messages
sql/share/french/errmsg.txt:
  New error messages
sql/share/german/errmsg.sys:
  New error messages
sql/share/german/errmsg.txt:
  New error messages
sql/share/greek/errmsg.sys:
  New error messages
sql/share/greek/errmsg.txt:
  New error messages
sql/share/hungarian/errmsg.sys:
  New error messages
sql/share/hungarian/errmsg.txt:
  New error messages
sql/share/italian/errmsg.sys:
  New error messages
sql/share/italian/errmsg.txt:
  New error messages
sql/share/japanese/errmsg.sys:
  New error messages
sql/share/japanese/errmsg.txt:
  New error messages
sql/share/korean/errmsg.sys:
  New error messages
sql/share/korean/errmsg.txt:
  New error messages
sql/share/norwegian-ny/errmsg.txt:
  New error messages
sql/share/norwegian/errmsg.txt:
  New error messages
sql/share/polish/errmsg.sys:
  New error messages
sql/share/polish/errmsg.txt:
  New error messages
sql/share/portuguese/errmsg.sys:
  New error messages
sql/share/portuguese/errmsg.txt:
  New error messages
sql/share/romanian/errmsg.txt:
  New error messages
sql/share/russian/errmsg.sys:
  New error messages
sql/share/russian/errmsg.txt:
  New error messages
sql/share/slovak/errmsg.sys:
  New error messages
sql/share/slovak/errmsg.txt:
  New error messages
sql/share/spanish/errmsg.sys:
  New error messages
sql/share/spanish/errmsg.txt:
  New error messages
sql/share/swedish/errmsg.OLD:
  New error messages
sql/share/swedish/errmsg.sys:
  New error messages
sql/share/swedish/errmsg.txt:
  New error messages
sql/slave.cc:
  All statements are now run in a sub transaction
sql/sql_class.cc:
  All statements are now run in a sub transaction
sql/sql_class.h:
  All statements are now run in a sub transaction
sql/sql_delete.cc:
  Remember if we are using a non transactional table
sql/sql_insert.cc:
  Remember if we are using a non transactional table
sql/sql_load.cc:
  Remember if we are using a non transactional table
sql/sql_parse.cc:
  All statements are now run in a sub transaction
sql/sql_select.cc:
  Remember if we are using a non transactional table
sql/sql_table.cc:
  All statements are now run in a sub transaction
sql/sql_update.cc:
  All statements are now run in a sub transaction
sql/sql_yacc.yy:
  All statements are now run in a sub transaction
2000-11-24 01:51:18 +02:00

341 lines
8.1 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;
}
/*
At some point we need to be able to distinguish between warnings and
errors; The following function will help make this easier.
*/
void send_warning(NET *net, uint sql_errno, const char *err)
{
DBUG_ENTER("send_warning");
send_error(net,sql_errno,err);
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());
}