📄 sqlparser.java
字号:
break; case ')': parenCnt--; out[d++] = c; s++; break; default: out[d++] = c; s++; break; } } String args = String.valueOf(out, argStart, d - argStart).trim(); d = argStart; mustbe(')', false); terminator = tc; skipWhiteSpace(); // // Process convert scalar function. // Arguments need to be reversed and the data type // argument converted to an SQL server type // if (name.equals("convert") && arg2Start < args.length() - 1) { String arg2 = args.substring(arg2Start + 1).trim().toLowerCase(); String dataType = (String) cvMap.get(arg2); if (dataType == null) { // Will get server error if invalid type passed dataType = arg2; } copyLiteral("convert("); copyLiteral(dataType); out[d++] = ','; copyLiteral(args.substring(0, arg2Start)); out[d++] = ')'; return; } // // See if function mapped // String fn; if (connection.getServerType() == Driver.SQLSERVER) { fn = (String) msFnMap.get(name); if (fn == null) { fn = (String) fnMap.get(name); } } else { fn = (String) fnMap.get(name); } if (fn == null) { // Not mapped so assume simple case copyLiteral(name); out[d++] = '('; copyLiteral(args); out[d++] = ')'; return; } // // Process timestamp interval constants // if (args.length() > 8 && args.substring(0, 8).equalsIgnoreCase("sql_tsi_")) { args = args.substring(8); if (args.length() > 11 && args.substring(0, 11).equalsIgnoreCase("frac_second")) { args = "millisecond" + args.substring(11); } } // // Substitute mapped function name and arguments // final int len = fn.length(); for (int i = 0; i < len; i++) { final char c = fn.charAt(i); if (c == '$') { // Substitute arguments copyLiteral(args); } else { out[d++] = c; } } } /** * Processes the JDBC escape {escape 'X'}. * * @throws SQLException */ private void likeEscape() throws SQLException { copyLiteral("escape "); skipWhiteSpace(); if (in[s] == '\'' || in[s] == '"') { copyString(); } else { mustbe('\'', true); } skipWhiteSpace(); } /** * Processes the JDBC escape sequences. * * @throws SQLException */ private void escape() throws SQLException { char tc = terminator; terminator = '}'; StringBuffer escBuf = new StringBuffer(); s++; skipWhiteSpace(); if (in[s] == '?') { copyParam("@return_status", -1); skipWhiteSpace(); mustbe('=', false); skipWhiteSpace(); while (Character.isLetter(in[s])) { escBuf.append(Character.toLowerCase(in[s++])); } skipWhiteSpace(); String esc = escBuf.toString(); if (esc.equals("call")) { callEscape(); } else { throw new SQLException( Messages.get("error.parsesql.syntax", "call", String.valueOf(s)), "22019"); } } else { while (Character.isLetter(in[s])) { escBuf.append(Character.toLowerCase(in[s++])); } skipWhiteSpace(); String esc = escBuf.toString(); if (esc.equals("call")) { callEscape(); } else if (esc.equals("t")) { if (!getDateTimeField(timeMask)) { throw new SQLException( Messages.get("error.parsesql.syntax", "time", String.valueOf(s)), "22019"); } } else if (esc.equals("d")) { if (!getDateTimeField(dateMask)) { throw new SQLException( Messages.get("error.parsesql.syntax", "date", String.valueOf(s)), "22019"); } } else if (esc.equals("ts")) { if (!getDateTimeField(timestampMask)) { throw new SQLException( Messages.get("error.parsesql.syntax", "timestamp", String.valueOf(s)), "22019"); } } else if (esc.equals("oj")) { outerJoinEscape(); } else if (esc.equals("fn")) { functionEscape(); } else if (esc.equals("escape")) { likeEscape(); } else { throw new SQLException( Messages.get("error.parsesql.badesc", esc, String.valueOf(s)), "22019"); } } mustbe('}', false); terminator = tc; } /** * Extracts the first table name following the keyword FROM. * * @return the table name as a <code>String</code> */ private String getTableName() throws SQLException { StringBuffer name = new StringBuffer(128); copyWhiteSpace(); char c = (s < len) ? in[s] : ' '; if (c == '{') { // Start of {oj ... } we can assume that there is // more than one table in select and therefore // it would not be updateable. return ""; } // // Skip any leading comments before first table name // while (c == '/' || c == '-' && s + 1 < len) { if (c == '/') { if (in[s + 1] == '*') { skipMultiComments(); } else { break; } } else { if (in[s + 1] == '-') { skipSingleComments(); } else { break; } } copyWhiteSpace(); c = (s < len) ? in[s] : ' '; } if (c == '{') { // See comment above return ""; } // // Now process table name // while (s < len) { if (c == '[' || c == '"') { int start = d; copyString(); name.append(String.valueOf(out, start, d - start)); copyWhiteSpace(); c = (s < len) ? in[s] : ' '; } else { int start = d; c = (s < len) ? in[s++] : ' '; while ((isIdentifier(c)) && c != '.' && c != ',') { out[d++] = c; c = (s < len) ? in[s++] : ' '; } name.append(String.valueOf(out, start, d - start)); s--; copyWhiteSpace(); c = (s < len) ? in[s] : ' '; } if (c != '.') { break; } name.append(c); out[d++] = c; s++; copyWhiteSpace(); c = (s < len) ? in[s] : ' '; } return name.toString(); } /** * Parses the SQL statement processing JDBC escapes and parameter markers. * * @param extractTable true to return the first table name in the FROM clause of a select * @return The processed SQL statement, any procedure name, the first * SQL keyword and (optionally) the first table name as elements 0 1, 2 and 3 of the * returned <code>String[]</code>. * @throws SQLException */ String[] parse(boolean extractTable) throws SQLException { boolean isSelect = false; boolean isModified = false; boolean isSlowScan = true; try { while (s < len) { final char c = in[s]; switch (c) { case '{': escape(); isModified = true; break; case '[': case '"': case '\'': copyString(); break; case '?': copyParam(null, d); break; case '/': if (s+1 < len && in[s+1] == '*') { skipMultiComments(); } else { out[d++] = c; s++; } break; case '-': if (s+1 < len && in[s+1] == '-') { skipSingleComments(); } else { out[d++] = c; s++; } break; default: if (isSlowScan && Character.isLetter(c)) { if (keyWord == null) { keyWord = copyKeyWord(); if (keyWord.equals("select")) { isSelect = true; } isSlowScan = extractTable && isSelect; break; } if (extractTable && isSelect) { String sqlWord = copyKeyWord(); if (sqlWord.equals("from")) { // Ensure only first 'from' is processed isSlowScan = false; tableName = getTableName(); } break; } } out[d++] = c; s++; break; } } // // Impose a reasonable maximum limit on the number of parameters // unless the connection is sending statements unprepared (i.e. by // building a plain query) and this is not a procedure call. // if (params != null && params.size() > 255 && connection.getPrepareSql() != TdsCore.UNPREPARED && procName != null) { int limit = 255; // SQL 6.5 and Sybase < 12.50 if (connection.getServerType() == Driver.SYBASE) { if (connection.getDatabaseMajorVersion() > 12 || connection.getDatabaseMajorVersion() == 12 && connection.getDatabaseMinorVersion() >= 50) { limit = 2000; // Actually 2048 but allow some head room } } else { if (connection.getDatabaseMajorVersion() == 7) { limit = 1000; // Actually 1024 } else if (connection.getDatabaseMajorVersion() > 7) { limit = 2000; // Actually 2100 } } if (params.size() > limit) { throw new SQLException( Messages.get("error.parsesql.toomanyparams", Integer.toString(limit)), "22025"); } } String result[] = new String[4]; // return sql and procname result[0] = (isModified) ? new String(out, 0, d) : sql; result[1] = procName; result[2] = (keyWord == null) ? "" : keyWord; result[3] = tableName; return result; } catch (IndexOutOfBoundsException e) { // Should only come here if string is invalid in some way. throw new SQLException( Messages.get("error.parsesql.missing", String.valueOf(terminator)), "22025"); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -