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

fixed so that --ssl and --skip-ssl works with the MySQL clients.

Fixed core dump bug when sending wrong string to AES_DECRYPT()
parent 3bb2660d
......@@ -2304,12 +2304,14 @@ to do and is a powerful way to get information about any table in a database
that will help us create a situation matching the one you have.
@item
For speed-related bugs or problems with @code{SELECT} statements, you should
always include the output of @code{EXPLAIN SELECT ...}, and at least the
number of rows that the @code{SELECT} statement produces. The more
information you give about your situation, the more likely it is that someone
can help you! For example, the following is an example of a very good bug
report (it should of course be posted with the @code{mysqlbug} script):
For speed-related bugs or problems with @code{SELECT} statements, you
should always include the output of @code{EXPLAIN SELECT ...}, and at
least the number of rows that the @code{SELECT} statement produces. You
should also include the output from @code{SHOW CREATE TABLE table_name}
for each involved table. The more information you give about your
situation, the more likely it is that someone can help you! For
example, the following is an example of a very good bug report (it
should of course be posted with the @code{mysqlbug} script):
Example run using the @code{mysql} command-line tool (note the use of the
@code{\G} statement terminator for statements whose output width would
......@@ -50440,6 +50442,12 @@ each individual 4.0.x release.
@itemize @bullet
@item
Fixed overrun bug when calling @code{AES_DECRYPT()} with wrong arguments
@item
@code{--skip-ssl} can now be used to disable SSL in the MySQL clients,
even if one is using other ssl options in a options file or previously
on the command line.
@item
Added @code{LOCK TABLES} and @code{CREATE TEMPORARY TABLES} privilege on
the database level. One must run the @code{ mysql_fix_privilege_tables}
script on old installations to activate these.
......@@ -50494,12 +50502,13 @@ This affected at least @code{default-table-type} option.
Fixed a bug that caused @code{REPAIR TABLE} to fail on tables
with duplicates in a unique key.
@item
Fixed a bug in guessing a field type out of the function. The error was
introduced in 4.0.3 so that field type depended on the first argument to
the function instead of the function itself
Fixed a bug from 4.0.3 in calculating the default field type for some
functions. This affected queries of type @code{CREATE TABLE table_name
SELECT expression(),...}
@item
Fixed a bug with wildcarded fields in select list, which led to the wrong
number of elements in a list containing all fields
Fixed bug in queries of type
@code{SELECT * FROM table-list GROUP BY ...} and
@code{SELECT DISTINCT * FROM ...}.
@item
Fixed bug with the @code{--slow-log} when logging an administrator command
(like @code{FLUSH TABLES}).
......@@ -2209,9 +2209,6 @@ sql_real_connect(char *host,char *database,char *user,char *password,
if (using_opt_local_infile)
mysql_options(&mysql,MYSQL_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
#ifdef HAVE_OPENSSL
if (opt_ssl_key || opt_ssl_cert || opt_ssl_ca || opt_ssl_capath ||
opt_ssl_cipher)
opt_use_ssl= 1;
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
......
......@@ -52,7 +52,7 @@ static uint ex_val_max_len[MAX_MYSQL_VAR];
static my_bool ex_status_printed = 0; /* First output is not relative. */
static uint ex_var_count, max_var_length, max_val_length;
#include "sslopt-vars.h"
#include <sslopt-vars.h>
static void print_version(void);
static void usage(void);
......@@ -150,7 +150,7 @@ static struct my_option my_long_options[] =
{"sleep", 'i', "Execute commands again and again with a sleep between.",
(gptr*) &interval, (gptr*) &interval, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0,
0, 0},
#include "sslopt-longopts.h"
#include <sslopt-longopts.h>
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", (gptr*) &user,
(gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......@@ -211,6 +211,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case '#':
DBUG_PUSH(argument ? argument : "d:t:o,/tmp/mysqladmin.trace");
break;
#include <sslopt-case.h>
case 'V':
print_version();
exit(0);
......@@ -279,9 +280,6 @@ int main(int argc,char *argv[])
mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT, (char*) &tmp);
}
#ifdef HAVE_OPENSSL
if (opt_ssl_key || opt_ssl_cert || opt_ssl_ca || opt_ssl_capath ||
opt_ssl_cipher)
opt_use_ssl= 1;
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
......
......@@ -20,9 +20,9 @@
#include "client_priv.h"
#include <m_ctype.h>
#include "mysql_version.h"
#include "mysqld_error.h"
#include "sslopt-vars.h"
#include <mysql_version.h>
#include <mysqld_error.h>
#include <sslopt-vars.h>
/* Exit codes */
......@@ -121,7 +121,7 @@ static struct my_option my_long_options[] =
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
#include <sslopt-longopts.h>
{"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
......@@ -239,6 +239,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
#include <sslopt-case.h>
case OPT_TABLES:
opt_databases = 0;
break;
......@@ -529,9 +530,6 @@ static int dbConnect(char *host, char *user, char *passwd)
if (opt_compress)
mysql_options(&mysql_connection, MYSQL_OPT_COMPRESS, NullS);
#ifdef HAVE_OPENSSL
if (opt_ssl_key || opt_ssl_cert || opt_ssl_ca || opt_ssl_capath ||
opt_ssl_cipher)
opt_use_ssl= 1;
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
......
......@@ -88,7 +88,7 @@ static my_string opt_mysql_unix_port=0;
static int first_error=0;
extern ulong net_buffer_length;
static DYNAMIC_STRING extended_row;
#include "sslopt-vars.h"
#include <sslopt-vars.h>
FILE *md_result_file;
static struct my_option my_long_options[] =
......@@ -211,7 +211,7 @@ static struct my_option my_long_options[] =
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
#include <sslopt-longopts.h>
{"tab",'T',
"Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.",
(gptr*) &path, (gptr*) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......@@ -335,6 +335,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
#include <sslopt-case.h>
case 'V': print_version(); exit(0);
case 'X':
opt_xml = 1;
......@@ -457,9 +458,6 @@ static int dbConnect(char *host, char *user,char *passwd)
if (opt_compress)
mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL
if (opt_ssl_key || opt_ssl_cert || opt_ssl_ca || opt_ssl_capath ||
opt_ssl_cipher)
opt_use_ssl= 1;
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
......
......@@ -47,7 +47,7 @@ static char *opt_password=0, *current_user=0,
static uint opt_mysql_port=0;
static my_string opt_mysql_unix_port=0;
static my_string opt_ignore_lines=0;
#include "sslopt-vars.h"
#include <sslopt-vars.h>
static struct my_option my_long_options[] =
{
......@@ -119,7 +119,7 @@ static struct my_option my_long_options[] =
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
#include <sslopt-longopts.h>
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", (gptr*) &current_user,
(gptr*) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......@@ -188,6 +188,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
#include <sslopt-case.h>
case 'V': print_version(); exit(0);
case 'I':
case '?':
......@@ -347,9 +348,6 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
mysql_options(&mysql_connection,MYSQL_OPT_LOCAL_INFILE,
(char*) &opt_local_file);
#ifdef HAVE_OPENSSL
if (opt_ssl_key || opt_ssl_cert || opt_ssl_ca || opt_ssl_capath ||
opt_ssl_cipher)
opt_use_ssl= 1;
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
......
......@@ -18,16 +18,14 @@
#define SHOW_VERSION "9.4"
#include <my_global.h>
#include "client_priv.h"
#include <my_sys.h>
#include <m_string.h>
#include "mysql.h"
#include "mysql_version.h"
#include "mysqld_error.h"
#include <mysql.h>
#include <mysqld_error.h>
#include <signal.h>
#include <stdarg.h>
#include "sslopt-vars.h"
#include <sslopt-vars.h>
static my_string host=0,opt_password=0,user=0;
static my_bool opt_show_keys=0,opt_compress=0,opt_status=0, tty_password=0;
......@@ -85,9 +83,6 @@ int main(int argc, char **argv)
if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
#ifdef HAVE_OPENSSL
if (opt_ssl_key || opt_ssl_cert || opt_ssl_ca || opt_ssl_capath ||
opt_ssl_cipher)
opt_use_ssl= 1;
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
......@@ -156,7 +151,7 @@ static struct my_option my_long_options[] =
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
#include <sslopt-longopts.h>
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", (gptr*) &user,
(gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......@@ -224,6 +219,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
#include <sslopt-case.h>
case 'V':
print_version();
exit(0);
......
/* Copyright (C) 2000 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 */
#ifdef HAVE_OPENSSL
case OPT_SSL_KEY:
case OPT_SSL_CERT:
case OPT_SSL_CA:
case OPT_SSL_CAPATH:
case OPT_SSL_CIPHER:
/*
Enable use of SSL if we are using any ssl option
One can disable SSL later by using --skip-ssl or --ssl=0
*/
opt_use_ssl= 1;
break;
#endif
......@@ -223,3 +223,8 @@ SELECT CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugs
CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter)
Link";"1";"1";"1";"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"2001-02-28 08:40:16";"20010228084016";"0";"4
drop table t1;
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, tmp text NOT NULL, KEY id (id)) TYPE=MyISAM;
INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
1
DROP TABLE t1;
......@@ -114,3 +114,12 @@ SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugdesc,created,mo
SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugstatus,submitter), '"') FROM t1;
SELECT CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter) FROM t1;
drop table t1;
#
# Test bug in AES_DECRYPT() when called with wrong argument
#
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, tmp text NOT NULL, KEY id (id)) TYPE=MyISAM;
INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
DROP TABLE t1;
......@@ -178,7 +178,7 @@ int my_aes_decrypt(const char *source, int source_length, char *dest,
char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
int rc; /* Result codes */
int num_blocks; /* Number of complete blocks */
char pad_len; /* Pad size for the last block */
uint pad_len; /* Pad size for the last block */
int i;
if ((rc=my_aes_create_key(&aes_key,AES_DECRYPT,key,key_length)))
......@@ -197,7 +197,8 @@ int my_aes_decrypt(const char *source, int source_length, char *dest,
}
rijndaelDecrypt(aes_key.rk, aes_key.nr, source, block);
pad_len = block[AES_BLOCK_SIZE-1]; /* Use last char in the block as size */
/* Use last char in the block as size */
pad_len = (uint) (uchar) block[AES_BLOCK_SIZE-1];
if (pad_len > AES_BLOCK_SIZE)
return AES_BAD_DATA;
......
#!@PERL@ -w
use strict;
use DBI;
use Getopt::Long;
$Getopt::Long::ignorecase=0;
print "explain_log provided by http://www.mobile.de\n";
print "=========== ================================\n";
my $Param={};
$Param->{host}='';
$Param->{user}='';
$Param->{password}='';
$Param->{PrintError}=0;
if (!GetOptions ('date|d:i' => \$Param->{ViewDate},
'host|h:s' => \$Param->{host},
'user|u:s' => \$Param->{user},
'password|p:s' => \$Param->{password},
'printerror|e:s' => \$Param->{PrintError},
)) {
ShowOptions();
}
else {
$Param->{UpdateCount} = 0;
$Param->{SelectCount} = 0;
$Param->{IdxUseCount} = 0;
$Param->{LineCount} = 0;
$Param->{Init} = 0;
$Param->{Field} = 0;
$Param->{Refresh} = 0;
$Param->{QueryCount} = 0;
$Param->{Statistics} =0;
$Param->{Query} = undef;
$Param->{ALL} = undef ;
$Param->{Comment} = undef ;
@{$Param->{Rows}} = (qw|possible_keys key type|);
if ($Param->{ViewDate}) {
$Param->{View} = 0;
}
else {
$Param->{View} = 1;
}
#print "Date=$Param->{ViewDate}, host=$Param->{host}, user=$Param->{user}, password=$Param->{password}\n";
$Param->{dbh}=DBI->connect("DBI:mysql:host=$Param->{host}",$Param->{user},$Param->{password},{PrintError=>0});
if (DBI::err()) {
print "Error: " . DBI::errstr() . "\n";
}
else {
$Param->{Start} = time;
while(<STDIN>) {
$Param->{LineCount} ++ ;
if ($Param->{ViewDate} ) {
if (m/^(\d{6})\s+\d{1,2}:\d\d:\d\d\s.*$/) { # get date
#print "# $1 #\n";
if ($1 == $Param->{ViewDate}) {
$Param->{View} = 1;
}
else {
$Param->{View} = 0;
}
}
}
if ($Param->{View} ) {
#print "->>>$_";
if (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+\s+on\s+(.*)$/i) { # get connection ID($2) and database($3)
#print "C-$1--$2--$3------\n";
RunQuery($Param);
if (defined $3) {
$Param->{CID}->{$2} = $3 ;
#print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n";
}
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+$/i) { # get connection ID($2) and database($3)
#print "\n <<<<<<<<<<<<<<<<<<----------------------------<<<<<<<<<<<<<<<< \n";
#print "Connect \n";
RunQuery($Param);
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Change user .*\s+on\s+(.*)$/i) { # get connection ID($2) and database($3)
#print "C-$1--$2--$3------\n";
RunQuery($Param);
if (defined $3) {
$Param->{CID}->{$2} = $3 ;
#print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n";
}
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Quit\s+$/i) { # remove connection ID($2) and querystring
#print "Q-$1--$2--------\n";
RunQuery($Param);
delete $Param->{CID}->{$2} ;
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(select.+)$/i) { # get connection ID($2) and querystring
#print "S1-$1--$2--$3------\n";
RunQuery($Param);
unless ($Param->{CID}->{$2}) {
#print "Error: No Database for Handle: $2 found\n";
}
else {
$Param->{DB}=$Param->{CID}->{$2};
my $s = "$3";
$s =~ s/from\s/from $Param->{DB}./i;
$Param->{Query}="EXPLAIN $s";
#$s =~ m/from\s+(\w+[.]\w+)/i;
#$Param->{tab} =$1;
#print "-- $Param->{tab} -- $s --\n";
}
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(update.+)$/i) { # get connection ID($2) and querystring
#print "S2--$1--$2--$3------\n";
RunQuery($Param);
unless ($Param->{CID}->{$2}) {
#print "Error: No Database for Handle: $2 found\n";
}
else {
$Param->{DB}=$Param->{CID}->{$2};
my $ud = $3;
$ud =~ m/^update\s+(\w+).+(where.+)$/i;
$Param->{Query} ="EXPLAIN SELECT * FROM $1 $2";
$Param->{Query} =~ s/from\s/from $Param->{DB}./i;
#$Param->{Query} =~ m/from\s+(\w+[.]\w+)/i;
#$Param->{tab} =$1;
}
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Statistics\s+(.*)$/i) { # get connection ID($2) and info?
$Param->{Statistics} ++;
#print "Statistics--$1--$2--$3------\n";
RunQuery($Param);
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(.+)$/i) { # get connection ID($2)
$Param->{QueryCount} ++;
#print "Query-NULL $3\n";
RunQuery($Param);
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Refresh\s+(.+)$/i) { # get connection ID($2)
$Param->{Refresh} ++;
#print "Refresh\n";
RunQuery($Param);
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Init\s+(.+)$/i) { # get connection ID($2)
$Param->{Init} ++;
#print "Init $3\n";
RunQuery($Param);
}
elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Field\s+(.+)$/i) { # get connection ID($2)
$Param->{Field} ++;
#print "Field $3\n";
RunQuery($Param);
}
elsif (m/^\s+(.+)$/ ) { # command could be some lines ...
#print "multi-lined ($1)\n";
my ($A)=$1;
chomp $A;
$Param->{Query} .= " $1";
#print "multi-lined ($1)<<$Param->{Query}>>\n";
}
}
}
$Param->{dbh}->disconnect();
if (1 == 0) {
print "\nunclosed handles----------------------------------------\n";
my $count=0;
foreach (sort keys %{$Param->{CID}}) {
print "$count | $_ : $Param->{CID}->{$_} \n";
$count ++;
}
}
print "\nIndex usage ------------------------------------\n";
foreach my $t (sort keys %{$Param->{Data}}) {
print "\nTable\t$t: ---\n";
foreach my $k (sort keys %{$Param->{Data}->{$t}}) {
print " count\t$k:\n";
my %h = %{$Param->{Data}->{$t}->{$k}};
foreach (sort {$h{$a} <=> $h{$b}} keys %h) {
print " $Param->{Data}->{$t}->{$k}->{$_}\t$_\n";
}
}
}
$Param->{AllCount}=0;
print "\nQueries causing table scans -------------------\n\n";
foreach (@{$Param->{ALL}}) {
$Param->{AllCount} ++;
print "$_\n";
}
print "Sum: $Param->{AllCount} table scans\n";
print "\nSummary ---------------------------------------\n\n";
print "Select: \t$Param->{SelectCount} queries\n";
print "Update: \t$Param->{UpdateCount} queries\n";
print "\n";
print "Init: \t$Param->{Init} times\n";
print "Field: \t$Param->{Field} times\n";
print "Refresh: \t$Param->{Refresh} times\n";
print "Query: \t$Param->{QueryCount} times\n";
print "Statistics:\t$Param->{Statistics} times\n";
print "\n";
print "Logfile: \t$Param->{LineCount} lines\n";
print "Started: \t".localtime($Param->{Start})."\n";
print "Finished: \t".localtime(time)."\n";
}
}
###########################################################################
#
#
#
sub RunQuery {
my $Param = shift ;
if (defined $Param->{Query}) {
if (defined $Param->{DB} ) {
$Param->{Query} =~ m/from\s+(\w+[.]\w+|\w+)/i;
$Param->{tab} =$1;
#print "||$Param->{tab} -- $Param->{Query}\n";
my $sth=$Param->{dbh}->prepare("USE $Param->{DB}");
if (DBI::err()) {
if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
}
else {
$sth->execute();
if (DBI::err()) {
if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
}
else {
$sth->finish();
$sth=$Param->{dbh}->prepare($Param->{Query});
if (DBI::err()) {
if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
}
else {
#print "$Param->{Query}\n";
$sth->execute();
if (DBI::err()) {
if ($Param->{PrintError}) {print "[$Param->{LineCount}]<<$Param->{Query}>>\n";}
if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
}
else {
my $row = undef;
while ($row = $sth->fetchrow_hashref()) {
$Param->{SelectCount} ++;
if (defined $row->{Comment}) {
push (@{$Param->{Comment}}, "$row->{Comment}; $_; $Param->{DB}; $Param->{Query}");
}
foreach (@{$Param->{Rows}}) {
if (defined $row->{$_}) {
#if (($_ eq 'type' ) and ($row->{$_} eq 'ALL')) {
if ($row->{type} eq 'ALL') {
push (@{$Param->{ALL}}, "$Param->{Query}");
#print ">> $row->{$_} $_ $Param->{DB} $Param->{Query}\n";
}
$Param->{IdxUseCount} ++;
$Param->{Data}->{$Param->{tab}}->{$_}->{$row->{$_}} ++;
}
}
}
}
}
}
}
$sth->finish();
}
$Param->{Query} = undef ;
}
}
###########################################################################
#
#
#
sub ShowOptions {
print <<EOF;
Usage: $0 [OPTIONS] < LOGFILE
--date=YYMMDD select only entrys of date
-d=YYMMDD
--host=HOSTNAME db-host to ask
-h=HOSTNAME
--user=USERNAME db-user
-u=USERNAME
--password=PASSWORD password of db-user
-p=PASSWORD
Read logfile from STDIN an try to EXPLAIN all SELECT statements. All UPDATE statements are rewritten to an EXPLAIN SELECT statement. The results of the EXPLAIN statement are collected and counted. All results with type=ALL are collected in an separete list. Results are printed to STDOUT.
EOF
}
1;
__END__
=pod
=head1 NAME
explain_log.pl
Feed a mysqld general logfile (created with mysqld --log) back into mysql
and collect statistics about index usage with EXPLAIN.
=head1 DISCUSSION
To optimize your indices, you have to know which ones are actually
used and what kind of queries are causing table scans. Especially
if you are generating your queries dynamically and you have a huge
amount of queries going on, this isn't easy.
Use this tool to take a look at the effects of your real life queries.
Then add indices to avoid table scans and remove those which aren't used.
=head1 USAGE
explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw] < logfile
--date=YYMMDD select only entrys of date
-d=YYMMDD
--host=HOSTNAME db-host to ask
-h=HOSTNAME
--user=USERNAME db-user
-u=USERNAME
--password=PASSWORD password of db-user
-p=PASSWORD
=head1 EXAMPLE
explain_log.pl --host=localhost --user=foo --password=bar < /var/lib/mysql/mobile.log
=head1 AUTHOR
Stefan Nitz
Jan Willamowius <jan@mobile.de>, http://www.mobile.de
=head1 RECRUITING
If you are looking for a MySQL or Perl job, take a look at http://www.mobile.de
and send me an email with your resume (you must be speaking German!).
=head1 SEE ALSO
mysql documentation
=cut
......@@ -279,7 +279,7 @@ sub RunQuery {
if (defined $row->{$_}) {
#if (($_ eq 'type' ) and ($row->{$_} eq 'ALL')) {
if ($row->{type} eq 'ALL') {
push (@{$Param->{ALL}}, "$row->{$_} $_ $Param->{DB} $Param->{Query}");
push (@{$Param->{ALL}}, "$Param->{Query}");
#print ">> $row->{$_} $_ $Param->{DB} $Param->{Query}\n";
}
$Param->{IdxUseCount} ++;
......
......@@ -114,7 +114,7 @@ String *Item_func_sha::val_str(String *str)
/* No need to check error as the only case would be too long message */
sha1_input(&context,(const unsigned char *) sptr->ptr(), sptr->length());
/* Ensure that memory is free and we got result */
if ( !( str->alloc(SHA1_HASH_SIZE*2) || (sha1_result(&context,digest)) ) )
if (!( str->alloc(SHA1_HASH_SIZE*2) || (sha1_result(&context,digest))))
{
sprintf((char *) str->ptr(),
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\
......@@ -144,24 +144,25 @@ void Item_func_sha::fix_length_and_dec()
String *Item_func_aes_encrypt::val_str(String *str)
{
String * sptr = args[0]->val_str(str); // String to encrypt
String tmp_value; // required to handle second parameter
String * key= args[1]->val_str(&tmp_value); // key
char key_buff[80];
String tmp_key_value(key_buff, sizeof(key_buff));
String *sptr= args[0]->val_str(str); // String to encrypt
String *key= args[1]->val_str(&tmp_key_value); // key
int aes_length;
if (sptr && key) // we need both arguments to be not NULL
{
null_value=0;
aes_length=my_aes_get_size(sptr->length()); // calculate result length
aes_length=my_aes_get_size(sptr->length()); // Calculate result length
if (!str->alloc(aes_length)) // Ensure that memory is free
if (!str_value.alloc(aes_length)) // Ensure that memory is free
{
// finally encrypt directly to allocated buffer.
if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str->ptr(),
if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str_value.ptr(),
key->ptr(), key->length()) == aes_length)
{
// We got the expected result length
str->length((uint) aes_length);
return str;
str_value.length((uint) aes_length);
return &str_value;
}
}
}
......@@ -178,30 +179,35 @@ void Item_func_aes_encrypt::fix_length_and_dec()
String *Item_func_aes_decrypt::val_str(String *str)
{
String * sptr= args[0]->val_str(str); // String to decrypt
String tmp_value; // temporary string required for parsing
String * key= args[1]->val_str(&tmp_value); // key
int length; // original length after decrypt
char key_buff[80];
String tmp_key_value(key_buff, sizeof(key_buff)), *sptr, *key;
DBUG_ENTER("Item_func_aes_decrypt::val_str");
sptr= args[0]->val_str(str); // String to decrypt
key= args[1]->val_str(&tmp_key_value); // Key
if (sptr && key) // Need to have both arguments not NULL
{
null_value=0;
if (!str->alloc(sptr->length())) // Ensure that memory is free
if (!str_value.alloc(sptr->length())) // Ensure that memory is free
{
// finally decrypt directly to allocated buffer.
length=my_aes_decrypt(sptr->ptr(), sptr->length(), (char*) str->ptr(),
int length;
length=my_aes_decrypt(sptr->ptr(), sptr->length(),
(char*) str_value.ptr(),
key->ptr(), key->length());
if (length >= 0) // if we got correct data data
{
str->length((uint) length);
return str;
str_value.length((uint) length);
DBUG_RETURN(&str_value);
}
}
}
// Bad parameters. No memory or bad data will all go here
null_value=1;
return 0;
DBUG_RETURN(0);
}
void Item_func_aes_decrypt::fix_length_and_dec()
{
max_length=args[0]->max_length;
......
......@@ -115,7 +115,13 @@ net_printf(NET *net, uint errcode, ...)
is useful for rare errors that are not worth the hassle to put in
errmsg.sys, but at the same time, the message is not fixed text
*/
format=errcode ? ER(errcode) : va_arg(args,char*);
if (errcode)
format= ER(errcode);
else
{
format=va_arg(args,char*);
errcode= ER_UNKNOWN_ERROR;
}
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);
......
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