static ParsedDeclareStatement parse()

in src/main/java/com/google/cloud/spanner/pgadapter/statements/DeclareStatement.java [182:254]


  static ParsedDeclareStatement parse(String sql) {
    Preconditions.checkNotNull(sql);

    // DECLARE name [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ]
    //    CURSOR [ { WITH | WITHOUT } HOLD ] FOR query
    // The keywords ASENSITIVE, BINARY, INSENSITIVE, and SCROLL can appear in any order.
    SimpleParser parser = new SimpleParser(sql);
    if (!parser.eatKeyword("declare")) {
      throw PGExceptionFactory.newPGException(
          "not a valid DECLARE statement: " + sql, SQLState.SyntaxError);
    }
    Builder builder = new Builder();
    TableOrIndexName name = parser.readTableOrIndexName();
    if (name == null || name.schema != null) {
      throw PGExceptionFactory.newPGException("invalid cursor name: " + sql, SQLState.SyntaxError);
    }
    builder.name = unquoteOrFoldIdentifier(name.name);
    while (parser.hasMoreTokens()
        && !parser.peekKeyword("cursor")
        && !parser.peekKeyword("for")
        && !parser.peekKeyword("with")
        && !parser.peekKeyword("without")) {
      if (parser.eatKeyword("binary")) {
        builder.binary = true;
      } else if (parser.eatKeyword("asensitive")) {
        if (builder.sensitivity == Sensitivity.INSENSITIVE) {
          throw PGExceptionFactory.newPGException(
              "cannot specify both INSENSITIVE and ASENSITIVE", SQLState.SyntaxError);
        }
        builder.sensitivity = Sensitivity.ASENSITIVE;
      } else if (parser.eatKeyword("insensitive")) {
        if (builder.sensitivity == Sensitivity.ASENSITIVE) {
          throw PGExceptionFactory.newPGException(
              "cannot specify both INSENSITIVE and ASENSITIVE", SQLState.SyntaxError);
        }
        builder.sensitivity = Sensitivity.INSENSITIVE;
      } else if (parser.eatKeyword("scroll")) {
        if (builder.scroll == Scroll.NO_SCROLL) {
          throw PGExceptionFactory.newPGException(
              "cannot specify both SCROLL and NO SCROLL", SQLState.SyntaxError);
        }
        builder.scroll = Scroll.SCROLL;
      } else if (parser.eatKeyword("no", "scroll")) {
        if (builder.scroll == Scroll.SCROLL) {
          throw PGExceptionFactory.newPGException(
              "cannot specify both SCROLL and NO SCROLL", SQLState.SyntaxError);
        }
        builder.scroll = Scroll.NO_SCROLL;
      } else {
        throw PGExceptionFactory.newPGException("syntax error: " + sql, SQLState.SyntaxError);
      }
    }
    if (!parser.eatKeyword("cursor")) {
      throw PGExceptionFactory.newPGException(
          "missing expected CURSOR keyword: " + sql, SQLState.SyntaxError);
    }
    if (parser.eatKeyword("with", "hold")) {
      builder.holdability = Holdability.HOLD;
    } else if (parser.eatKeyword("without", "hold")) {
      builder.holdability = Holdability.NO_HOLD;
    }
    if (!parser.eatKeyword("for")) {
      throw PGExceptionFactory.newPGException(
          "missing expected FOR keyword: " + sql, SQLState.SyntaxError);
    }
    if (!parser.hasMoreTokens()) {
      throw PGExceptionFactory.newPGException(
          "missing query for cursor: " + sql, SQLState.SyntaxError);
    }
    builder.sql = parser.getSql().substring(parser.getPos()).trim();

    return new ParsedDeclareStatement(builder);
  }