*** bash-2.05a/parse.y.orig Wed Oct 31 01:23:35 2001 --- bash-2.05a/parse.y Thu Jul 18 19:57:18 2002 *************** *** 18,23 **** --- 18,34 ---- with Bash; see the file LICENSE. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + /*===================================================================== + * This file was modified by SAKAIDA Masaaki. + * + * Change Log + * 1. Change "select" to "selects" in STRING_INT_ALIST. + * 2. Change read_token() in yylex() to read_EXEC_SQL_token(). + * 3. Add read_EXEC_SQL_token() routines. + * + *===================================================================== + */ + %{ #include "config.h" *************** *** 1570,1576 **** { "esac", ESAC }, { "for", FOR }, #if defined (SELECT_COMMAND) ! { "select", SELECT }, #endif { "while", WHILE }, { "until", UNTIL }, --- 1581,1590 ---- { "esac", ESAC }, { "for", FOR }, #if defined (SELECT_COMMAND) ! /*========================================= ! * Change "select" to "selects" for SQL. ! *========================================*/ ! { "selects", SELECT }, #endif { "while", WHILE }, { "until", UNTIL }, *************** *** 1967,1973 **** two_tokens_ago = token_before_that; token_before_that = last_read_token; last_read_token = current_token; ! current_token = read_token (READ); return (current_token); } --- 1981,1993 ---- two_tokens_ago = token_before_that; token_before_that = last_read_token; last_read_token = current_token; ! ! /*=============================================== ! * Change read_token() to read_EXEC_SQL_token() ! * Original: current_token = read_token (READ); ! *=============================================*/ ! (void)read_EXEC_SQL_token(); /* return current_toke */ ! return (current_token); } *************** *** 4218,4221 **** --- 4238,4567 ---- } return (REVERSE_LIST (wl, WORD_LIST *)); + } + + /*================================================================== + * Change "SQL;" string to 'exec_sql' token and one "SQL" token. + * + * If token is SQL reserved word, then this prase_SQL_statement starts. + * And it changes string to 'exec_sql "SQL"'. + * + * These routines have been made by SAKAIDA and KUBO-san. + * SAKAIDA Masaaki at 1999.11.11 -- Osaka,Japan + * KUBO Takehiro at 2000.11.12 -- Kanagawa,Japan + * + * Change Logs + * 2000.11.12: Modify fix_sized array to use RESIZE_MALLOCED_BUFFER() (KUBO) + * 2001.04.15: Modify source style. (SAKAIDA) + * 2001.04.15: Add SQL_word[] to "CHECKPOINT". (SAKAIDA) + * 2001.04.15: Change SQL_MAXLEN to 65536. (SAKAIDA) + * 2001.04.15: Change '\t' to ' '. (SAKAIDA) + * 2001.08.01: Fix the bug of parsing ';' surrounded in parenthesis.(SAKAIDA) + * 2001.11.26: Add 'ANALYZE' of SQL_word[]. + * 2002.05.09: Change local variables to static variable in read_EXEC_SQL_token(). + * 2002.05.10: Add the functionality of describing the '#' comment in SQL. + * 2002.07.15: Add "REINDEX" into SQL_word[]. (ISHIDA akio) + * 2002.07.17: Fix the bug of the double quotation surrounded by the single quotation + * and the bug of the single quotation surrounded by the double quotation. + * 2002.07.17: Add the functionality of processing the signle quotation data + * surrounded by the special signle quotation. + * + *================================================================== + */ + #include + + #define SQL_EXEC_WORD "exec_sql" + #define SQL_MAXLEN 65536 /* max. length for check */ + + char *SQL_word[] = { + "ABORT", "ALTER", "ANALYZE", + "BEGIN", + "CHECKPOINT", "CLOSE", "CLUSTER", + "COMMENT", "COMMIT", "CONNECT", + "COPY", + "CREATE", "DECLARE", "DELETE", + "DISCONNECT", "DROP", + "END", "EXPLAIN", "FETCH", + "GRANT", + "INSERT", "LISTEN", "LOAD", + "LOCK", + "MOVE", + "NOTIFY", + "REINDEX", "RESET", "REVOKE", "ROLLBACK", + "SELECT", "SET", "SHOW", + "TRUNCATE", + "UNLISTEN", "UPDATE", + "VACUUM", + (char *)NULL + }; + + static int read_EXEC_SQL_reserved_word(char *reserved, int *len); + static int read_EXEC_SQL_statement(char *reserved, int len); + + + int + read_EXEC_SQL_token() + /******************************************************************* + * (common variables) + * YYSTYPE yylval + * static int SQL_flag + * static int last_read_token + * char *ps2_prompt + * char **prompt_string_pointer + * %token TIME, TIMEOPT, WORD + * + * return current_token (global variable) + *******************************************************************/ + { + static int SQL_flag = 0; /* if a token is SQL then 1 else 0 */ + static char reserved[32]; /* e.g. "\"SELECT " */ + static int len = 0; /* reserved variable length */ + + if (SQL_flag == 0) + { + /*------ get token word ----------------*/ + current_token = read_token (READ); + + /*------ serach SQL reserved word ------*/ + SQL_flag = read_EXEC_SQL_reserved_word(reserved, &len); + } + else if(SQL_flag == 1) + { + /*--- change tokens to one SQL token ---*/ + (void)read_EXEC_SQL_statement(reserved, len); + SQL_flag = 0 ; + } + } + + static int + read_EXEC_SQL_reserved_word(char *reserved, int *len) + /******************************************************************** + * search SQL reserved word. + *******************************************************************/ + { + int SQL_flag = 0; + int len1, len2; + int index; + + reserved[0] = '\0'; + *len = 0; + + /*---------------- Starting SQL statement -------------------*/ + if( ( (last_read_token == '\n' || last_read_token == '\0') || + (last_read_token == TIME || last_read_token == TIMEOPT )) && + current_token == WORD ) + { + index= 0; + len1 = strlen(yylval.word->word); + + while( SQL_word[index] != NULL ) + { + len2 = strlen(SQL_word[index]); + + /*------- Compare WORD and SQL_start_word --------*/ + if( len1==len2 && strUcmp(yylval.word->word,&SQL_word[index][0],len1)==0 ) + { + /*----- Stock SQL reserved word ----------*/ + strcpy( reserved, "\"" ); + strcat( reserved, yylval.word->word ); + strcat( reserved, " " ); + *len = strlen(reserved); + + SQL_flag = 1 ; + + /*------- Change Token to 'exec_sql' -----*/ + free( yylval.word->word ); + yylval.word->word = xmalloc( sizeof(SQL_EXEC_WORD) + 1 ); + strcpy( yylval.word->word, SQL_EXEC_WORD); + break; + } + index++; + } + } + return(SQL_flag); + } + + + static int + read_EXEC_SQL_statement(char *reserved, int len) + /******************************************************************* + * change some tokens to one SQL token surrounded by double quote. + ******************************************************************/ + { + WORD_DESC *the_word; + int character, character2; + int sqt = 0, wqt = 0, ssqt = 0; + int retsize = TOKEN_DEFAULT_GROW_SIZE; + int retind = len; + int parenth = 0; + + /*---------- Setting of parser variable ------------*/ + the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC)); + the_word->word = (char *)xmalloc(TOKEN_DEFAULT_GROW_SIZE); + the_word->flags = 0; + + yylval.word = the_word; + current_token = WORD; + + /*---------- Initial settings ----------------------*/ + strcpy(the_word->word, reserved); + retind = len; + + while ((character = shell_getc (1)) != EOF) + { + character2 = '\0'; + + /*--------------- stock character ----------------------*/ + RESIZE_MALLOCED_BUFFER (the_word->word, retind, 1, retsize, + TOKEN_DEFAULT_GROW_SIZE); + the_word->word[retind++] = (char)character; + + /*-------------------- escape character -----------------*/ + if( character == '\\' ) + { + character2 = shell_getc (1); + RESIZE_MALLOCED_BUFFER (the_word->word, retind, 1, retsize, + TOKEN_DEFAULT_GROW_SIZE); + the_word->word[retind++] = (char)character2; + + /*-------- special single quote --------*/ + if( wqt == 0 && sqt == 0 && ssqt == 0 && character2 == '\'' ) + ssqt = 1; + else if( wqt == 0 && sqt == 0 && ssqt == 1 && character2 == '\'' ) + ssqt = 0; + + /*------------ double quote ------------*/ + if( sqt == 0 && wqt == 0 && character2 == '\"' ) + wqt = 1; + else if( sqt == 0 && wqt == 1 && character2 == '\"' ) + wqt = 0; + + continue; + } + + /*----------- special single quote(\'........\')--------------*/ + if( ssqt == 1 && character == '"' ) /* \'..."...\' */ + { + RESIZE_MALLOCED_BUFFER (the_word->word, retind, 1, retsize, + TOKEN_DEFAULT_GROW_SIZE); + the_word->word[retind-1] = '\\'; + the_word->word[retind++] = (char)character; + continue; + } + + if ( ssqt == 1 ) /* characters between special single quote */ + continue; + + + /*-------------------- single quote ---------------------*/ + if( wqt == 0 && sqt == 0 && character == '\'' ) /* start */ + { + sqt = 1; + continue; + } + + if( wqt == 0 && sqt == 1 && character == '\'' ) /* end of single quote */ + { + character2 = shell_getc (1); + RESIZE_MALLOCED_BUFFER (the_word->word, retind, 1, retsize, + TOKEN_DEFAULT_GROW_SIZE); + the_word->word[retind++] = (char)character2; + + if( character2 == '\'' ) /* '...''...' */ + continue; + + character = character2; /* end of single quote */ + sqt = 0; + } + + if( wqt == 0 && sqt == 1 && character == '"' ) /* '...\"...' */ + { + RESIZE_MALLOCED_BUFFER (the_word->word, retind, 1, retsize, + TOKEN_DEFAULT_GROW_SIZE); + the_word->word[retind-1] = '\\'; + the_word->word[retind++] = (char)character; + continue; + } + + if ( wqt == 0 && sqt == 1 ) /* characters between single quote */ + continue; + + /*-------------------- double quote ---------------------*/ + if( sqt == 0 && wqt == 0 && character == '\"' ) /* start */ + { + RESIZE_MALLOCED_BUFFER (the_word->word, retind, 1, retsize, + TOKEN_DEFAULT_GROW_SIZE); + the_word->word[retind-1] = '\\'; + the_word->word[retind++] = (char)character; + wqt = 1; + continue; + } + + if( sqt == 0 && wqt == 1 && character == '\"' ) /* end of single quote */ + { + RESIZE_MALLOCED_BUFFER (the_word->word, retind, 1, retsize, + TOKEN_DEFAULT_GROW_SIZE); + the_word->word[retind-1] = '\\'; + the_word->word[retind++] = (char)character; + wqt = 0; + continue; + } + + if ( sqt == 0 && wqt == 1 ) /* characters between double quote */ + continue; + + /*--------------- Comment -------------------------------*/ + if( sqt == 0 && wqt == 0 && character == '#' ) + { + the_word->word[retind-1] = ' '; + while ((character = shell_getc (1)) != EOF) + { + if( character == '\0' || character == '\n' ) + break; + } + } + + /*--------------- control character ---------------------*/ + if( sqt == 0 && wqt == 0 && character == '\n' ) + { + prompt_string_pointer = &ps2_prompt; + prompt_again (); + continue; + } + + if( sqt == 0 && wqt == 0 && character == '\t' ) + { + the_word->word[retind-1] = ' '; + continue; + } + + /*--------------- parentheses ----------------------------*/ + if( sqt == 0 && wqt == 0 && character == '(' ) + { + parenth++; + continue; + } + if( sqt == 0 && wqt == 0 && character == ')' ) + { + parenth--; + continue; + } + + /*--------------- end of SQL statement ------------------*/ + if( sqt == 0 && wqt == 0 && parenth == 0 && character == ';' ) + break; + + /*--------------- chaeck max length ---------------------*/ + if( retind > SQL_MAXLEN ) + { + fprintf (stderr, "Error: SQL statement too long(max.:%d).\n", SQL_MAXLEN); + break; + } + } + + RESIZE_MALLOCED_BUFFER (the_word->word, retind, 2, retsize, + TOKEN_DEFAULT_GROW_SIZE); + the_word->word[retind++] = '"'; + the_word->word[retind++] = '\0'; + }