private static int parseSql()

in pgjdbc/src/main/java/org/postgresql/core/Parser.java [1209:1311]


  private static int parseSql(char[] sql, int i, StringBuilder newsql, boolean stopOnComma,
      boolean stdStrings) throws SQLException {
    SqlParseState state = SqlParseState.IN_SQLCODE;
    int len = sql.length;
    int nestedParenthesis = 0;
    boolean endOfNested = false;

    // because of the ++i loop
    i--;
    while (!endOfNested && ++i < len) {
      char c = sql[i];

      state_switch:
      switch (state) {
        case IN_SQLCODE:
          if (c == '$') {
            int i0 = i;
            i = parseDollarQuotes(sql, i);
            checkParsePosition(i, len, i0, sql,
                "Unterminated dollar quote started at position {0} in SQL {1}. Expected terminating $$");
            newsql.append(sql, i0, i - i0 + 1);
            break;
          } else if (c == '\'') {
            // start of a string?
            int i0 = i;
            i = parseSingleQuotes(sql, i, stdStrings);
            checkParsePosition(i, len, i0, sql,
                "Unterminated string literal started at position {0} in SQL {1}. Expected ' char");
            newsql.append(sql, i0, i - i0 + 1);
            break;
          } else if (c == '"') {
            // start of a identifier?
            int i0 = i;
            i = parseDoubleQuotes(sql, i);
            checkParsePosition(i, len, i0, sql,
                "Unterminated identifier started at position {0} in SQL {1}. Expected \" char");
            newsql.append(sql, i0, i - i0 + 1);
            break;
          } else if (c == '/') {
            int i0 = i;
            i = parseBlockComment(sql, i);
            checkParsePosition(i, len, i0, sql,
                "Unterminated block comment started at position {0} in SQL {1}. Expected */ sequence");
            newsql.append(sql, i0, i - i0 + 1);
            break;
          } else if (c == '-') {
            int i0 = i;
            i = parseLineComment(sql, i);
            newsql.append(sql, i0, i - i0 + 1);
            break;
          } else if (c == '(') { // begin nested sql
            nestedParenthesis++;
          } else if (c == ')') { // end of nested sql
            nestedParenthesis--;
            if (nestedParenthesis < 0) {
              endOfNested = true;
              break;
            }
          } else if (stopOnComma && c == ',' && nestedParenthesis == 0) {
            endOfNested = true;
            break;
          } else if (c == '{') { // start of an escape code?
            if (i + 1 < len) {
              SqlParseState[] availableStates = SqlParseState.VALUES;
              // skip first state, it's not a escape code state
              for (int j = 1; j < availableStates.length; j++) {
                SqlParseState availableState = availableStates[j];
                int matchedPosition = availableState.getMatchedPosition(sql, i + 1);
                if (matchedPosition == 0) {
                  continue;
                }
                i += matchedPosition;
                if (availableState.replacementKeyword != null) {
                  newsql.append(availableState.replacementKeyword);
                }
                state = availableState;
                break state_switch;
              }
            }
          }
          newsql.append(c);
          break;

        case ESC_FUNCTION:
          // extract function name
          i = escapeFunction(sql, i, newsql, stdStrings);
          state = SqlParseState.IN_SQLCODE; // end of escaped function (or query)
          break;
        case ESC_DATE:
        case ESC_TIME:
        case ESC_TIMESTAMP:
        case ESC_OUTERJOIN:
        case ESC_ESCAPECHAR:
          if (c == '}') {
            state = SqlParseState.IN_SQLCODE; // end of escape code.
          } else {
            newsql.append(c);
          }
          break;
      } // end switch
    }
    return i;
  }