tokens.consume(ALTER, TABLE);
String tableName = parseName(tokens);
AstNode alterTableNode = nodeFactory().node(tableName, parentNode, TYPE_ALTER_TABLE_STATEMENT);
tokens.consume("ADD");
// System.out.println(" >> PARSING ALTER STATEMENT >> TABLE Name = " + tableName);
if (isTableConstraint(tokens)) {
parseTableConstraint(tokens, alterTableNode, true);
} else {
// This segment can also be enclosed in "()" brackets to handle multiple ColumnDefinition ADDs
if (tokens.matches(L_PAREN, "REF")) {
// ALTER TABLE staff ADD (REF(dept) WITH ROWID);
tokens.consume(L_PAREN, "REF", L_PAREN);
parseName(tokens);
tokens.consume(R_PAREN, "WITH", "ROWID", R_PAREN);
} else if (tokens.matches(L_PAREN, "SCOPE")) {
// ALTER TABLE staff ADD (SCOPE FOR (dept) IS offices);
tokens.consume(L_PAREN, "SCOPE", "FOR", L_PAREN);
parseName(tokens);
tokens.consume(R_PAREN, "IS");
parseName(tokens);
tokens.consume(R_PAREN);
} else if (tokens.matches(L_PAREN)) {
parseColumns(tokens, alterTableNode, true);
} else {
// Assume single ADD COLUMN
parseSingleTerminatedColumnDefinition(tokens, alterTableNode, true);
}
}
parseUntilTerminator(tokens); // COULD BE "NESTED TABLE xxxxxxxx" option clause
markEndOfStatement(tokens, alterTableNode);
return alterTableNode;
} else if (tokens.matches("ALTER", "TABLE", TokenStream.ANY_VALUE, "DROP")) {
markStartOfStatement(tokens);
tokens.consume(ALTER, TABLE);
String tableName = parseName(tokens);
AstNode alterTableNode = nodeFactory().node(tableName, parentNode, TYPE_ALTER_TABLE_STATEMENT);
tokens.consume(DROP);
if (tokens.canConsume("CONSTRAINT")) {
String constraintName = parseName(tokens); // constraint name
AstNode constraintNode = nodeFactory().node(constraintName, alterTableNode, TYPE_DROP_TABLE_CONSTRAINT_DEFINITION);
if (tokens.canConsume(DropBehavior.CASCADE)) {
constraintNode.setProperty(DROP_BEHAVIOR, DropBehavior.CASCADE);
} else if (tokens.canConsume(DropBehavior.RESTRICT)) {
constraintNode.setProperty(DROP_BEHAVIOR, DropBehavior.RESTRICT);
}
} else if (tokens.canConsume("COLUMN")) {
// ALTER TABLE supplier
// DROP COLUMN supplier_name;
String columnName = parseName(tokens);
AstNode columnNode = nodeFactory().node(columnName, alterTableNode, TYPE_DROP_COLUMN_DEFINITION);
if (tokens.canConsume(DropBehavior.CASCADE)) {
columnNode.setProperty(DROP_BEHAVIOR, DropBehavior.CASCADE);
} else if (tokens.canConsume(DropBehavior.RESTRICT)) {
columnNode.setProperty(DROP_BEHAVIOR, DropBehavior.RESTRICT);
}
} else {
parseUntilTerminator(tokens); // EXAMPLE: "DROP UNIQUE (email)", or "DROP (col_1, col_2)"
}
markEndOfStatement(tokens, alterTableNode);
return alterTableNode;
} else if (tokens.matches("ALTER", "TABLE", TokenStream.ANY_VALUE, "RENAME")) {
// ALTER TABLE customers RENAME TO my_customers;
// ALTER TABLE customers RENAME CONSTRAINT cust_fname_nn TO cust_firstname_nn;
markStartOfStatement(tokens);
tokens.consume(ALTER, TABLE);
String oldName = parseName(tokens);
AstNode alterTableNode = nodeFactory().node(oldName, parentNode, TYPE_ALTER_TABLE_STATEMENT);
if (tokens.canConsume("RENAME", "TO")) {
String newName = parseName(tokens);
alterTableNode.setProperty(NEW_NAME, newName);
parseUntilTerminator(tokens);
} else if (tokens.canConsume("RENAME", "COLUMN")) {
String oldColumnName = parseName(tokens);
tokens.consume("TO");
String newColumnName = parseName(tokens);
parseUntilTerminator(tokens);
AstNode renameColumnNode = nodeFactory().node(oldColumnName, alterTableNode, TYPE_RENAME_COLUMN);
renameColumnNode.setProperty(NEW_NAME, newColumnName);
} else if (tokens.canConsume("RENAME", "CONSTRAINT")) {
String oldConstraintName = parseName(tokens);
tokens.consume("TO");
String newConstraintName = parseName(tokens);
parseUntilTerminator(tokens);
AstNode renameColumnNode = nodeFactory().node(oldConstraintName, alterTableNode, TYPE_RENAME_CONSTRAINT);
renameColumnNode.setProperty(NEW_NAME, newConstraintName);
}
markEndOfStatement(tokens, alterTableNode);
return alterTableNode;