Process JDBC escape strings and parameter markers in the SQL string.
This code recognizes the following escapes:
- Date {d 'yyyy-mm-dd'}
- Time {t 'hh:mm:ss'}
- Timestamp {ts 'yyyy-mm-dd hh:mm:ss.nnn'}
- ESCAPE {escape 'x'}
- Function {fn xxxx([arg,arg...])}
NB The concat(arg, arg) operator is converted to (arg + arg)
- OuterJoin {oj .....}
- Call {?=call proc [arg, arg...]}
or {call proc [arg, arg...]}
Notes:
- This code is designed to be as efficient as possible and as
result the validation done here is limited.
- SQL comments are parsed correctly thanks to code supplied by
Joel Fouse.
cache
private static SimpleLRUCache cache
LRU cache of previously parsed SQL
connection
private final ConnectionJDBC2 connection
Connection object for server specific parsing.
cvMap
private static HashMap cvMap
Map of jdbc to server data types for convert
d
private int d
Current position in output buffer.
dateMask
private static final byte[] dateMask
Syntax mask for date escape.
fnMap
private static HashMap fnMap
Map of jdbc to sybase function names.
identifierChar
private static boolean[] identifierChar
Lookup table to test if character is part of an identifier.
in
private final char[] in
Input buffer with SQL statement.
keyWord
private String keyWord
First SQL keyword or identifier in statement.
len
private final int len
Length of input buffer.
msFnMap
private static HashMap msFnMap
Map of jdbc to sql server function names.
out
private final char[] out
Output buffer to contain parsed SQL.
params
private final ArrayList params
Parameter list to be populated or null
if no parameters
are expected.
procName
private String procName
Procedure name in call escape.
s
private int s
Current position in input buffer.
sql
private final String sql
Original SQL string
tableName
private String tableName
First table name in from clause
terminator
private char terminator
Current expected terminator character.
timeMask
private static final byte[] timeMask
Syntax mask for time escape.
timestampMask
(package private) static final byte[] timestampMask
Syntax mask for timestamp escape.
callEscape
private void callEscape()
throws SQLException
Processes the JDBC {call procedure [(?,?,?)]} type escape.
copyKeyWord
private String copyKeyWord()
Copies over possible SQL keyword eg 'SELECT'
copyLiteral
private void copyLiteral(String txt)
throws SQLException
Inserts a String literal in the output buffer.
txt
- The text to insert.
copyParam
private void copyParam(String name,
int pos)
throws SQLException
Builds a new parameter item.
name
- Optional parameter name or null.pos
- The parameter marker position in the output buffer.
copyParamName
private String copyParamName()
Copies an embedded parameter name to the output buffer.
- The identifier as a
String
.
copyProcName
private String copyProcName()
throws SQLException
Copies an embedded stored procedure identifier over to the output buffer.
- The identifier as a
String
.
copyString
private void copyString()
Copies over an embedded string literal unchanged.
copyWhiteSpace
private void copyWhiteSpace()
Copies over white space.
escape
private void escape()
throws SQLException
Processes the JDBC escape sequences.
functionEscape
private void functionEscape()
throws SQLException
Processes the JDBC escape {fn function()}.
getCache
private static SimpleLRUCache getCache(ConnectionJDBC2 connection)
Retrieves the statement cache, creating it if required.
- the cache as a
SimpleLRUCache
getDateTimeField
private boolean getDateTimeField(byte[] mask)
throws SQLException
Utility routine to validate date and time escapes.
mask
- The validation mask
- True if the escape was valid and processed OK.
getTableName
private String getTableName()
throws SQLException
Extracts the first table name following the keyword FROM.
- the table name as a
String
isIdentifier
private static boolean isIdentifier(int ch)
Determines if character could be part of an SQL identifier.
Characters > 127 are assumed to be unicode letters in other
languages than english which is reasonable in this application.
ch
- the character to test.
boolean
true if ch in A-Z a-z 0-9 @ $ # _.
likeEscape
private void likeEscape()
throws SQLException
Processes the JDBC escape {escape 'X'}.
mustbe
private void mustbe(char c,
boolean copy)
throws SQLException
Checks that the next character is as expected.
c
- The expected character.copy
- True if found character should be copied.
outerJoinEscape
private void outerJoinEscape()
throws SQLException
Processes the JDBC escape {oj left outer join etc}.
parse
(package private) static String[] parse(String sql,
ArrayList paramList,
ConnectionJDBC2 connection,
boolean extractTable)
throws SQLException
Parse the SQL statement processing JDBC escapes and parameter markers.
extractTable
- true to return the first table name in the FROM clause of a select
- 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
String[]
.
parse
(package private) String[] parse(boolean extractTable)
throws SQLException
Parses the SQL statement processing JDBC escapes and parameter markers.
extractTable
- true to return the first table name in the FROM clause of a select
- 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
String[]
.
skipMultiComments
private void skipMultiComments()
throws SQLException
Skips multi-line comments
skipSingleComments
private void skipSingleComments()
Skips single-line comments.
skipWhiteSpace
private void skipWhiteSpace()
Skips embedded white space.