Commit c16b9dfc authored by unknown's avatar unknown
Browse files

Merge rurik.mysql.com:/home/igor/mysql-5.0

into  rurik.mysql.com:/home/igor/dev/mysql-5.0-0

parents b54cb499 c5ed5c4b
Loading
Loading
Loading
Loading
+50 −29
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ void tee_fprintf(FILE *file, const char *fmt, ...);
void tee_fputs(const char *s, FILE *file);
void tee_puts(const char *s, FILE *file);
void tee_putc(int c, FILE *file);
static void tee_print_sized_data(const char *data, unsigned int length, unsigned int width);
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
/* The names of functions that actually do the manipulation. */
static int get_options(int argc,char **argv);
static int com_quit(String *str,char*),
@@ -2315,31 +2315,48 @@ print_table_data(MYSQL_RES *result)
    mysql_field_seek(result, 0);
    for (uint off= 0; off < mysql_num_fields(result); off++)
    {
      const char *str= cur[off] ? cur[off] : "NULL";
      uint currlength;
      uint maxlength;
      uint numcells;
      const char *buffer;
      uint data_length;
      uint field_max_length;
      bool right_justified;
      uint visible_length;
      uint extra_padding;

      field= mysql_fetch_field(result);
      maxlength= field->max_length;
      currlength= (uint) lengths[off];
      numcells= charset_info->cset->numcells(charset_info, 
                                                    str, str + currlength);
      if (maxlength > MAX_COLUMN_LENGTH)
      if (lengths[off] == 0) 
      {
        tee_print_sized_data(str, currlength, maxlength);
        tee_fputs(" |", PAGER);
        buffer= "NULL";
        data_length= 4;
      } 
      else 
      {
        if (num_flag[off] != 0)
          tee_fprintf(PAGER, " %-*s|", maxlength + currlength - numcells, str);
        buffer= cur[off];
        data_length= (uint) lengths[off];
      }

      field= mysql_fetch_field(result);
      field_max_length= field->max_length;

      /* 
       How many text cells on the screen will this string span?  If it contains
       multibyte characters, then the number of characters we occupy on screen
       will be fewer than the number of bytes we occupy in memory.

       We need to find how much screen real-estate we will occupy to know how 
       many extra padding-characters we should send with the printing function.
      */
      visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
      extra_padding= data_length - visible_length;

      if (field_max_length > MAX_COLUMN_LENGTH)
        tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, FALSE);
      else
      {
          tee_print_sized_data(str, currlength, maxlength);
          tee_fputs(" |", PAGER);
        }
        if (num_flag[off] != 0) /* if it is numeric, we right-justify it */
          tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, TRUE);
        else 
          tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, FALSE);
      }
      tee_fputs(" | ", PAGER);
    }
    (void) tee_fputs("\n", PAGER);
  }
@@ -2349,10 +2366,9 @@ print_table_data(MYSQL_RES *result)


static void
tee_print_sized_data(const char *data, unsigned int length, unsigned int width)
tee_print_sized_data(const char *data, unsigned int data_length, unsigned int total_bytes_to_send, bool right_justified)
{
  /* 
    It is not a number, so print each character justified to the left.
    For '\0's print ASCII spaces instead, as '\0' is eaten by (at
    least my) console driver, and that messes up the pretty table
    grid.  (The \0 is also the reason we can't use fprintf() .) 
@@ -2360,9 +2376,14 @@ tee_print_sized_data(const char *data, unsigned int length, unsigned int width)
  unsigned int i;
  const char *p;

  tee_putc(' ', PAGER);
  total_bytes_to_send -= 1;  
  /* Off by one, perhaps mistakenly accounting for a terminating NUL. */

  if (right_justified) 
    for (i= 0; i < (total_bytes_to_send - data_length); i++)
      tee_putc((int)' ', PAGER);

  for (i= 0, p= data; i < length; i+= 1, p+= 1)
  for (i= 0, p= data; i < data_length; i+= 1, p+= 1)
  {
    if (*p == '\0')
      tee_putc((int)' ', PAGER);
@@ -2370,8 +2391,8 @@ tee_print_sized_data(const char *data, unsigned int length, unsigned int width)
      tee_putc((int)*p, PAGER);
  }

  i+= 1; 
  for (   ; i < width; i+= 1)
  if (! right_justified) 
    for (i= 0; i < (total_bytes_to_send - data_length); i++)
      tee_putc((int)' ', PAGER);
}

@@ -3361,7 +3382,7 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate)
    if (info_type == INFO_ERROR)
    {
      if (!opt_nobeep)
	putchar('\007');		      	/* This should make a bell */
        putchar('\a');		      	/* This should make a bell */
      vidattr(A_STANDOUT);
      if (error)
      {
+12 −3
Original line number Diff line number Diff line
@@ -74,5 +74,14 @@ c_cp932
+----------------------+------------+--------+
| >a   <               | b          | 123421 | 
| >a   <               | 0123456789 |      4 | 
| >abcd<               |            | 4      |
| >abcd<               | NULL       |      4 | 
+----------------------+------------+--------+
+------+------+---------------------------+
| i    | j    | k                         |
+------+------+---------------------------+
|    1 | NULL | NULL                      | 
| NULL | NULL | <-----------------------> | 
| NULL | NULL | <-----                    | 
| NULL | NULL | Τη γλώσσα                 | 
| NULL | NULL | ᛖᚴ ᚷᛖᛏ                    | 
+------+------+---------------------------+
+130 −0
Original line number Diff line number Diff line
@@ -108,6 +108,9 @@ set @fvar= 123.4567;
prepare stmt1 from @fvar;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '123.4567' at line 1
drop table t1,t2;
deallocate prepare stmt3;
deallocate prepare stmt4;
deallocate prepare stmt5;
PREPARE stmt1 FROM "select _utf8 'A' collate utf8_bin = ?";
set @var='A';
EXECUTE stmt1 USING @var;
@@ -253,6 +256,7 @@ set names latin1;
execute ``;
1234
1234
deallocate prepare ``;
set names default;
create table t1 (a varchar(10)) charset=utf8;
insert into t1 (a) values ('yahoo');
@@ -781,6 +785,7 @@ EXECUTE b12651;
1
DROP VIEW b12651_V1;
DROP TABLE b12651_T1, b12651_T2;
DEALLOCATE PREPARE b12651;
prepare stmt from "select @@time_zone";
execute stmt;
@@time_zone
@@ -873,6 +878,130 @@ length(a)
10
drop table t1;
deallocate prepare stmt;
create table t1 (col1 integer, col2 integer);
insert into t1 values(100,100),(101,101),(102,102),(103,103);
prepare stmt from 'select col1, col2 from t1 where (col1, col2) in ((?,?))';
set @a=100, @b=100;
execute stmt using @a,@b;
col1	col2
100	100
set @a=101, @b=101;
execute stmt using @a,@b;
col1	col2
101	101
set @a=102, @b=102;
execute stmt using @a,@b;
col1	col2
102	102
set @a=102, @b=103;
execute stmt using @a,@b;
col1	col2
deallocate prepare stmt;
drop table t1;
set @old_max_prepared_stmt_count= @@max_prepared_stmt_count;
show variables like 'max_prepared_stmt_count';
Variable_name	Value
max_prepared_stmt_count	16382
show variables like 'prepared_stmt_count';
Variable_name	Value
prepared_stmt_count	0
select @@max_prepared_stmt_count, @@prepared_stmt_count;
@@max_prepared_stmt_count	@@prepared_stmt_count
16382	0
set global max_prepared_stmt_count=-1;
select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
0
set global max_prepared_stmt_count=10000000000000000;
select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
1048576
set global max_prepared_stmt_count=default;
select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
16382
set @@max_prepared_stmt_count=1;
ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
set max_prepared_stmt_count=1;
ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
set local max_prepared_stmt_count=1;
ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
set local prepared_stmt_count=0;
ERROR HY000: Variable 'prepared_stmt_count' is a read only variable
set @@prepared_stmt_count=0;
ERROR HY000: Variable 'prepared_stmt_count' is a read only variable
set global prepared_stmt_count=1;
ERROR HY000: Variable 'prepared_stmt_count' is a read only variable
set global max_prepared_stmt_count=1;
select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
1
set global max_prepared_stmt_count=0;
select @@max_prepared_stmt_count, @@prepared_stmt_count;
@@max_prepared_stmt_count	@@prepared_stmt_count
0	0
prepare stmt from "select 1";
ERROR 42000: Can't create more than max_prepared_stmt_count statements (current value: 0)
select @@prepared_stmt_count;
@@prepared_stmt_count
0
set global max_prepared_stmt_count=1;
prepare stmt from "select 1";
select @@prepared_stmt_count;
@@prepared_stmt_count
1
prepare stmt1 from "select 1";
ERROR 42000: Can't create more than max_prepared_stmt_count statements (current value: 1)
select @@prepared_stmt_count;
@@prepared_stmt_count
1
deallocate prepare stmt;
select @@prepared_stmt_count;
@@prepared_stmt_count
0
prepare stmt from "select 1";
select @@prepared_stmt_count;
@@prepared_stmt_count
1
prepare stmt from "select 2";
select @@prepared_stmt_count;
@@prepared_stmt_count
1
select @@prepared_stmt_count, @@max_prepared_stmt_count;
@@prepared_stmt_count	@@max_prepared_stmt_count
1	1
set global max_prepared_stmt_count=0;
prepare stmt from "select 1";
ERROR 42000: Can't create more than max_prepared_stmt_count statements (current value: 0)
execute stmt;
ERROR HY000: Unknown prepared statement handler (stmt) given to EXECUTE
select @@prepared_stmt_count;
@@prepared_stmt_count
0
prepare stmt from "select 1";
ERROR 42000: Can't create more than max_prepared_stmt_count statements (current value: 0)
select @@prepared_stmt_count;
@@prepared_stmt_count
0
set global max_prepared_stmt_count=3;
select @@max_prepared_stmt_count, @@prepared_stmt_count;
@@max_prepared_stmt_count	@@prepared_stmt_count
3	0
prepare stmt from "select 1";
prepare stmt from "select 2";
prepare stmt1 from "select 3";
prepare stmt2 from "select 4";
ERROR 42000: Can't create more than max_prepared_stmt_count statements (current value: 3)
prepare stmt2 from "select 4";
ERROR 42000: Can't create more than max_prepared_stmt_count statements (current value: 3)
select @@max_prepared_stmt_count, @@prepared_stmt_count;
@@max_prepared_stmt_count	@@prepared_stmt_count
3	3
deallocate prepare stmt;
select @@max_prepared_stmt_count, @@prepared_stmt_count;
@@max_prepared_stmt_count	@@prepared_stmt_count
3	0
set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
create table t1 (id int);
prepare ins_call from "insert into t1 (id) values (1)";
execute ins_call;
@@ -883,6 +1012,7 @@ drop table t1;
create table t1 (a int, b int);
insert into t1 (a,b) values (2,8),(1,9),(3,7);
prepare stmt from "select * from t1 order by ?";
set @a=NULL;
execute stmt using @a;
a	b
2	8
+6 −0
Original line number Diff line number Diff line
@@ -61,3 +61,9 @@ drop table t1;
# Bug#16859 -- NULLs in columns must not truncate data as if a C-language "string".
#
--exec $MYSQL -t test -e "create table t1 (col1 binary(4), col2 varchar(10), col3 int); insert into t1 values ('a', 'b', 123421),('a ', '0123456789', 4), ('abcd', '', 4); select concat('>',col1,'<'), col2, col3 from t1; drop table t1;" 2>&1

#
# Bug#18265 -- mysql client: No longer right-justifies numeric columns
#
--exec $MYSQL -t --default-character-set utf8 test -e "create table t1 (i int, j int, k char(25) charset utf8); insert into t1 (i) values (1); insert into t1 (k) values ('<----------------------->'); insert into t1 (k) values ('<-----'); insert into t1 (k) values ('Τη γλώσσα'); insert into t1 (k) values ('ᛖᚴ ᚷᛖᛏ'); select * from t1; DROP TABLE t1;"
+143 −0
Original line number Diff line number Diff line
@@ -114,6 +114,9 @@ set @fvar= 123.4567;
prepare stmt1 from @fvar;

drop table t1,t2;
deallocate prepare stmt3;
deallocate prepare stmt4;
deallocate prepare stmt5;

#
# Bug #4105: Server crash on attempt to prepare a statement with character
@@ -257,6 +260,7 @@ prepare `ü` from 'select 1234';
execute `ü` ;
set names latin1;
execute ``;
deallocate prepare ``;
set names default;


@@ -823,6 +827,7 @@ EXECUTE b12651;

DROP VIEW b12651_V1;
DROP TABLE b12651_T1, b12651_T2;
DEALLOCATE PREPARE b12651;

#
# Bug#9359 "Prepared statements take snapshot of system vars at PREPARE
@@ -921,6 +926,143 @@ select length(a) from t1;
drop table t1;
deallocate prepare stmt;

#
# Bug#16248 "WHERE (col1,col2) IN ((?,?)) gives wrong results":
# check that ROW implementation is reexecution-friendly.
#
create table t1 (col1 integer, col2 integer);
insert into t1 values(100,100),(101,101),(102,102),(103,103);
prepare stmt from 'select col1, col2 from t1 where (col1, col2) in ((?,?))';
set @a=100, @b=100;
execute stmt using @a,@b;
set @a=101, @b=101;
execute stmt using @a,@b;
set @a=102, @b=102;
execute stmt using @a,@b;
set @a=102, @b=103;
execute stmt using @a,@b;
deallocate prepare stmt;
drop table t1;

#
# Bug#16365 Prepared Statements: DoS with too many open statements
# Check that the limit @@max_prpeared_stmt_count works.
#
# Save the old value
set @old_max_prepared_stmt_count= @@max_prepared_stmt_count;
#
# Disable prepared statement protocol: in this test we set
# @@max_prepared_stmt_count to 0 or 1 and would like to test the limit
# manually.
#
--disable_ps_protocol
#
# A. Check that the new variables are present in SHOW VARIABLES list.
#
show variables like 'max_prepared_stmt_count';
show variables like 'prepared_stmt_count';
#
# B. Check that the new variables are selectable.
#
select @@max_prepared_stmt_count, @@prepared_stmt_count;
#
# C. Check that max_prepared_stmt_count is settable (global only),
#    whereas prepared_stmt_count is readonly.
#
set global max_prepared_stmt_count=-1;
select @@max_prepared_stmt_count;
set global max_prepared_stmt_count=10000000000000000;
select @@max_prepared_stmt_count;
set global max_prepared_stmt_count=default;
select @@max_prepared_stmt_count;
--error ER_GLOBAL_VARIABLE
set @@max_prepared_stmt_count=1;
--error ER_GLOBAL_VARIABLE
set max_prepared_stmt_count=1;
--error ER_GLOBAL_VARIABLE
set local max_prepared_stmt_count=1;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
set local prepared_stmt_count=0;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
set @@prepared_stmt_count=0;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR 
set global prepared_stmt_count=1;
# set to a reasonable limit works
set global max_prepared_stmt_count=1;
select @@max_prepared_stmt_count;
#
# D. Check that the variables actually work.
#
set global max_prepared_stmt_count=0;
select @@max_prepared_stmt_count, @@prepared_stmt_count;
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
prepare stmt from "select 1";
select @@prepared_stmt_count;
set global max_prepared_stmt_count=1;
prepare stmt from "select 1";
select @@prepared_stmt_count;
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
prepare stmt1 from "select 1";
select @@prepared_stmt_count;
deallocate prepare stmt;
select @@prepared_stmt_count;
#
# E. Check that we can prepare a statement with the same name 
# successfully, without hitting the limit.
#
prepare stmt from "select 1";
select @@prepared_stmt_count;
prepare stmt from "select 2";
select @@prepared_stmt_count;
#
# F. We can set the max below the current count. In this case no new 
# statements should be allowed to prepare.
#
select @@prepared_stmt_count, @@max_prepared_stmt_count;
set global max_prepared_stmt_count=0;
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
prepare stmt from "select 1";
# Result: the old statement is deallocated, the new is not created.
--error 1243 # ER_UNKNOWN_STMT_HANDLER
execute stmt;
select @@prepared_stmt_count;
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
prepare stmt from "select 1";
select @@prepared_stmt_count;
#
# G. Show that the variables are up to date even after a connection with all
# statements in it was terminated.
#
set global max_prepared_stmt_count=3;
select @@max_prepared_stmt_count, @@prepared_stmt_count;
prepare stmt from "select 1";
connect (con1,localhost,root,,);
connection con1;
prepare stmt from "select 2";
prepare stmt1 from "select 3";
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
prepare stmt2 from "select 4";
connection default;
--error ER_MAX_PREPARED_STMT_COUNT_REACHED
prepare stmt2 from "select 4";
select @@max_prepared_stmt_count, @@prepared_stmt_count;
disconnect con1;
connection default;
# Wait for the connection to die: deal with a possible race
deallocate prepare stmt;
let $count= `select @@prepared_stmt_count`;
if ($count)
{
--sleep 2
  let $count= `select @@prepared_stmt_count`;
}
select @@max_prepared_stmt_count, @@prepared_stmt_count;
#
# Restore the old value.
#
set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
--enable_ps_protocol

# End of 4.1 tests

#
@@ -946,6 +1088,7 @@ insert into t1 (a,b) values (2,8),(1,9),(3,7);

# Will order by index
prepare stmt from "select * from t1 order by ?";
set @a=NULL;
execute stmt using @a;
set @a=1;
execute stmt using @a;
Loading