/* * Copyright 1999-2017 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.druid.sql.parser; import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.util.FnvHash; import com.alibaba.druid.util.JdbcConstants; public class SQLCreateTableParser extends SQLDDLParser { public SQLCreateTableParser(String sql) { super(sql); } public SQLCreateTableParser(SQLExprParser exprParser) { super(exprParser); } public SQLCreateTableStatement parseCreateTable() { List comments = null; if (lexer.isKeepComments() && lexer.hasComment()) { comments = lexer.readAndResetComments(); } SQLCreateTableStatement stmt = parseCreateTable(true); if (comments != null) { stmt.addBeforeComment(comments); } return stmt; } public SQLCreateTableStatement parseCreateTable(boolean acceptCreate) { SQLCreateTableStatement createTable = newCreateStatement(); if (acceptCreate) { if (lexer.hasComment() && lexer.isKeepComments()) { createTable.addBeforeComment(lexer.readAndResetComments()); } accept(Token.CREATE); } if (lexer.identifierEquals("GLOBAL")) { lexer.nextToken(); if (lexer.identifierEquals("TEMPORARY")) { lexer.nextToken(); createTable.setType(SQLCreateTableStatement.Type.GLOBAL_TEMPORARY); } else { throw new ParserException("syntax error " + lexer.info()); } } else if (lexer.token == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("LOCAL")) { lexer.nextToken(); if (lexer.token == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("TEMPORAY")) { lexer.nextToken(); createTable.setType(SQLCreateTableStatement.Type.LOCAL_TEMPORARY); } else { throw new ParserException("syntax error. " + lexer.info()); } } accept(Token.TABLE); if (lexer.token() == Token.IF) { lexer.nextToken(); accept(Token.NOT); accept(Token.EXISTS); createTable.setIfNotExiists(true); } createTable.setName(this.exprParser.name()); if (lexer.token == Token.LPAREN) { lexer.nextToken(); for (; ; ) { Token token = lexer.token; if (token == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("SUPPLEMENTAL") && JdbcConstants.ORACLE.equals(dbType)) { this.parseCreateTableSupplementalLogingProps(createTable); } else if (token == Token.IDENTIFIER // || token == Token.LITERAL_ALIAS) { SQLColumnDefinition column = this.exprParser.parseColumn(); createTable.getTableElementList().add(column); } else if (token == Token.PRIMARY // || token == Token.UNIQUE // || token == Token.CHECK // || token == Token.CONSTRAINT || token == Token.FOREIGN) { SQLConstraint constraint = this.exprParser.parseConstaint(); constraint.setParent(createTable); createTable.getTableElementList().add((SQLTableElement) constraint); } else if (token == Token.TABLESPACE) { throw new ParserException("TODO " + lexer.info()); } else { SQLColumnDefinition column = this.exprParser.parseColumn(); createTable.getTableElementList().add(column); } if (lexer.token == Token.COMMA) { lexer.nextToken(); if (lexer.token == Token.RPAREN) { // compatible for sql server break; } continue; } break; } accept(Token.RPAREN); if (lexer.identifierEquals(FnvHash.Constants.INHERITS)) { lexer.nextToken(); accept(Token.LPAREN); SQLName inherits = this.exprParser.name(); createTable.setInherits(new SQLExprTableSource(inherits)); accept(Token.RPAREN); } } if (lexer.token == Token.AS) { lexer.nextToken(); SQLSelect select = this.createSQLSelectParser().select(); createTable.setSelect(select); } if (lexer.token == Token.WITH && JdbcConstants.POSTGRESQL.equals(dbType)) { lexer.nextToken(); accept(Token.LPAREN); for (;;) { String name = lexer.stringVal(); lexer.nextToken(); accept(Token.EQ); SQLExpr value = this.exprParser.expr(); value.setParent(createTable); createTable.getTableOptions().put(name, value); if (lexer.token == Token.COMMA) { lexer.nextToken(); continue; } break; } accept(Token.RPAREN); } return createTable; } protected void parseCreateTableSupplementalLogingProps(SQLCreateTableStatement stmt) { throw new ParserException("TODO " + lexer.info()); } protected SQLCreateTableStatement newCreateStatement() { return new SQLCreateTableStatement(getDbType()); } }