From a855617f36d86706498358e30d7862d4ca42d652 Mon Sep 17 00:00:00 2001
From: "jcole@tetra.spaceapes.com" <>
Date: Mon, 12 Mar 2001 18:16:30 -0600
Subject: [PATCH] Added SQL_ANSI_MODE.

---
 Docs/manual.texi    | 24 ++++++++++++++++---
 sql/gen_lex_hash.cc |  8 ++++---
 sql/lex.h           |  1 +
 sql/mysql_priv.h    |  2 ++
 sql/sql_class.h     |  5 +++-
 sql/sql_lex.cc      | 56 ++++++++++++++++++++++++++-------------------
 sql/sql_parse.cc    |  4 ++++
 sql/sql_yacc.yy     | 23 ++++++++++++++++---
 8 files changed, 89 insertions(+), 34 deletions(-)

diff --git a/Docs/manual.texi b/Docs/manual.texi
index 999bb67250..6d797a08e0 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -895,7 +895,8 @@ Changes in release 4.0.x (Development; Alpha)
 
 Changes in release 3.23.x  (Stable)
 
-* News-3.23.34a::               
+* News-3.23.35::                Changes in release 3.23.35
+* News-3.23.34a::               Changes in release 3.23.34a
 * News-3.23.34::                Changes in release 3.23.34
 * News-3.23.33::                Changes in release 3.23.33
 * News-3.23.32::                Changes in release 3.23.32
@@ -22066,6 +22067,11 @@ or
 mysql> UPDATE mysql.user SET password=PASSWORD("newpass") where user="bob' and host="%.loc.gov";
 @end example
 
+@item SQL_ANSI_MODE = 0 | 1
+@cindex ANSI mode, SQL_ANSI_MODE
+If set to @code{1}, the connection will be in ANSI mode, as described in
+@ref{ANSI mode}.
+
 @item SQL_AUTO_IS_NULL = 0 | 1
 If set to @code{1} (default) then one can find the last inserted row
 for a table with an auto_increment row with the following construct:
@@ -42048,7 +42054,9 @@ users uses this code as the rest of the code and because of this we are
 not yet 100 % confident in this code.
 
 @menu
-* News-3.23.34a::               
+
+* News-3.23.35::                Changes in release 3.23.35
+* News-3.23.34a::               Changes in release 3.23.34a
 * News-3.23.34::                Changes in release 3.23.34
 * News-3.23.33::                Changes in release 3.23.33
 * News-3.23.32::                Changes in release 3.23.32
@@ -42086,9 +42094,19 @@ not yet 100 % confident in this code.
 * News-3.23.0::                 Changes in release 3.23.0
 @end menu
 
-@node News-3.23.34a, News-3.23.34, News-3.23.x, News-3.23.x
+@node News-3.23.35, News-3.23.34a, News-3.23.x, News-3.23.x
+@appendixsubsec Changes in release 3.23.35
+@itemize @bullet
+@item
+Added SQL_ANSI_MODE.  You can now switch to ANSI mode for only your 
+connection by running @code{SET SQL_ANSI_MODE=1}, and you can turn
+ANSI mode off with @code{SET SQL_ANSI_MODE=0}.
+@end itemize
+
+@node News-3.23.34a, News-3.23.34, News-3.23.35, News-3.23.x
 @appendixsubsec Changes in release 3.23.34a
 @itemize @bullet
+@item
 Add extra files to distribution to allow one to compile Innobase.
 @end itemize
 
diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc
index 78ffb26636..ca105257f1 100644
--- a/sql/gen_lex_hash.cc
+++ b/sql/gen_lex_hash.cc
@@ -254,7 +254,7 @@ you have to change 'main' to print out the new function\n");
   if (write_warning)
     fprintf (stderr,"Fatal error when generating hash for symbols\n\
 Didn't find suitable values for perfect hashing:\n\
-You have to edit gen_lex_hase.cc to generate a new hashing function.\n\
+You have to edit gen_lex_hash.cc to generate a new hashing function.\n\
 You can try running gen_lex_hash with --search to find a suitable value\n\
 Symbol array size = %d\n",function_mod);
   return -1;
@@ -472,8 +472,10 @@ int main(int argc,char **argv)
   int error;
 
   MY_INIT(argv[0]);
- start_value=5315771L; best_t1=6916833L;  best_t2=3813748L;  best_type=3; /* mode=5839  add=5  type: 0 */
- if (get_options(argc,(char **) argv))
+  start_value=4934807L;  best_t1=5181754L;  best_t2=1469522L;  best_type=0;
+  /* mode=4999  add=7  type: 0 */
+
+  if (get_options(argc,(char **) argv))
     exit(1);
 
   make_max_length_table();
diff --git a/sql/lex.h b/sql/lex.h
index 6f030aa524..6d676a3975 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -270,6 +270,7 @@ static SYMBOL symbols[] = {
   { "SLAVE",            SYM(SLAVE),0,0},
   { "SMALLINT",		SYM(SMALLINT),0,0},
   { "SONAME",		SYM(UDF_SONAME_SYM),0,0},
+  { "SQL_ANSI_MODE",    SYM(SQL_ANSI_MODE),0,0},
   { "SQL_AUTO_IS_NULL", SYM(SQL_AUTO_IS_NULL),0,0},
   { "SQL_BIG_RESULT",	SYM(SQL_BIG_RESULT),0,0},
   { "SQL_BIG_SELECTS",	SYM(SQL_BIG_SELECTS),0,0},
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index a975cab3c7..1f41e0a0d2 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -539,6 +539,8 @@ extern struct show_var_st init_vars[];
 extern struct show_var_st status_vars[];
 extern enum db_type default_table_type;
 
+extern uchar global_state_map[256];
+
 #ifndef __WIN__
 extern pthread_t signal_thread;
 #endif
diff --git a/sql/sql_class.h b/sql/sql_class.h
index f9720a3774..0a52f46d2a 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -280,7 +280,10 @@ public:
 
   ulong slave_proxy_id; // in slave thread we need to know in behalf of which
   // thread the query is being run to replicate temp tables properly 
-  
+
+  // thread-specific state map for lex parser
+  uchar state_map[256];
+
   THD();
   ~THD();
   bool store_globals();
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index b8d2ee13b0..f0357b99d7 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -75,7 +75,7 @@ inline int lex_casecmp(const char *s, const char *t, uint len)
 
 #include "lex_hash.h"
 
-static uchar state_map[256];
+uchar global_state_map[256];
 
 
 void lex_init(void)
@@ -89,42 +89,49 @@ void lex_init(void)
 
   VOID(pthread_key_create(&THR_LEX,NULL));
 
-  /* Fill state_map with states to get a faster parser */
+  /* Fill global_state_map with states to get a faster parser */
   for (i=0; i < 256 ; i++)
   {
     if (isalpha(i))
-      state_map[i]=(uchar) STATE_IDENT;
+      global_state_map[i]=(uchar) STATE_IDENT;
     else if (isdigit(i))
-      state_map[i]=(uchar) STATE_NUMBER_IDENT;
+      global_state_map[i]=(uchar) STATE_NUMBER_IDENT;
 #if defined(USE_MB) && defined(USE_MB_IDENT)
     else if (use_mb(default_charset_info) && my_ismbhead(default_charset_info, i))
-      state_map[i]=(uchar) STATE_IDENT;
+      global_state_map[i]=(uchar) STATE_IDENT;
 #endif
     else if (!isgraph(i))
-      state_map[i]=(uchar) STATE_SKIP;      
+      global_state_map[i]=(uchar) STATE_SKIP;      
     else
-      state_map[i]=(uchar) STATE_CHAR;
+      global_state_map[i]=(uchar) STATE_CHAR;
   }
-  state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) STATE_IDENT;
-  state_map[(uchar)'\'']=state_map[(uchar)'"']=(uchar) STATE_STRING;
-  state_map[(uchar)'-']=state_map[(uchar)'+']=(uchar) STATE_SIGNED_NUMBER;
-  state_map[(uchar)'.']=(uchar) STATE_REAL_OR_POINT;
-  state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) STATE_CMP_OP;
-  state_map[(uchar)'<']= (uchar) STATE_LONG_CMP_OP;
-  state_map[(uchar)'&']=state_map[(uchar)'|']=(uchar) STATE_BOOL;
-  state_map[(uchar)'#']=(uchar) STATE_COMMENT;
-  state_map[(uchar)';']=(uchar) STATE_COLON;
-  state_map[(uchar)':']=(uchar) STATE_SET_VAR;
-  state_map[0]=(uchar) STATE_EOL;
-  state_map[(uchar)'\\']= (uchar) STATE_ESCAPE;
-  state_map[(uchar)'/']= (uchar) STATE_LONG_COMMENT;
-  state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT;
-  state_map[(uchar)'@']= (uchar) STATE_USER_END;
-  state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER;
+  global_state_map[(uchar)'_']=
+    global_state_map[(uchar)'$']=(uchar) STATE_IDENT;
+  global_state_map[(uchar)'\'']=
+    global_state_map[(uchar)'"']=(uchar) STATE_STRING;
+  global_state_map[(uchar)'-']=
+    global_state_map[(uchar)'+']=(uchar) STATE_SIGNED_NUMBER;
+  global_state_map[(uchar)'.']=(uchar) STATE_REAL_OR_POINT;
+  global_state_map[(uchar)'>']=
+    global_state_map[(uchar)'=']=
+    global_state_map[(uchar)'!']= (uchar) STATE_CMP_OP;
+  global_state_map[(uchar)'<']= (uchar) STATE_LONG_CMP_OP;
+  global_state_map[(uchar)'&']=global_state_map[(uchar)'|']=(uchar) STATE_BOOL;
+  global_state_map[(uchar)'#']=(uchar) STATE_COMMENT;
+  global_state_map[(uchar)';']=(uchar) STATE_COLON;
+  global_state_map[(uchar)':']=(uchar) STATE_SET_VAR;
+  global_state_map[0]=(uchar) STATE_EOL;
+  global_state_map[(uchar)'\\']= (uchar) STATE_ESCAPE;
+  global_state_map[(uchar)'/']= (uchar) STATE_LONG_COMMENT;
+  global_state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT;
+  global_state_map[(uchar)'@']= (uchar) STATE_USER_END;
+  global_state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER;
+
   if (thd_startup_options & OPTION_ANSI_MODE)
   {
-    state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER;
+    global_state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER;
   }
+
   DBUG_VOID_RETURN;
 }
 
@@ -418,6 +425,7 @@ int yylex(void *arg)
   uint length;
   enum lex_states state,prev_state;
   LEX	*lex=current_lex;
+  uchar *state_map = lex->thd->state_map;
   YYSTYPE *yylval=(YYSTYPE*) arg;
 
   lex->yylval=yylval;			// The global state
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 31f59c5b85..5a2318ebfc 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -512,6 +512,10 @@ pthread_handler_decl(handle_one_connection,arg)
     return 0;
   }
 
+  // copy global state map into thread
+  for(int x=0; x < 256; x++)
+    thd->state_map[x] = global_state_map[x];
+
   do
   {
     int error;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index fa44e7799f..9a0badda09 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -394,6 +394,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
 %token  END
 %token  THEN_SYM
 
+%token  SQL_ANSI_MODE
 %token	SQL_BIG_TABLES
 %token	SQL_BIG_SELECTS
 %token	SQL_SELECT_LIMIT
@@ -2603,6 +2604,18 @@ option_value:
 	  else
 	    Lex->options|= OPTION_NOT_AUTO_COMMIT;
 	}
+        | SQL_ANSI_MODE equal NUM
+        { 
+          if(atoi($3.str) == 0) 
+          {
+            Lex->options &= ~(OPTION_ANSI_MODE);
+            Lex->thd->state_map[(uchar) '"'] = STATE_STRING;
+          } else {
+            Lex->options |= OPTION_ANSI_MODE;
+            Lex->thd->state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER;
+          }
+        }
+
 	| SQL_SELECT_LIMIT equal ULONG_NUM
 	{
 	  Lex->select_limit= $3;
@@ -2697,16 +2710,20 @@ text_or_password:
 	  }
 
 set_option:
-	SQL_BIG_TABLES		{ $$= OPTION_BIG_TABLES; }
+       	SQL_BIG_TABLES	        { $$= OPTION_BIG_TABLES; }
 	| SQL_BIG_SELECTS	{ $$= OPTION_BIG_SELECTS; }
 	| SQL_LOG_OFF		{ $$= OPTION_LOG_OFF; }
 	| SQL_LOG_UPDATE
            {
-	     $$= (opt_sql_bin_update)? OPTION_UPDATE_LOG|OPTION_BIN_LOG: OPTION_UPDATE_LOG ;
+	     $$= (opt_sql_bin_update)? 
+                        OPTION_UPDATE_LOG|OPTION_BIN_LOG: 
+                        OPTION_UPDATE_LOG ;
 	   }
 	| SQL_LOG_BIN
            {
-	     $$= (opt_sql_bin_update)? OPTION_UPDATE_LOG|OPTION_BIN_LOG: OPTION_BIN_LOG ;
+	     $$= (opt_sql_bin_update)? 
+                        OPTION_UPDATE_LOG|OPTION_BIN_LOG: 
+                        OPTION_BIN_LOG ;
 	   }
 	| SQL_WARNINGS		{ $$= OPTION_WARNINGS; }
 	| SQL_LOW_PRIORITY_UPDATES { $$= OPTION_LOW_PRIORITY_UPDATES; }
-- 
2.30.9