From: Date: February 2 2007 10:02pm Subject: Connector/J commit: r6301 - branches/branch_5_0/connector-j branches/branch_5_0/connector-j/src/com/mysql/jdbc trunk/connector-j trunk/connector-j/src/com/mysql/jdbc List-Archive: http://lists.mysql.com/commits/19282 X-Bug: 24794 Message-Id: <200702022102.l12L24qV010410@bk-internal.mysql.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modified: branches/branch_5_0/connector-j/CHANGES branches/branch_5_0/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java trunk/connector-j/CHANGES trunk/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java Log: Fixed BUG#24794 - DatabaseMetaData.getSQLKeywords() doesn't return all reserved words for current MySQL version. The current fix/implementation returns keywords for MySQL-5.1, and doesn't distinguish between different versions of the server. Modified: branches/branch_5_0/connector-j/CHANGES =================================================================== --- branches/branch_5_0/connector-j/CHANGES 2007-02-02 19:16:21 UTC (rev 6300) +++ branches/branch_5_0/connector-j/CHANGES 2007-02-02 21:02:01 UTC (rev 6301) @@ -111,6 +111,11 @@ non-server-side prepared statements. (Enable old implementation with "useFastDateParsing=false" as a configuration parameter). + - Fixed BUG#24794 - DatabaseMetaData.getSQLKeywords() doesn't return + all reserved words for current MySQL version. The current fix/implementation + returns keywords for MySQL-5.1, and doesn't distinguish between different + versions of the server. + 10-20-06 - Version 5.0.4 - Fixed BUG#21379 - column names don't match metadata in cases Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java =================================================================== --- branches/branch_5_0/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java 2007-02-02 19:16:21 UTC (rev 6300) +++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java 2007-02-02 21:02:01 UTC (rev 6301) @@ -82,7 +82,7 @@ abstract void forEach(Object each) throws SQLException; } - + protected abstract class IteratorWithCleanup { abstract void close() throws SQLException; @@ -90,7 +90,7 @@ abstract Object next() throws SQLException; } - + class LocalAndReferencedColumns { String constraintName; @@ -424,6 +424,8 @@ } } + private static String mysqlKeywordsThatArentSQL92; + private static final int DEFERRABILITY = 13; private static final int DELETE_RULE = 10; @@ -463,6 +465,140 @@ private static final byte[] VIEW_AS_BYTES = "VIEW".getBytes(); + static { + // Current as-of MySQL-5.1.16 + String[] allMySQLKeywords = new String[] { "ACCESSIBLE", "ADD", "ALL", + "ALTER", "ANALYZE", "AND", "AS", "ASC", "ASENSITIVE", "BEFORE", + "BETWEEN", "BIGINT", "BINARY", "BLOB", "BOTH", "BY", "CALL", + "CASCADE", "CASE", "CHANGE", "CHAR", "CHARACTER", "CHECK", + "COLLATE", "COLUMN", "CONDITION", "CONNECTION", "CONSTRAINT", + "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT_DATE", + "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", + "DATABASE", "DATABASES", "DAY_HOUR", "DAY_MICROSECOND", + "DAY_MINUTE", "DAY_SECOND", "DEC", "DECIMAL", "DECLARE", + "DEFAULT", "DELAYED", "DELETE", "DESC", "DESCRIBE", + "DETERMINISTIC", "DISTINCT", "DISTINCTROW", "DIV", "DOUBLE", + "DROP", "DUAL", "EACH", "ELSE", "ELSEIF", "ENCLOSED", + "ESCAPED", "EXISTS", "EXIT", "EXPLAIN", "FALSE", "FETCH", + "FLOAT", "FLOAT4", "FLOAT8", "FOR", "FORCE", "FOREIGN", "FROM", + "FULLTEXT", "GRANT", "GROUP", "HAVING", "HIGH_PRIORITY", + "HOUR_MICROSECOND", "HOUR_MINUTE", "HOUR_SECOND", "IF", + "IGNORE", "IN", "INDEX", "INFILE", "INNER", "INOUT", + "INSENSITIVE", "INSERT", "INT", "INT1", "INT2", "INT3", "INT4", + "INT8", "INTEGER", "INTERVAL", "INTO", "IS", "ITERATE", "JOIN", + "KEY", "KEYS", "KILL", "LEADING", "LEAVE", "LEFT", "LIKE", + "LIMIT", "LINEAR", "LINES", "LOAD", "LOCALTIME", + "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT", + "LOOP", "LOW_PRIORITY", "MATCH", "MEDIUMBLOB", "MEDIUMINT", + "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", + "MINUTE_SECOND", "MOD", "MODIFIES", "NATURAL", "NOT", + "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON", "OPTIMIZE", + "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER", + "OUTFILE", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE", + "RANGE", "READ", "READS", "READ_ONLY", "READ_WRITE", "REAL", + "REFERENCES", "REGEXP", "RELEASE", "RENAME", "REPEAT", + "REPLACE", "REQUIRE", "RESTRICT", "RETURN", "REVOKE", "RIGHT", + "RLIKE", "SCHEMA", "SCHEMAS", "SECOND_MICROSECOND", "SELECT", + "SENSITIVE", "SEPARATOR", "SET", "SHOW", "SMALLINT", "SPATIAL", + "SPECIFIC", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", + "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", + "SSL", "STARTING", "STRAIGHT_JOIN", "TABLE", "TERMINATED", + "THEN", "TINYBLOB", "TINYINT", "TINYTEXT", "TO", "TRAILING", + "TRIGGER", "TRUE", "UNDO", "UNION", "UNIQUE", "UNLOCK", + "UNSIGNED", "UPDATE", "USAGE", "USE", "USING", "UTC_DATE", + "UTC_TIME", "UTC_TIMESTAMP", "VALUES", "VARBINARY", "VARCHAR", + "VARCHARACTER", "VARYING", "WHEN", "WHERE", "WHILE", "WITH", + "WRITE", "X509", "XOR", "YEAR_MONTH", "ZEROFILL" }; + + String[] sql92Keywords = new String[] { "ABSOLUTE", "EXEC", "OVERLAPS", + "ACTION", "EXECUTE", "PAD", "ADA", "EXISTS", "PARTIAL", "ADD", + "EXTERNAL", "PASCAL", "ALL", "EXTRACT", "POSITION", "ALLOCATE", + "FALSE", "PRECISION", "ALTER", "FETCH", "PREPARE", "AND", + "FIRST", "PRESERVE", "ANY", "FLOAT", "PRIMARY", "ARE", "FOR", + "PRIOR", "AS", "FOREIGN", "PRIVILEGES", "ASC", "FORTRAN", + "PROCEDURE", "ASSERTION", "FOUND", "PUBLIC", "AT", "FROM", + "READ", "AUTHORIZATION", "FULL", "REAL", "AVG", "GET", + "REFERENCES", "BEGIN", "GLOBAL", "RELATIVE", "BETWEEN", "GO", + "RESTRICT", "BIT", "GOTO", "REVOKE", "BIT_LENGTH", "GRANT", + "RIGHT", "BOTH", "GROUP", "ROLLBACK", "BY", "HAVING", "ROWS", + "CASCADE", "HOUR", "SCHEMA", "CASCADED", "IDENTITY", "SCROLL", + "CASE", "IMMEDIATE", "SECOND", "CAST", "IN", "SECTION", + "CATALOG", "INCLUDE", "SELECT", "CHAR", "INDEX", "SESSION", + "CHAR_LENGTH", "INDICATOR", "SESSION_USER", "CHARACTER", + "INITIALLY", "SET", "CHARACTER_LENGTH", "INNER", "SIZE", + "CHECK", "INPUT", "SMALLINT", "CLOSE", "INSENSITIVE", "SOME", + "COALESCE", "INSERT", "SPACE", "COLLATE", "INT", "SQL", + "COLLATION", "INTEGER", "SQLCA", "COLUMN", "INTERSECT", + "SQLCODE", "COMMIT", "INTERVAL", "SQLERROR", "CONNECT", "INTO", + "SQLSTATE", "CONNECTION", "IS", "SQLWARNING", "CONSTRAINT", + "ISOLATION", "SUBSTRING", "CONSTRAINTS", "JOIN", "SUM", + "CONTINUE", "KEY", "SYSTEM_USER", "CONVERT", "LANGUAGE", + "TABLE", "CORRESPONDING", "LAST", "TEMPORARY", "COUNT", + "LEADING", "THEN", "CREATE", "LEFT", "TIME", "CROSS", "LEVEL", + "TIMESTAMP", "CURRENT", "LIKE", "TIMEZONE_HOUR", + "CURRENT_DATE", "LOCAL", "TIMEZONE_MINUTE", "CURRENT_TIME", + "LOWER", "TO", "CURRENT_TIMESTAMP", "MATCH", "TRAILING", + "CURRENT_USER", "MAX", "TRANSACTION", "CURSOR", "MIN", + "TRANSLATE", "DATE", "MINUTE", "TRANSLATION", "DAY", "MODULE", + "TRIM", "DEALLOCATE", "MONTH", "TRUE", "DEC", "NAMES", "UNION", + "DECIMAL", "NATIONAL", "UNIQUE", "DECLARE", "NATURAL", + "UNKNOWN", "DEFAULT", "NCHAR", "UPDATE", "DEFERRABLE", "NEXT", + "UPPER", "DEFERRED", "NO", "USAGE", "DELETE", "NONE", "USER", + "DESC", "NOT", "USING", "DESCRIBE", "NULL", "VALUE", + "DESCRIPTOR", "NULLIF", "VALUES", "DIAGNOSTICS", "NUMERIC", + "VARCHAR", "DISCONNECT", "OCTET_LENGTH", "VARYING", "DISTINCT", + "OF", "VIEW", "DOMAIN", "ON", "WHEN", "DOUBLE", "ONLY", + "WHENEVER", "DROP", "OPEN", "WHERE", "ELSE", "OPTION", "WITH", + "END", "OR", "WORK", "END-EXEC", "ORDER", "WRITE", "ESCAPE", + "OUTER", "YEAR", "EXCEPT", "OUTPUT", "ZONE", "EXCEPTION" }; + + TreeMap mySQLKeywordMap = new TreeMap(); + + for (int i = 0; i < allMySQLKeywords.length; i++) { + mySQLKeywordMap.put(allMySQLKeywords[i], null); + } + + HashMap sql92KeywordMap = new HashMap(sql92Keywords.length); + + for (int i = 0; i < sql92Keywords.length; i++) { + sql92KeywordMap.put(sql92Keywords[i], null); + } + + Iterator it = sql92KeywordMap.keySet().iterator(); + + while (it.hasNext()) { + mySQLKeywordMap.remove(it.next()); + } + + StringBuffer keywordBuf = new StringBuffer(); + + it = mySQLKeywordMap.keySet().iterator(); + + if (it.hasNext()) { + keywordBuf.append(it.next().toString()); + } + + while (it.hasNext()) { + keywordBuf.append(","); + keywordBuf.append(it.next().toString()); + } + + mysqlKeywordsThatArentSQL92 = keywordBuf.toString(); + } + + static java.sql.ResultSet buildResultSet(com.mysql.jdbc.Field[] fields, + java.util.ArrayList rows, Connection c) throws SQLException { + int fieldsLength = fields.length; + + for (int i = 0; i < fieldsLength; i++) { + fields[i].setConnection(c); + fields[i].setUseOldNameMetadata(true); + } + + return new com.mysql.jdbc.ResultSet(c.getCatalog(), fields, + new RowDataStatic(rows), c, null); + } + /** The connection to the database */ protected Connection conn; @@ -523,19 +659,6 @@ return buildResultSet(fields, rows, this.conn); } - static java.sql.ResultSet buildResultSet(com.mysql.jdbc.Field[] fields, - java.util.ArrayList rows, Connection c) throws SQLException { - int fieldsLength = fields.length; - - for (int i = 0; i < fieldsLength; i++) { - fields[i].setConnection(c); - fields[i].setUseOldNameMetadata(true); - } - - return new com.mysql.jdbc.ResultSet(c.getCatalog(), fields, - new RowDataStatic(rows), c, null); - } - private void convertToJdbcFunctionList(String catalog, ResultSet proceduresRs, boolean needsClientFiltering, String db, Map procedureRowsOrderedByName, int nameIndex) throws SQLException { @@ -720,6 +843,61 @@ } /** + * Finds the end of the parameter declaration from the output of "SHOW + * CREATE PROCEDURE". + * + * @param beginIndex + * should be the index of the procedure body that contains the + * first "(". + * @param procedureDef + * the procedure body + * @param quoteChar + * the identifier quote character in use + * @return the ending index of the parameter declaration, not including the + * closing ")" + * @throws SQLException + * if a parse error occurs. + */ + private int endPositionOfParameterDeclaration(int beginIndex, + String procedureDef, String quoteChar) throws SQLException { + int currentPos = beginIndex + 1; + int parenDepth = 1; // counting the first openParen + + while (parenDepth > 0 && currentPos < procedureDef.length()) { + int closedParenIndex = StringUtils.indexOfIgnoreCaseRespectQuotes( + currentPos, procedureDef, ")", quoteChar.charAt(0), + !this.conn.isNoBackslashEscapesSet()); + + if (closedParenIndex != -1) { + int nextOpenParenIndex = StringUtils + .indexOfIgnoreCaseRespectQuotes(currentPos, + procedureDef, "(", quoteChar.charAt(0), + !this.conn.isNoBackslashEscapesSet()); + + if (nextOpenParenIndex != -1 + && nextOpenParenIndex < closedParenIndex) { + parenDepth++; + currentPos = closedParenIndex + 1; // set after closed + // paren that increases + // depth + } else { + parenDepth--; + currentPos = closedParenIndex; // start search from same + // position + } + } else { + // we should always get closed paren of some sort + throw SQLError + .createSQLException( + "Internal error when parsing callable statement metadata", + SQLError.SQL_STATE_GENERAL_ERROR); + } + } + + return currentPos; + } + + /** * Extracts foreign key info for one table. * * @param rows @@ -979,6 +1157,65 @@ } /** + * Finds the end of the RETURNS clause for SQL Functions by using any of the + * keywords allowed after the RETURNS clause, or a label. + * + * @param procedureDefn + * the function body containing the definition of the function + * @param quoteChar + * the identifier quote string in use + * @param positionOfReturnKeyword + * the position of "RETRUNS" in the definition + * @return the end of the returns clause + * @throws SQLException + * if a parse error occurs + */ + private int findEndOfReturnsClause(String procedureDefn, String quoteChar, + int positionOfReturnKeyword) throws SQLException { + /* + * characteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | + * NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { + * DEFINER | INVOKER } | COMMENT 'string' + */ + + String[] tokens = new String[] { "LANGUAGE", "NOT", "DETERMINISTIC", + "CONTAINS", "NO", "READ", "MODIFIES", "SQL", "COMMENT", "BEGIN", + "RETURN" }; + + int startLookingAt = positionOfReturnKeyword + "RETURNS".length() + 1; + + for (int i = 0; i < tokens.length; i++) { + int endOfReturn = StringUtils.indexOfIgnoreCaseRespectQuotes( + startLookingAt, procedureDefn, tokens[i], quoteChar + .charAt(0), !this.conn.isNoBackslashEscapesSet()); + + if (endOfReturn != -1) { + return endOfReturn; + } + } + + // Label? + int endOfReturn = StringUtils.indexOfIgnoreCaseRespectQuotes( + startLookingAt, procedureDefn, ":", quoteChar.charAt(0), + !this.conn.isNoBackslashEscapesSet()); + + if (endOfReturn != -1) { + // seek back until whitespace + for (int i = endOfReturn; i > 0; i--) { + if (Character.isWhitespace(procedureDefn.charAt(i))) { + return i; + } + } + } + + // We can't parse it. + + throw SQLError.createSQLException( + "Internal error when parsing callable statement metadata", + SQLError.SQL_STATE_GENERAL_ERROR); + } + + /** * @see DatabaseMetaData#getAttributes(String, String, String, String) */ public java.sql.ResultSet getAttributes(String arg0, String arg1, @@ -1561,120 +1798,6 @@ } /** - * Finds the end of the parameter declaration from the output of "SHOW - * CREATE PROCEDURE". - * - * @param beginIndex - * should be the index of the procedure body that contains the - * first "(". - * @param procedureDef - * the procedure body - * @param quoteChar - * the identifier quote character in use - * @return the ending index of the parameter declaration, not including the - * closing ")" - * @throws SQLException - * if a parse error occurs. - */ - private int endPositionOfParameterDeclaration(int beginIndex, - String procedureDef, String quoteChar) throws SQLException { - int currentPos = beginIndex + 1; - int parenDepth = 1; // counting the first openParen - - while (parenDepth > 0 && currentPos < procedureDef.length()) { - int closedParenIndex = StringUtils.indexOfIgnoreCaseRespectQuotes( - currentPos, procedureDef, ")", quoteChar.charAt(0), - !this.conn.isNoBackslashEscapesSet()); - - if (closedParenIndex != -1) { - int nextOpenParenIndex = StringUtils - .indexOfIgnoreCaseRespectQuotes(currentPos, - procedureDef, "(", quoteChar.charAt(0), - !this.conn.isNoBackslashEscapesSet()); - - if (nextOpenParenIndex != -1 - && nextOpenParenIndex < closedParenIndex) { - parenDepth++; - currentPos = closedParenIndex + 1; // set after closed - // paren that increases - // depth - } else { - parenDepth--; - currentPos = closedParenIndex; // start search from same - // position - } - } else { - // we should always get closed paren of some sort - throw SQLError - .createSQLException( - "Internal error when parsing callable statement metadata", - SQLError.SQL_STATE_GENERAL_ERROR); - } - } - - return currentPos; - } - - /** - * Finds the end of the RETURNS clause for SQL Functions by using any of the - * keywords allowed after the RETURNS clause, or a label. - * - * @param procedureDefn - * the function body containing the definition of the function - * @param quoteChar - * the identifier quote string in use - * @param positionOfReturnKeyword - * the position of "RETRUNS" in the definition - * @return the end of the returns clause - * @throws SQLException - * if a parse error occurs - */ - private int findEndOfReturnsClause(String procedureDefn, String quoteChar, - int positionOfReturnKeyword) throws SQLException { - /* - * characteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | - * NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { - * DEFINER | INVOKER } | COMMENT 'string' - */ - - String[] tokens = new String[] { "LANGUAGE", "NOT", "DETERMINISTIC", - "CONTAINS", "NO", "READ", "MODIFIES", "SQL", "COMMENT", "BEGIN", - "RETURN" }; - - int startLookingAt = positionOfReturnKeyword + "RETURNS".length() + 1; - - for (int i = 0; i < tokens.length; i++) { - int endOfReturn = StringUtils.indexOfIgnoreCaseRespectQuotes( - startLookingAt, procedureDefn, tokens[i], quoteChar - .charAt(0), !this.conn.isNoBackslashEscapesSet()); - - if (endOfReturn != -1) { - return endOfReturn; - } - } - - // Label? - int endOfReturn = StringUtils.indexOfIgnoreCaseRespectQuotes( - startLookingAt, procedureDefn, ":", quoteChar.charAt(0), - !this.conn.isNoBackslashEscapesSet()); - - if (endOfReturn != -1) { - // seek back until whitespace - for (int i = endOfReturn; i > 0; i--) { - if (Character.isWhitespace(procedureDefn.charAt(i))) { - return i; - } - } - } - - // We can't parse it. - - throw SQLError.createSQLException( - "Internal error when parsing callable statement metadata", - SQLError.SQL_STATE_GENERAL_ERROR); - } - - /** * Parses the cascade option string and returns the DBMD constant that * represents it (for deletes) * @@ -4197,22 +4320,7 @@ * DOCUMENT ME! */ public String getSQLKeywords() throws SQLException { - return "AUTO_INCREMENT,BINARY,BLOB,ENUM,INFILE,LOAD,MEDIUMINT,OPTION,OUTFILE,REPLACE,SET,TEXT,UNSIGNED,ZEROFILL"; - - /* - * [20:44] root@test> select GROUP_CONCAT(reserved.a) from reserved left - * join sql92 on (reserved.a=sql92.a) where sql92.a IS NULL GROUP BY - * (reserved.b) \G ************************** 1. row - * *************************** GROUP_CONCAT(reserved.a): - * RETURN,REQUIRE,REPLACE,REPEAT,RENAME, - * REGEXP,PURGE,SPECIFIC,SPATIAL,SONAME,SHOW,SEPARATOR,SENSITIVE, - * SECOND_MICROSECOND,RLIKE,MOD,MINUTE_SECOND,MINUTE_MICROSECOND, - * MIDDLEINT,MEDIUMTEXT,MEDIUMINT,MEDIUMBLOB,MASTER_SERVER_ID, - * LOW_PRIORITY,LOOP,LONGTEXT,OUTFILE,OUT,OPTIONALLY,OPTIMIZE, - * NO_WRITE_TO_BINLOG,LONGBLOB,ZEROFILL,UTC_DATE,USER_RESOURCES,USE, - * UNSIGNED,UNLOCK,UNDO,UTC_TIME,UTC_TIMESTAMP,YEAR_MONTH,XOR,WHILE, - * VARCHARACTER,VARBINARY,TINYTEXT,SQL_T - */ + return mysqlKeywordsThatArentSQL92; } /** Modified: trunk/connector-j/CHANGES =================================================================== --- trunk/connector-j/CHANGES 2007-02-02 19:16:21 UTC (rev 6300) +++ trunk/connector-j/CHANGES 2007-02-02 21:02:01 UTC (rev 6301) @@ -106,7 +106,12 @@ - Use faster datetime parsing for ResultSets that come from plain or non-server-side prepared statements. (Enable old implementation with "useFastDateParsing=false" as a configuration parameter). - + + - Fixed BUG#24794 - DatabaseMetaData.getSQLKeywords() doesn't return + all reserved words for current MySQL version. The current fix/implementation + returns keywords for MySQL-5.1, and doesn't distinguish between different + versions of the server. + 10-20-06 - Version 5.0.4 - Fixed BUG#21379 - column names don't match metadata in cases Modified: trunk/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java =================================================================== --- trunk/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java 2007-02-02 19:16:21 UTC (rev 6300) +++ trunk/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java 2007-02-02 21:02:01 UTC (rev 6301) @@ -424,7 +424,9 @@ } } } - + + private static String mysqlKeywordsThatArentSQL92; + private static final int MAX_IDENTIFIER_LENGTH = 64; private static final int DEFERRABILITY = 13; @@ -465,7 +467,128 @@ private static final int UPDATE_RULE = 9; private static final byte[] VIEW_AS_BYTES = "VIEW".getBytes(); + + static { + // Current as-of MySQL-5.1.16 + String[] allMySQLKeywords = new String[] { "ACCESSIBLE", "ADD", "ALL", + "ALTER", "ANALYZE", "AND", "AS", "ASC", "ASENSITIVE", "BEFORE", + "BETWEEN", "BIGINT", "BINARY", "BLOB", "BOTH", "BY", "CALL", + "CASCADE", "CASE", "CHANGE", "CHAR", "CHARACTER", "CHECK", + "COLLATE", "COLUMN", "CONDITION", "CONNECTION", "CONSTRAINT", + "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT_DATE", + "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", + "DATABASE", "DATABASES", "DAY_HOUR", "DAY_MICROSECOND", + "DAY_MINUTE", "DAY_SECOND", "DEC", "DECIMAL", "DECLARE", + "DEFAULT", "DELAYED", "DELETE", "DESC", "DESCRIBE", + "DETERMINISTIC", "DISTINCT", "DISTINCTROW", "DIV", "DOUBLE", + "DROP", "DUAL", "EACH", "ELSE", "ELSEIF", "ENCLOSED", + "ESCAPED", "EXISTS", "EXIT", "EXPLAIN", "FALSE", "FETCH", + "FLOAT", "FLOAT4", "FLOAT8", "FOR", "FORCE", "FOREIGN", "FROM", + "FULLTEXT", "GRANT", "GROUP", "HAVING", "HIGH_PRIORITY", + "HOUR_MICROSECOND", "HOUR_MINUTE", "HOUR_SECOND", "IF", + "IGNORE", "IN", "INDEX", "INFILE", "INNER", "INOUT", + "INSENSITIVE", "INSERT", "INT", "INT1", "INT2", "INT3", "INT4", + "INT8", "INTEGER", "INTERVAL", "INTO", "IS", "ITERATE", "JOIN", + "KEY", "KEYS", "KILL", "LEADING", "LEAVE", "LEFT", "LIKE", + "LIMIT", "LINEAR", "LINES", "LOAD", "LOCALTIME", + "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT", + "LOOP", "LOW_PRIORITY", "MATCH", "MEDIUMBLOB", "MEDIUMINT", + "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", + "MINUTE_SECOND", "MOD", "MODIFIES", "NATURAL", "NOT", + "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON", "OPTIMIZE", + "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER", + "OUTFILE", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE", + "RANGE", "READ", "READS", "READ_ONLY", "READ_WRITE", "REAL", + "REFERENCES", "REGEXP", "RELEASE", "RENAME", "REPEAT", + "REPLACE", "REQUIRE", "RESTRICT", "RETURN", "REVOKE", "RIGHT", + "RLIKE", "SCHEMA", "SCHEMAS", "SECOND_MICROSECOND", "SELECT", + "SENSITIVE", "SEPARATOR", "SET", "SHOW", "SMALLINT", "SPATIAL", + "SPECIFIC", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", + "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", + "SSL", "STARTING", "STRAIGHT_JOIN", "TABLE", "TERMINATED", + "THEN", "TINYBLOB", "TINYINT", "TINYTEXT", "TO", "TRAILING", + "TRIGGER", "TRUE", "UNDO", "UNION", "UNIQUE", "UNLOCK", + "UNSIGNED", "UPDATE", "USAGE", "USE", "USING", "UTC_DATE", + "UTC_TIME", "UTC_TIMESTAMP", "VALUES", "VARBINARY", "VARCHAR", + "VARCHARACTER", "VARYING", "WHEN", "WHERE", "WHILE", "WITH", + "WRITE", "X509", "XOR", "YEAR_MONTH", "ZEROFILL" }; + String[] sql92Keywords = new String[] { "ABSOLUTE", "EXEC", "OVERLAPS", + "ACTION", "EXECUTE", "PAD", "ADA", "EXISTS", "PARTIAL", "ADD", + "EXTERNAL", "PASCAL", "ALL", "EXTRACT", "POSITION", "ALLOCATE", + "FALSE", "PRECISION", "ALTER", "FETCH", "PREPARE", "AND", + "FIRST", "PRESERVE", "ANY", "FLOAT", "PRIMARY", "ARE", "FOR", + "PRIOR", "AS", "FOREIGN", "PRIVILEGES", "ASC", "FORTRAN", + "PROCEDURE", "ASSERTION", "FOUND", "PUBLIC", "AT", "FROM", + "READ", "AUTHORIZATION", "FULL", "REAL", "AVG", "GET", + "REFERENCES", "BEGIN", "GLOBAL", "RELATIVE", "BETWEEN", "GO", + "RESTRICT", "BIT", "GOTO", "REVOKE", "BIT_LENGTH", "GRANT", + "RIGHT", "BOTH", "GROUP", "ROLLBACK", "BY", "HAVING", "ROWS", + "CASCADE", "HOUR", "SCHEMA", "CASCADED", "IDENTITY", "SCROLL", + "CASE", "IMMEDIATE", "SECOND", "CAST", "IN", "SECTION", + "CATALOG", "INCLUDE", "SELECT", "CHAR", "INDEX", "SESSION", + "CHAR_LENGTH", "INDICATOR", "SESSION_USER", "CHARACTER", + "INITIALLY", "SET", "CHARACTER_LENGTH", "INNER", "SIZE", + "CHECK", "INPUT", "SMALLINT", "CLOSE", "INSENSITIVE", "SOME", + "COALESCE", "INSERT", "SPACE", "COLLATE", "INT", "SQL", + "COLLATION", "INTEGER", "SQLCA", "COLUMN", "INTERSECT", + "SQLCODE", "COMMIT", "INTERVAL", "SQLERROR", "CONNECT", "INTO", + "SQLSTATE", "CONNECTION", "IS", "SQLWARNING", "CONSTRAINT", + "ISOLATION", "SUBSTRING", "CONSTRAINTS", "JOIN", "SUM", + "CONTINUE", "KEY", "SYSTEM_USER", "CONVERT", "LANGUAGE", + "TABLE", "CORRESPONDING", "LAST", "TEMPORARY", "COUNT", + "LEADING", "THEN", "CREATE", "LEFT", "TIME", "CROSS", "LEVEL", + "TIMESTAMP", "CURRENT", "LIKE", "TIMEZONE_HOUR", + "CURRENT_DATE", "LOCAL", "TIMEZONE_MINUTE", "CURRENT_TIME", + "LOWER", "TO", "CURRENT_TIMESTAMP", "MATCH", "TRAILING", + "CURRENT_USER", "MAX", "TRANSACTION", "CURSOR", "MIN", + "TRANSLATE", "DATE", "MINUTE", "TRANSLATION", "DAY", "MODULE", + "TRIM", "DEALLOCATE", "MONTH", "TRUE", "DEC", "NAMES", "UNION", + "DECIMAL", "NATIONAL", "UNIQUE", "DECLARE", "NATURAL", + "UNKNOWN", "DEFAULT", "NCHAR", "UPDATE", "DEFERRABLE", "NEXT", + "UPPER", "DEFERRED", "NO", "USAGE", "DELETE", "NONE", "USER", + "DESC", "NOT", "USING", "DESCRIBE", "NULL", "VALUE", + "DESCRIPTOR", "NULLIF", "VALUES", "DIAGNOSTICS", "NUMERIC", + "VARCHAR", "DISCONNECT", "OCTET_LENGTH", "VARYING", "DISTINCT", + "OF", "VIEW", "DOMAIN", "ON", "WHEN", "DOUBLE", "ONLY", + "WHENEVER", "DROP", "OPEN", "WHERE", "ELSE", "OPTION", "WITH", + "END", "OR", "WORK", "END-EXEC", "ORDER", "WRITE", "ESCAPE", + "OUTER", "YEAR", "EXCEPT", "OUTPUT", "ZONE", "EXCEPTION" }; + + TreeMap mySQLKeywordMap = new TreeMap(); + + for (int i = 0; i < allMySQLKeywords.length; i++) { + mySQLKeywordMap.put(allMySQLKeywords[i], null); + } + + HashMap sql92KeywordMap = new HashMap(sql92Keywords.length); + + for (int i = 0; i < sql92Keywords.length; i++) { + sql92KeywordMap.put(sql92Keywords[i], null); + } + + Iterator it = sql92KeywordMap.keySet().iterator(); + + while (it.hasNext()) { + mySQLKeywordMap.remove(it.next()); + } + + StringBuffer keywordBuf = new StringBuffer(); + + it = mySQLKeywordMap.keySet().iterator(); + + if (it.hasNext()) { + keywordBuf.append(it.next().toString()); + } + + while (it.hasNext()) { + keywordBuf.append(","); + keywordBuf.append(it.next().toString()); + } + + mysqlKeywordsThatArentSQL92 = keywordBuf.toString(); + } + /** The connection to the database */ protected Connection conn; @@ -4222,22 +4345,7 @@ * DOCUMENT ME! */ public String getSQLKeywords() throws SQLException { - return "AUTO_INCREMENT,BINARY,BLOB,ENUM,INFILE,LOAD,MEDIUMINT,OPTION,OUTFILE,REPLACE,SET,TEXT,UNSIGNED,ZEROFILL"; - - /* - * [20:44] root@test> select GROUP_CONCAT(reserved.a) from reserved left - * join sql92 on (reserved.a=sql92.a) where sql92.a IS NULL GROUP BY - * (reserved.b) \G ************************** 1. row - * *************************** GROUP_CONCAT(reserved.a): - * RETURN,REQUIRE,REPLACE,REPEAT,RENAME, - * REGEXP,PURGE,SPECIFIC,SPATIAL,SONAME,SHOW,SEPARATOR,SENSITIVE, - * SECOND_MICROSECOND,RLIKE,MOD,MINUTE_SECOND,MINUTE_MICROSECOND, - * MIDDLEINT,MEDIUMTEXT,MEDIUMINT,MEDIUMBLOB,MASTER_SERVER_ID, - * LOW_PRIORITY,LOOP,LONGTEXT,OUTFILE,OUT,OPTIONALLY,OPTIMIZE, - * NO_WRITE_TO_BINLOG,LONGBLOB,ZEROFILL,UTC_DATE,USER_RESOURCES,USE, - * UNSIGNED,UNLOCK,UNDO,UTC_TIME,UTC_TIMESTAMP,YEAR_MONTH,XOR,WHILE, - * VARCHARACTER,VARBINARY,TINYTEXT,SQL_T - */ + return mysqlKeywordsThatArentSQL92; } /**