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);
}