📄 sqlparser.java
字号:
} s--; return new String(out, start, d - start); } /** * Copies over white space. */ private void copyWhiteSpace() { while (s < in.length && Character.isWhitespace(in[s])) { out[d++] = in[s++]; } } /** * Checks that the next character is as expected. * * @param c The expected character. * @param copy True if found character should be copied. * @throws SQLException if expected characeter not found. */ private void mustbe(char c, boolean copy) throws SQLException { if (in[s] != c) { throw new SQLException( Messages.get("error.parsesql.mustbe", String.valueOf(s), String.valueOf(c)), "22019"); } if (copy) { out[d++] = in[s++]; } else { s++; } } /** * Skips embedded white space. */ private void skipWhiteSpace() { while (Character.isWhitespace(in[s])) { s++; } } /** * Skips single-line comments. */ private void skipSingleComments() { while (s < len && in[s] != '\n' && in[s] != '\r') { // comments should be passed on to the server out[d++] = in[s++]; } } /** * Skips multi-line comments */ private void skipMultiComments() throws SQLException { int block = 0; do { if (s < len - 1) { if (in[s] == '/' && in[s + 1] == '*') { block++; } else if (in[s] == '*' && in[s + 1] == '/') { block--; } // comments should be passed on to the server out[d++] = in[s++]; } else { throw new SQLException( Messages.get("error.parsesql.missing", "*/"), "22025"); } } while (block > 0); out[d++] = in[s++]; } /** * Processes the JDBC {call procedure [(?,?,?)]} type escape. * * @throws SQLException if an error occurs */ private void callEscape() throws SQLException { // Insert EXECUTE into SQL so that proc can be called as normal SQL copyLiteral("EXECUTE "); keyWord = "execute"; // Process procedure name procName = copyProcName(); skipWhiteSpace(); if (in[s] == '(') { // Optional ( ) s++; terminator = ')'; skipWhiteSpace(); } else { terminator = '}'; } out[d++] = ' '; // Process any parameters while (in[s] != terminator) { String name = null; if (in[s] == '@') { // Named parameter name = copyParamName(); skipWhiteSpace(); mustbe('=', true); skipWhiteSpace(); if (in[s] == '?') { copyParam(name, d); } else { // Named param has literal value can't call as RPC procName = ""; } } else if (in[s] == '?') { copyParam(name, d); } else { // Literal parameter can't call as RPC procName = ""; } // Now find terminator or comma while (in[s] != terminator && in[s] != ',') { if (in[s] == '{') { escape(); } else if (in[s] == '\'' || in[s] == '[' || in[s] == '"') { copyString(); } else { out[d++] = in[s++]; } } if (in[s] == ',') { out[d++] = in[s++]; } skipWhiteSpace(); } if (terminator == ')') { s++; // Elide } terminator = '}'; skipWhiteSpace(); } /** * Utility routine to validate date and time escapes. * * @param mask The validation mask * @return True if the escape was valid and processed OK. */ private boolean getDateTimeField(byte[] mask) throws SQLException { skipWhiteSpace(); if (in[s] == '?') { // Allow {ts ?} type construct copyParam(null, d); skipWhiteSpace(); return in[s] == terminator; } out[d++] = '\''; terminator = (in[s] == '\'' || in[s] == '"') ? in[s++] : '}'; skipWhiteSpace(); int ptr = 0; while (ptr < mask.length) { char c = in[s++]; if (c == ' ' && out[d - 1] == ' ') { continue; // Eliminate multiple spaces } if (mask[ptr] == '#') { if (!Character.isDigit(c)) { return false; } } else if (mask[ptr] != c) { return false; } if (c != '-') { out[d++] = c; } ptr++; } if (mask.length == 19) { // Timestamp int digits = 0; if (in[s] == '.') { out[d++] = in[s++]; while (Character.isDigit(in[s])) { if (digits < 3) { out[d++] = in[s++]; digits++; } else { s++; } } } else { out[d++] = '.'; } for (; digits < 3; digits++) { out[d++] = '0'; } } skipWhiteSpace(); if (in[s] != terminator) { return false; } if (terminator != '}') { s++; // Skip terminator } skipWhiteSpace(); out[d++] = '\''; return true; } /** Syntax mask for time escape. */ private static final byte[] timeMask = { '#','#',':','#','#',':','#','#' }; /** Syntax mask for date escape. */ private static final byte[] dateMask = { '#','#','#','#','-','#','#','-','#','#' }; /** Syntax mask for timestamp escape. */ static final byte[] timestampMask = { '#','#','#','#','-','#','#','-','#','#',' ', '#','#',':','#','#',':','#','#' }; /** * Processes the JDBC escape {oj left outer join etc}. * * @throws SQLException */ private void outerJoinEscape() throws SQLException { while (in[s] != '}') { final char c = in[s]; switch (c) { case '\'': case '"': case '[': copyString(); break; case '{': // Nested escape! escape(); break; case '?': copyParam(null, d); break; default: out[d++] = c; s++; break; } } } /** Map of jdbc to sybase function names. */ private static HashMap fnMap = new HashMap(); /** Map of jdbc to sql server function names. */ private static HashMap msFnMap = new HashMap(); /** Map of jdbc to server data types for convert */ private static HashMap cvMap = new HashMap(); static { // Microsoft only functions msFnMap.put("length", "len($)"); msFnMap.put("truncate", "round($, 1)"); // Common functions fnMap.put("user", "user_name($)"); fnMap.put("database", "db_name($)"); fnMap.put("ifnull", "isnull($)"); fnMap.put("now", "getdate($)"); fnMap.put("atan2", "atn2($)"); fnMap.put("mod", "($)"); fnMap.put("length", "char_length($)"); fnMap.put("locate", "charindex($)"); fnMap.put("repeat", "replicate($)"); fnMap.put("insert", "stuff($)"); fnMap.put("lcase", "lower($)"); fnMap.put("ucase", "upper($)"); fnMap.put("concat", "($)"); fnMap.put("curdate", "convert(datetime, convert(varchar, getdate(), 112))"); fnMap.put("curtime", "convert(datetime, convert(varchar, getdate(), 108))"); fnMap.put("dayname", "datename(weekday,$)"); fnMap.put("dayofmonth", "datepart(day,$)"); fnMap.put("dayofweek", "datepart(weekday,$)"); fnMap.put("dayofyear", "datepart(dayofyear,$)"); fnMap.put("hour", "datepart(hour,$)"); fnMap.put("minute", "datepart(minute,$)"); fnMap.put("second", "datepart(second,$)"); fnMap.put("year", "datepart(year,$)"); fnMap.put("quarter", "datepart(quarter,$)"); fnMap.put("month", "datepart(month,$)"); fnMap.put("week", "datepart(week,$)"); fnMap.put("monthname", "datename(month,$)"); fnMap.put("timestampadd", "dateadd($)"); fnMap.put("timestampdiff", "datediff($)"); // convert jdbc to sql types cvMap.put("binary", "varbinary"); cvMap.put("char", "varchar"); cvMap.put("date", "datetime"); cvMap.put("double", "float"); cvMap.put("longvarbinary", "image"); cvMap.put("longvarchar", "text"); cvMap.put("time", "datetime"); cvMap.put("timestamp", "timestamp"); } /** * Processes the JDBC escape {fn function()}. * * @throws SQLException */ private void functionEscape() throws SQLException { char tc = terminator; skipWhiteSpace(); StringBuffer nameBuf = new StringBuffer(); // // Capture name // while (Character.isLetterOrDigit(in[s])) { nameBuf.append(in[s++]); } String name = nameBuf.toString().toLowerCase(); // // Now collect arguments // skipWhiteSpace(); mustbe('(', false); int parenCnt = 1; int argStart = d; int arg2Start = 0; terminator = ')'; while (in[s] != ')' || parenCnt > 1) { final char c = in[s]; switch (c) { case '\'': case '"': case '[': copyString(); break; case '{': // Process nested escapes! escape(); break; case ',': if (arg2Start == 0) { arg2Start = d - argStart; } if (name.equals("concat")) { out[d++] = '+'; s++; } else if (name.equals("mod")) { out[d++] = '%'; s++; } else { out[d++] = c; s++; } break; case '(': parenCnt++; out[d++] = c; s++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -