Class SQLParser

java.lang.Object
net.sourceforge.jtds.jdbc.SQLParser

class SQLParser extends Object
Process JDBC escape strings and parameter markers in the SQL string.

This code recognizes the following escapes:

  1. Date {d 'yyyy-mm-dd'}
  2. Time {t 'hh:mm:ss'}
  3. Timestamp {ts 'yyyy-mm-dd hh:mm:ss.nnn'}
  4. ESCAPE {escape 'x'}
  5. Function {fn xxxx([arg,arg...])} NB The concat(arg, arg) operator is converted to (arg + arg)
  6. OuterJoin {oj .....}
  7. Call {?=call proc [arg, arg...]} or {call proc [arg, arg...]}
Notes:
  1. This code is designed to be as efficient as possible and as result the validation done here is limited.
Author:
Mike Hutchinson, Holger Rehn
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    private static class 
    Serialized version of a parsed SQL query (the value stored in the cache for a parsed SQL).
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    a LRU cache for the last 500 parsed SQL statements
    private final JtdsConnection
    Connection object for server specific parsing.
    private static HashMap
    Map of jdbc to server data types for convert
    private int
    Current position in output buffer.
    private static final byte[]
    Syntax mask for date escape.
    private static HashMap
    Map of jdbc to sybase function names.
    private static boolean[]
    Lookup table to test if character is part of an identifier.
    private final char[]
    Input buffer with SQL statement.
    private String
    First SQL keyword or identifier in statement.
    private final int
    Length of input buffer.
    private static HashMap
    Map of jdbc to sql server function names.
    private char[]
    Output buffer to contain parsed SQL.
    private final ArrayList
    Parameter list to be populated or null if no parameters are expected.
    private String
    Procedure name in call escape.
    private int
    Current position in input buffer.
    private final String
    Original SQL string
    private String
    First table name in from clause
    private char
    Current expected terminator character.
    private static final byte[]
    Syntax mask for time escape.
    (package private) static final byte[]
    Syntax mask for timestamp escape.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    SQLParser(String sqlIn, ArrayList paramList, JtdsConnection connection)
    Constructs a new parser object to process the supplied SQL.
  • Method Summary

    Modifier and Type
    Method
    Description
    private final void
    append(char character)
    Adds the given character to out, incrementing d by 1 and expanding out by a fixed number of characters if necessary.
    private final void
    append(char[] chars)
     
    private void
    Processes the JDBC {call procedure [(?,?,?)]} type escape.
    private String
    Copies over possible SQL keyword eg 'SELECT'
    private void
    Inserts a String literal in the output buffer.
    private void
    copyParam(String name, int pos)
    Builds a new parameter item.
    private String
    Copies an embedded parameter name to the output buffer.
    private String
    Copies an embedded stored procedure identifier over to the output buffer.
    private void
    Copies over an embedded string literal unchanged.
    private void
    Copies over white space.
    private void
    Processes the JDBC escape sequences.
    private void
    Processes the JDBC escape {fn function()}.
    private boolean
    getDateTimeField(byte[] mask)
    Utility routine to validate date and time escapes.
    private String
    Extracts the first table name following the keyword FROM.
    private static boolean
    isIdentifier(int ch)
    Determines if character could be part of an SQL identifier.
    private void
    Processes the JDBC escape {escape 'X'}.
    private void
    mustbe(char c, boolean copy)
    Checks that the next character is as expected.
    private void
    Processes the JDBC escape {oj left outer join etc}.
    (package private) String[]
    parse(boolean extractTable)
    Parses the SQL statement processing JDBC escapes and parameter markers.
    (package private) static String[]
    parse(String sql, ArrayList paramList, JtdsConnection connection, boolean extractTable)
    Parse the SQL statement processing JDBC escapes and parameter markers.
    private void
    Skips multi-line comments
    private void
    Skips single-line comments.
    private void
     

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • _Cache

      private static final SimpleLRUCache<SQLCacheKey,SQLParser.CachedSQLQuery> _Cache
      a LRU cache for the last 500 parsed SQL statements
    • sql

      private final String sql
      Original SQL string
    • in

      private final char[] in
      Input buffer with SQL statement.
    • s

      private int s
      Current position in input buffer.
    • len

      private final int len
      Length of input buffer.
    • out

      private char[] out
      Output buffer to contain parsed SQL.
    • d

      private int d
      Current position in output buffer.
    • params

      private final ArrayList params
      Parameter list to be populated or null if no parameters are expected.
    • terminator

      private char terminator
      Current expected terminator character.
    • procName

      private String procName
      Procedure name in call escape.
    • keyWord

      private String keyWord
      First SQL keyword or identifier in statement.
    • tableName

      private String tableName
      First table name in from clause
    • connection

      private final JtdsConnection connection
      Connection object for server specific parsing.
    • identifierChar

      private static boolean[] identifierChar
      Lookup table to test if character is part of an identifier.
    • timeMask

      private static final byte[] timeMask
      Syntax mask for time escape.
    • dateMask

      private static final byte[] dateMask
      Syntax mask for date escape.
    • timestampMask

      static final byte[] timestampMask
      Syntax mask for timestamp escape.
    • fnMap

      private static HashMap fnMap
      Map of jdbc to sybase function names.
    • msFnMap

      private static HashMap msFnMap
      Map of jdbc to sql server function names.
    • cvMap

      private static HashMap cvMap
      Map of jdbc to server data types for convert
  • Constructor Details

    • SQLParser

      private SQLParser(String sqlIn, ArrayList paramList, JtdsConnection connection)
      Constructs a new parser object to process the supplied SQL.
      Parameters:
      sqlIn - the SQL statement to parse
      paramList - the parameter list array to populate or null if no parameters are expected
      connection - the parent Connection object
  • Method Details

    • parse

      static String[] parse(String sql, ArrayList paramList, JtdsConnection connection, boolean extractTable) throws SQLException

      Parse the SQL statement processing JDBC escapes and parameter markers.

      Parameters:
      extractTable - true to return the first table name in the FROM clause of a SELECT
      Returns:
      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[].
      Throws:
      SQLException - if a parse error occurs
    • 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.

      Parameters:
      ch - the character to test.
      Returns:
      boolean true if ch in A-Z a-z 0-9 @ $ # _.
    • copyLiteral

      private void copyLiteral(String txt) throws SQLException
      Inserts a String literal in the output buffer.
      Parameters:
      txt - The text to insert.
      Throws:
      SQLException
    • copyString

      private void copyString()
      Copies over an embedded string literal unchanged.
    • copyKeyWord

      private String copyKeyWord()
      Copies over possible SQL keyword eg 'SELECT'
    • copyParam

      private void copyParam(String name, int pos) throws SQLException
      Builds a new parameter item.
      Parameters:
      name - Optional parameter name or null.
      pos - The parameter marker position in the output buffer.
      Throws:
      SQLException
    • copyProcName

      private String copyProcName() throws SQLException
      Copies an embedded stored procedure identifier over to the output buffer.
      Returns:
      The identifier as a String.
      Throws:
      SQLException
    • copyParamName

      private String copyParamName()
      Copies an embedded parameter name to the output buffer.
      Returns:
      The identifier as a String.
    • copyWhiteSpace

      private void copyWhiteSpace()
      Copies over white space.
    • mustbe

      private void mustbe(char c, boolean copy) throws SQLException
      Checks that the next character is as expected.
      Parameters:
      c - The expected character.
      copy - True if found character should be copied.
      Throws:
      SQLException - if expected characeter not found.
    • skipWhiteSpace

      private void skipWhiteSpace() throws SQLException
      Throws:
      SQLException
    • skipSingleComments

      private void skipSingleComments()
      Skips single-line comments.
    • skipMultiComments

      private void skipMultiComments() throws SQLException
      Skips multi-line comments
      Throws:
      SQLException
    • callEscape

      private void callEscape() throws SQLException
      Processes the JDBC {call procedure [(?,?,?)]} type escape.
      Throws:
      SQLException - if an error occurs
    • getDateTimeField

      private boolean getDateTimeField(byte[] mask) throws SQLException
      Utility routine to validate date and time escapes.
      Parameters:
      mask - The validation mask
      Returns:
      True if the escape was valid and processed OK.
      Throws:
      SQLException
    • outerJoinEscape

      private void outerJoinEscape() throws SQLException
      Processes the JDBC escape {oj left outer join etc}.
      Throws:
      SQLException
    • functionEscape

      private void functionEscape() throws SQLException
      Processes the JDBC escape {fn function()}.
      Throws:
      SQLException
    • likeEscape

      private void likeEscape() throws SQLException
      Processes the JDBC escape {escape 'X'}.
      Throws:
      SQLException
    • escape

      private void escape() throws SQLException
      Processes the JDBC escape sequences.
      Throws:
      SQLException
    • getTableName

      private String getTableName() throws SQLException
      Extracts the first table name following the keyword FROM.
      Returns:
      the table name as a String
      Throws:
      SQLException
    • append

      private final void append(char[] chars)
    • append

      private final void append(char character)

      Adds the given character to out, incrementing d by 1 and expanding out by a fixed number of characters if necessary.

    • parse

      String[] parse(boolean extractTable) throws SQLException
      Parses the SQL statement processing JDBC escapes and parameter markers.
      Parameters:
      extractTable - true to return the first table name in the FROM clause of a select
      Returns:
      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[].
      Throws:
      SQLException