Commit 05597586 authored by monty@tik.mysql.fi's avatar monty@tik.mysql.fi

Added support for ANSI SQL X'hex-string' format.

Fixed mysqldump to use -- instead of # as comment characters.
Removed support for the 3.20 protocol format
parent 0b8f1595
...@@ -14374,12 +14374,16 @@ like an integer (64-bit precision). In string context these act like a binary ...@@ -14374,12 +14374,16 @@ like an integer (64-bit precision). In string context these act like a binary
string where each pair of hex digits is converted to a character: string where each pair of hex digits is converted to a character:
@example @example
mysql> SELECT x'FF'
-> 255
mysql> SELECT 0xa+0; mysql> SELECT 0xa+0;
-> 10 -> 10
mysql> select 0x5061756c; mysql> select 0x5061756c;
-> Paul -> Paul
@end example @end example
The x'hexstring' syntax (new in 4.0) is based on ANSI SQL and the 0x
syntax is based on ODBC.
Hexadecimal strings are often used by ODBC to give values for BLOB columns. Hexadecimal strings are often used by ODBC to give values for BLOB columns.
@tindex NULL value @tindex NULL value
...@@ -46427,6 +46431,8 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. ...@@ -46427,6 +46431,8 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@itemize @bullet @itemize @bullet
@item @item
Allow ANSI SQL syntax @code{X'hexadecimal-number'}
@item
Added @code{ALTER TABLE table_name DISABLE KEYS} and Added @code{ALTER TABLE table_name DISABLE KEYS} and
@code{ALTER TABLE table_name ENABLE KEYS} commands. @code{ALTER TABLE table_name ENABLE KEYS} commands.
@item @item
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
** Tnu Samuel <tonu@please.do.not.remove.this.spam.ee> ** Tnu Samuel <tonu@please.do.not.remove.this.spam.ee>
**/ **/
#define DUMP_VERSION "8.14" #define DUMP_VERSION "8.15"
#include <global.h> #include <global.h>
#include <my_sys.h> #include <my_sys.h>
...@@ -274,12 +274,12 @@ puts("\ ...@@ -274,12 +274,12 @@ puts("\
static void write_heder(FILE *sql_file, char *db_name) static void write_heder(FILE *sql_file, char *db_name)
{ {
fprintf(sql_file, "# MySQL dump %s\n#\n", DUMP_VERSION); fprintf(sql_file, "-- MySQL dump %s\n#\n", DUMP_VERSION);
fprintf(sql_file, "# Host: %s Database: %s\n", fprintf(sql_file, "-- Host: %s Database: %s\n",
current_host ? current_host : "localhost", db_name ? db_name : ""); current_host ? current_host : "localhost", db_name ? db_name : "");
fputs("#--------------------------------------------------------\n", fputs("---------------------------------------------------------\n",
sql_file); sql_file);
fprintf(sql_file, "# Server version\t%s\n", fprintf(sql_file, "-- Server version\t%s\n",
mysql_get_server_info(&mysql_connection)); mysql_get_server_info(&mysql_connection));
return; return;
} /* write_heder */ } /* write_heder */
...@@ -515,7 +515,7 @@ static int dbConnect(char *host, char *user,char *passwd) ...@@ -515,7 +515,7 @@ static int dbConnect(char *host, char *user,char *passwd)
DBUG_ENTER("dbConnect"); DBUG_ENTER("dbConnect");
if (verbose) if (verbose)
{ {
fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost"); fprintf(stderr, "-- Connecting to %s...\n", host ? host : "localhost");
} }
mysql_init(&mysql_connection); mysql_init(&mysql_connection);
if (opt_compress) if (opt_compress)
...@@ -542,7 +542,7 @@ static int dbConnect(char *host, char *user,char *passwd) ...@@ -542,7 +542,7 @@ static int dbConnect(char *host, char *user,char *passwd)
static void dbDisconnect(char *host) static void dbDisconnect(char *host)
{ {
if (verbose) if (verbose)
fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost"); fprintf(stderr, "-- Disconnecting from %s...\n", host ? host : "localhost");
mysql_close(sock); mysql_close(sock);
} /* dbDisconnect */ } /* dbDisconnect */
...@@ -608,7 +608,7 @@ static uint getTableStructure(char *table, char* db) ...@@ -608,7 +608,7 @@ static uint getTableStructure(char *table, char* db)
delayed= opt_delayed ? " DELAYED " : ""; delayed= opt_delayed ? " DELAYED " : "";
if (verbose) if (verbose)
fprintf(stderr, "# Retrieving table structure for table %s...\n", table); fprintf(stderr, "-- Retrieving table structure for table %s...\n", table);
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", opt_quoted); sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", opt_quoted);
table_name=quote_name(table,table_buff); table_name=quote_name(table,table_buff);
...@@ -837,7 +837,7 @@ static uint getTableStructure(char *table, char* db) ...@@ -837,7 +837,7 @@ static uint getTableStructure(char *table, char* db)
{ /* If old MySQL version */ { /* If old MySQL version */
if (verbose) if (verbose)
fprintf(stderr, fprintf(stderr,
"# Warning: Couldn't get status information for table '%s' (%s)\n", "-- Warning: Couldn't get status information for table '%s' (%s)\n",
table,mysql_error(sock)); table,mysql_error(sock));
} }
} }
...@@ -934,7 +934,7 @@ static void dumpTable(uint numFields, char *table) ...@@ -934,7 +934,7 @@ static void dumpTable(uint numFields, char *table)
ulong rownr, row_break, total_length, init_length; ulong rownr, row_break, total_length, init_length;
if (verbose) if (verbose)
fprintf(stderr, "# Sending SELECT query...\n"); fprintf(stderr, "-- Sending SELECT query...\n");
if (path) if (path)
{ {
char filename[FN_REFLEN], tmp_path[FN_REFLEN]; char filename[FN_REFLEN], tmp_path[FN_REFLEN];
...@@ -977,10 +977,10 @@ static void dumpTable(uint numFields, char *table) ...@@ -977,10 +977,10 @@ static void dumpTable(uint numFields, char *table)
sprintf(query, "SELECT * FROM %s", quote_name(table,table_buff)); sprintf(query, "SELECT * FROM %s", quote_name(table,table_buff));
if (where) if (where)
{ {
fprintf(result_file,"# WHERE: %s\n",where); fprintf(result_file,"-- WHERE: %s\n",where);
strxmov(strend(query), " WHERE ",where,NullS); strxmov(strend(query), " WHERE ",where,NullS);
} }
fputs("#\n\n", result_file); fputs("\n\n", result_file);
if (mysql_query(sock, query)) if (mysql_query(sock, query))
{ {
...@@ -997,7 +997,7 @@ static void dumpTable(uint numFields, char *table) ...@@ -997,7 +997,7 @@ static void dumpTable(uint numFields, char *table)
return; return;
} }
if (verbose) if (verbose)
fprintf(stderr, "# Retrieving rows...\n"); fprintf(stderr, "-- Retrieving rows...\n");
if (mysql_num_fields(res) != numFields) if (mysql_num_fields(res) != numFields)
{ {
fprintf(stderr,"%s: Error in field count for table: '%s' ! Aborting.\n", fprintf(stderr,"%s: Error in field count for table: '%s' ! Aborting.\n",
......
...@@ -322,17 +322,9 @@ net_safe_read(MYSQL *mysql) ...@@ -322,17 +322,9 @@ net_safe_read(MYSQL *mysql)
if (len > 3) if (len > 3)
{ {
char *pos=(char*) net->read_pos+1; char *pos=(char*) net->read_pos+1;
if (mysql->protocol_version > 9)
{ /* New client protocol */
net->last_errno=uint2korr(pos); net->last_errno=uint2korr(pos);
pos+=2; pos+=2;
len-=2; len-=2;
}
else
{
net->last_errno=CR_UNKNOWN_ERROR;
len--;
}
(void) strmake(net->last_error,(char*) pos, (void) strmake(net->last_error,(char*) pos,
min(len,sizeof(net->last_error)-1)); min(len,sizeof(net->last_error)-1));
} }
...@@ -1404,6 +1396,7 @@ mysql_ssl_clear(MYSQL *mysql) ...@@ -1404,6 +1396,7 @@ mysql_ssl_clear(MYSQL *mysql)
** If host == 0 then use localhost ** If host == 0 then use localhost
**************************************************************************/ **************************************************************************/
#ifdef USE_OLD_FUNCTIONS
MYSQL * STDCALL MYSQL * STDCALL
mysql_connect(MYSQL *mysql,const char *host, mysql_connect(MYSQL *mysql,const char *host,
const char *user, const char *passwd) const char *user, const char *passwd)
...@@ -1420,6 +1413,7 @@ mysql_connect(MYSQL *mysql,const char *host, ...@@ -1420,6 +1413,7 @@ mysql_connect(MYSQL *mysql,const char *host,
DBUG_RETURN(res); DBUG_RETURN(res);
} }
} }
#endif
/* /*
...@@ -1651,8 +1645,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -1651,8 +1645,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
DBUG_DUMP("packet",(char*) net->read_pos,10); DBUG_DUMP("packet",(char*) net->read_pos,10);
DBUG_PRINT("info",("mysql protocol version %d, server=%d", DBUG_PRINT("info",("mysql protocol version %d, server=%d",
PROTOCOL_VERSION, mysql->protocol_version)); PROTOCOL_VERSION, mysql->protocol_version));
if (mysql->protocol_version != PROTOCOL_VERSION && if (mysql->protocol_version != PROTOCOL_VERSION)
mysql->protocol_version != PROTOCOL_VERSION-1)
{ {
net->last_errno= CR_VERSION_ERROR; net->last_errno= CR_VERSION_ERROR;
sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version, sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version,
...@@ -2547,6 +2540,7 @@ mysql_list_processes(MYSQL *mysql) ...@@ -2547,6 +2540,7 @@ mysql_list_processes(MYSQL *mysql)
} }
#ifdef USE_OLD_FUNCTIONS
int STDCALL int STDCALL
mysql_create_db(MYSQL *mysql, const char *db) mysql_create_db(MYSQL *mysql, const char *db)
{ {
...@@ -2563,6 +2557,7 @@ mysql_drop_db(MYSQL *mysql, const char *db) ...@@ -2563,6 +2557,7 @@ mysql_drop_db(MYSQL *mysql, const char *db)
DBUG_PRINT("enter",("db: %s",db)); DBUG_PRINT("enter",("db: %s",db));
DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(uint) strlen(db),0)); DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(uint) strlen(db),0));
} }
#endif
int STDCALL int STDCALL
......
...@@ -258,8 +258,6 @@ static void usage(void) ...@@ -258,8 +258,6 @@ static void usage(void)
-k, --keys-used=# Tell MyISAM to update only some specific keys. # is a\n\ -k, --keys-used=# Tell MyISAM to update only some specific keys. # is a\n\
bit mask of which keys to use. This can be used to\n\ bit mask of which keys to use. This can be used to\n\
get faster inserts!\n\ get faster inserts!\n\
-l, --no-symlinks Do not follow symbolic links. Normally\n\
myisamchk repairs the table a symlink points at.\n\
-r, --recover Can fix almost anything except unique keys that aren't\n\ -r, --recover Can fix almost anything except unique keys that aren't\n\
unique.\n\ unique.\n\
-n, --sort-recover Force recovering with sorting even if the temporary\n\ -n, --sort-recover Force recovering with sorting even if the temporary\n\
......
...@@ -2,5 +2,9 @@ ...@@ -2,5 +2,9 @@
A 65 9223372036854775807 -1 A 65 9223372036854775807 -1
0x31+1 concat(0x31)+1 -0xf 0x31+1 concat(0x31)+1 -0xf
50 2 -15 50 2 -15
x'31' X'ffff'+0
1 65535
table type possible_keys key key_len ref rows Extra table type possible_keys key key_len ref rows Extra
t1 const UNIQ UNIQ 8 const 1 t1 const UNIQ UNIQ 8 const 1
x xx
1 2
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
select 0x41,0x41+0,0x41 | 0x7fffffffffffffff | 0,0xffffffffffffffff | 0 ; select 0x41,0x41+0,0x41 | 0x7fffffffffffffff | 0,0xffffffffffffffff | 0 ;
select 0x31+1,concat(0x31)+1,-0xf; select 0x31+1,concat(0x31)+1,-0xf;
select x'31',X'ffff'+0;
# #
# Test of hex constants in WHERE: # Test of hex constants in WHERE:
...@@ -14,3 +15,18 @@ insert into t1 set UNIQ=0x38afba1d73e6a18a; ...@@ -14,3 +15,18 @@ insert into t1 set UNIQ=0x38afba1d73e6a18a;
insert into t1 set UNIQ=123; insert into t1 set UNIQ=123;
explain select * from t1 where UNIQ=0x38afba1d73e6a18a; explain select * from t1 where UNIQ=0x38afba1d73e6a18a;
drop table t1; drop table t1;
#
# Test error conditions
#
--error 1064
select x'hello';
--error 1064
select 0xfg;
#
# Test likely error conditions
#
create table t1 select 1 as x, 2 as xx;
select x,xx from t1;
drop table t1;
...@@ -430,7 +430,7 @@ int yylex(void *arg) ...@@ -430,7 +430,7 @@ int yylex(void *arg)
switch(state) { switch(state) {
case STATE_OPERATOR_OR_IDENT: // Next is operator or keyword case STATE_OPERATOR_OR_IDENT: // Next is operator or keyword
case STATE_START: // Start of token case STATE_START: // Start of token
// Skipp startspace // Skip startspace
for (c=yyGet() ; (state_map[c] == STATE_SKIP) ; c= yyGet()) for (c=yyGet() ; (state_map[c] == STATE_SKIP) ; c= yyGet())
{ {
if (c == '\n') if (c == '\n')
...@@ -458,6 +458,11 @@ int yylex(void *arg) ...@@ -458,6 +458,11 @@ int yylex(void *arg)
return((int) c); return((int) c);
case STATE_IDENT: // Incomplete keyword or ident case STATE_IDENT: // Incomplete keyword or ident
if ((c == 'x' || c == 'X') && yyPeek() == '\'')
{ // Found x'hex-number'
state=STATE_HEX_NUMBER;
break;
}
#if defined(USE_MB) && defined(USE_MB_IDENT) #if defined(USE_MB) && defined(USE_MB_IDENT)
if (use_mb(default_charset_info)) if (use_mb(default_charset_info))
{ {
...@@ -520,7 +525,7 @@ int yylex(void *arg) ...@@ -520,7 +525,7 @@ int yylex(void *arg)
c=yyGet(); // should be '.' c=yyGet(); // should be '.'
return((int) c); return((int) c);
case STATE_NUMBER_IDENT: // number or ident which starts with num case STATE_NUMBER_IDENT: // number or ident which num-start
while (isdigit((c = yyGet()))) ; while (isdigit((c = yyGet()))) ;
if (state_map[c] != STATE_IDENT) if (state_map[c] != STATE_IDENT)
{ // Can't be identifier { // Can't be identifier
...@@ -546,10 +551,10 @@ int yylex(void *arg) ...@@ -546,10 +551,10 @@ int yylex(void *arg)
lex->tok_start[0] == '0' ) lex->tok_start[0] == '0' )
{ // Varbinary { // Varbinary
while (isxdigit((c = yyGet()))) ; while (isxdigit((c = yyGet()))) ;
if ((lex->ptr - lex->tok_start) >= 4) if ((lex->ptr - lex->tok_start) >= 4 && state_map[c] != STATE_IDENT)
{ {
yylval->lex_str=get_token(lex,yyLength()); yylval->lex_str=get_token(lex,yyLength());
yylval->lex_str.str+=2; // Skipp 0x yylval->lex_str.str+=2; // Skip 0x
yylval->lex_str.length-=2; yylval->lex_str.length-=2;
lex->yytoklen-=2; lex->yytoklen-=2;
return (HEX_NUM); return (HEX_NUM);
...@@ -604,20 +609,21 @@ int yylex(void *arg) ...@@ -604,20 +609,21 @@ int yylex(void *arg)
return(IDENT); return(IDENT);
case STATE_USER_VARIABLE_DELIMITER: case STATE_USER_VARIABLE_DELIMITER:
lex->tok_start=lex->ptr; // Skipp first ` lex->tok_start=lex->ptr; // Skip first `
while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER && while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER &&
c != (uchar) NAMES_SEP_CHAR) ; c != (uchar) NAMES_SEP_CHAR) ;
yylval->lex_str=get_token(lex,yyLength()); yylval->lex_str=get_token(lex,yyLength());
if (lex->convert_set) if (lex->convert_set)
lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen); lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
if (state_map[c] == STATE_USER_VARIABLE_DELIMITER) if (state_map[c] == STATE_USER_VARIABLE_DELIMITER)
yySkip(); // Skipp end ` yySkip(); // Skip end `
return(IDENT); return(IDENT);
case STATE_SIGNED_NUMBER: // Incomplete signed number case STATE_SIGNED_NUMBER: // Incomplete signed number
if (prev_state == STATE_OPERATOR_OR_IDENT) if (prev_state == STATE_OPERATOR_OR_IDENT)
{ {
if (c == '-' && yyPeek() == '-' && isspace(yyPeek2())) if (c == '-' && yyPeek() == '-' &&
(isspace(yyPeek2()) || iscntrl(yyPeek2())))
state=STATE_COMMENT; state=STATE_COMMENT;
else else
state= STATE_CHAR; // Must be operator state= STATE_CHAR; // Must be operator
...@@ -657,7 +663,7 @@ int yylex(void *arg) ...@@ -657,7 +663,7 @@ int yylex(void *arg)
{ {
c = yyGet(); c = yyGet();
if (c == '-' || c == '+') if (c == '-' || c == '+')
c = yyGet(); // Skipp sign c = yyGet(); // Skip sign
if (!isdigit(c)) if (!isdigit(c))
{ // No digit after sign { // No digit after sign
state= STATE_CHAR; state= STATE_CHAR;
...@@ -670,6 +676,21 @@ int yylex(void *arg) ...@@ -670,6 +676,21 @@ int yylex(void *arg)
yylval->lex_str=get_token(lex,yyLength()); yylval->lex_str=get_token(lex,yyLength());
return(REAL_NUM); return(REAL_NUM);
case STATE_HEX_NUMBER: // Found x'hexstring'
yyGet(); // Skip '
while (isxdigit((c = yyGet()))) ;
length=(lex->ptr - lex->tok_start); // Length of hexnum+3
if (!(length & 1) || c != '\'')
{
return(ABORT_SYM); // Illegal hex constant
}
yyGet(); // get_token makes an unget
yylval->lex_str=get_token(lex,length);
yylval->lex_str.str+=2; // Skip x'
yylval->lex_str.length-=3; // Don't count x' and last '
lex->yytoklen-=3;
return (HEX_NUM);
case STATE_CMP_OP: // Incomplete comparison operator case STATE_CMP_OP: // Incomplete comparison operator
if (state_map[yyPeek()] == STATE_CMP_OP || if (state_map[yyPeek()] == STATE_CMP_OP ||
state_map[yyPeek()] == STATE_LONG_CMP_OP) state_map[yyPeek()] == STATE_LONG_CMP_OP)
......
...@@ -65,6 +65,7 @@ enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT, ...@@ -65,6 +65,7 @@ enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
STATE_FOUND_IDENT, STATE_FOUND_IDENT,
STATE_SIGNED_NUMBER, STATE_SIGNED_NUMBER,
STATE_REAL, STATE_REAL,
STATE_HEX_NUMBER,
STATE_CMP_OP, STATE_CMP_OP,
STATE_LONG_CMP_OP, STATE_LONG_CMP_OP,
STATE_STRING, STATE_STRING,
......
...@@ -133,6 +133,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -133,6 +133,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token BINLOG_SYM %token BINLOG_SYM
%token EVENTS_SYM %token EVENTS_SYM
%token ABORT_SYM
%token ACTION %token ACTION
%token AGGREGATE_SYM %token AGGREGATE_SYM
%token ALL %token ALL
...@@ -3022,7 +3023,7 @@ option_value: ...@@ -3022,7 +3023,7 @@ option_value:
| SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM | SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM
{ {
pthread_mutex_lock(&LOCK_slave); pthread_mutex_lock(&LOCK_slave);
if(slave_running) if (slave_running)
send_error(&current_thd->net, ER_SLAVE_MUST_STOP); send_error(&current_thd->net, ER_SLAVE_MUST_STOP);
else else
slave_skip_counter = $3; slave_skip_counter = $3;
......
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