parser.java
来自「非常棒的java数据库」· Java 代码 · 共 1,699 行 · 第 1/5 页
JAVA
1,699 行
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.command;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.text.Collator;
import java.util.HashSet;
import org.h2.api.Trigger;
import org.h2.command.ddl.AlterIndexRename;
import org.h2.command.ddl.AlterTableAddConstraint;
import org.h2.command.ddl.AlterTableAlterColumn;
import org.h2.command.ddl.AlterTableDropConstraint;
import org.h2.command.ddl.AlterTableRename;
import org.h2.command.ddl.AlterTableRenameColumn;
import org.h2.command.ddl.AlterUser;
import org.h2.command.ddl.AlterView;
import org.h2.command.ddl.Analyze;
import org.h2.command.ddl.CreateAggregate;
import org.h2.command.ddl.CreateConstant;
import org.h2.command.ddl.CreateFunctionAlias;
import org.h2.command.ddl.CreateIndex;
import org.h2.command.ddl.CreateLinkedTable;
import org.h2.command.ddl.CreateRole;
import org.h2.command.ddl.CreateSchema;
import org.h2.command.ddl.CreateSequence;
import org.h2.command.ddl.CreateTable;
import org.h2.command.ddl.CreateTrigger;
import org.h2.command.ddl.CreateUser;
import org.h2.command.ddl.CreateUserDataType;
import org.h2.command.ddl.CreateView;
import org.h2.command.ddl.DeallocateProcedure;
import org.h2.command.ddl.DropAggregate;
import org.h2.command.ddl.DropConstant;
import org.h2.command.ddl.DropDatabase;
import org.h2.command.ddl.DropFunctionAlias;
import org.h2.command.ddl.DropIndex;
import org.h2.command.ddl.DropRole;
import org.h2.command.ddl.DropSchema;
import org.h2.command.ddl.DropSequence;
import org.h2.command.ddl.DropTable;
import org.h2.command.ddl.DropTrigger;
import org.h2.command.ddl.DropUser;
import org.h2.command.ddl.DropUserDataType;
import org.h2.command.ddl.DropView;
import org.h2.command.ddl.GrantRevoke;
import org.h2.command.ddl.PrepareProcedure;
import org.h2.command.ddl.SetComment;
import org.h2.command.ddl.TruncateTable;
import org.h2.command.dml.AlterSequence;
import org.h2.command.dml.AlterTableSet;
import org.h2.command.dml.BackupCommand;
import org.h2.command.dml.Call;
import org.h2.command.dml.Delete;
import org.h2.command.dml.ExecuteProcedure;
import org.h2.command.dml.ExplainPlan;
import org.h2.command.dml.Insert;
import org.h2.command.dml.Merge;
import org.h2.command.dml.NoOperation;
import org.h2.command.dml.Query;
import org.h2.command.dml.RunScriptCommand;
import org.h2.command.dml.ScriptCommand;
import org.h2.command.dml.Select;
import org.h2.command.dml.SelectOrderBy;
import org.h2.command.dml.SelectUnion;
import org.h2.command.dml.Set;
import org.h2.command.dml.SetTypes;
import org.h2.command.dml.TransactionCommand;
import org.h2.command.dml.Update;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.constraint.ConstraintReferential;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.DbObject;
import org.h2.engine.FunctionAlias;
import org.h2.engine.Procedure;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.engine.Setting;
import org.h2.engine.User;
import org.h2.engine.UserAggregate;
import org.h2.engine.UserDataType;
import org.h2.expression.Aggregate;
import org.h2.expression.Alias;
import org.h2.expression.CompareLike;
import org.h2.expression.Comparison;
import org.h2.expression.ConditionAndOr;
import org.h2.expression.ConditionExists;
import org.h2.expression.ConditionIn;
import org.h2.expression.ConditionInSelect;
import org.h2.expression.ConditionNot;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn;
import org.h2.expression.ExpressionList;
import org.h2.expression.Function;
import org.h2.expression.FunctionCall;
import org.h2.expression.JavaAggregate;
import org.h2.expression.JavaFunction;
import org.h2.expression.Operation;
import org.h2.expression.Parameter;
import org.h2.expression.Rownum;
import org.h2.expression.SequenceValue;
import org.h2.expression.Subquery;
import org.h2.expression.TableFunction;
import org.h2.expression.ValueExpression;
import org.h2.expression.Variable;
import org.h2.expression.Wildcard;
import org.h2.index.Index;
import org.h2.message.Message;
import org.h2.result.SortOrder;
import org.h2.schema.Schema;
import org.h2.schema.Sequence;
import org.h2.table.Column;
import org.h2.table.FunctionTable;
import org.h2.table.IndexColumn;
import org.h2.table.RangeTable;
import org.h2.table.Table;
import org.h2.table.TableData;
import org.h2.table.TableFilter;
import org.h2.table.TableView;
import org.h2.util.ByteUtils;
import org.h2.util.MathUtils;
import org.h2.util.ObjectArray;
import org.h2.util.StringCache;
import org.h2.util.StringUtils;
import org.h2.value.CompareMode;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueBoolean;
import org.h2.value.ValueBytes;
import org.h2.value.ValueDate;
import org.h2.value.ValueDecimal;
import org.h2.value.ValueInt;
import org.h2.value.ValueString;
import org.h2.value.ValueTime;
import org.h2.value.ValueTimestamp;
/**
* The parser is used to convert a SQL statement string to an command object.
*/
public class Parser {
// used during the tokenizer phase
private static final int CHAR_END = -1, CHAR_VALUE = 2, CHAR_QUOTED = 3;
private static final int CHAR_NAME = 4, CHAR_SPECIAL_1 = 5, CHAR_SPECIAL_2 = 6;
private static final int CHAR_STRING = 7, CHAR_DECIMAL = 8;
// this are token types
private static final int KEYWORD = 1, IDENTIFIER = 2, PARAMETER = 3, END = 4, VALUE = 5;
private static final int EQUAL = 6, BIGGER_EQUAL = 7, BIGGER = 8;
private static final int SMALLER = 9, SMALLER_EQUAL = 10, NOT_EQUAL = 11, AT = 12;
private static final int MINUS = 17, PLUS = 18;
private static final int STRING_CONCAT = 22;
private static final int OPEN = 31, CLOSE = 32, NULL = 34, TRUE = 40, FALSE = 41;
private static final int CURRENT_TIMESTAMP = 42, CURRENT_DATE = 43, CURRENT_TIME = 44, ROWNUM = 45;
private final Database database;
private final Session session;
private int[] characterTypes;
private int currentTokenType;
private String currentToken;
private boolean currentTokenQuoted;
private Value currentValue;
private String sqlCommand, originalSQL;
private char[] sqlCommandChars;
private int lastParseIndex;
private int parseIndex;
private Prepared prepared;
private Prepared currentPrepared;
private Select currentSelect;
private ObjectArray parameters;
private String schemaName;
private ObjectArray expected;
private boolean rightsChecked;
private boolean recompileAlways;
private ObjectArray indexedParameterList;
public Parser(Session session) {
this.session = session;
database = session.getDatabase();
}
/**
* Parse the statement and prepare it for execution.
*
* @param sql the SQL statement to parse
* @return the prepared object
*/
public Prepared prepare(String sql) throws SQLException {
try {
Prepared p = parse(sql);
p.prepare();
return p;
} catch (Exception e) {
throw Message.convert(e);
}
}
/**
* Parse the statement, but don't prepare it for execution.
*
* @param sql the SQL statement to parse
* @return the prepared object
*/
public Prepared parseOnly(String sql) throws SQLException {
try {
return parse(sql);
} catch (Exception e) {
throw Message.convert(e);
}
}
/**
* Parse a statement or a list of statements, and prepare it for execution.
*
* @param sql the SQL statement to parse
* @return the command object
*/
public Command prepareCommand(String sql) throws SQLException {
try {
Prepared p = parse(sql);
p.prepare();
Command c = new CommandContainer(this, sql, p);
p.setCommand(c);
if (isToken(";")) {
String remaining = originalSQL.substring(parseIndex);
if (remaining.trim().length() != 0) {
CommandList list = new CommandList(this, sql, c, remaining);
// list.addCommand(c);
// do {
// c = parseCommand();
// list.addCommand(c);
// } while(currentToken.equals(";"));
c = list;
}
} else if (currentTokenType != END) {
throw getSyntaxError();
}
return c;
} catch (Exception e) {
throw Message.addSQL(Message.convert(e), this.originalSQL);
}
}
private Prepared parse(String sql) throws SQLException {
Prepared p;
try {
// first, try the fast variant
p = parse(sql, false);
} catch (SQLException e) {
if (e.getErrorCode() == ErrorCode.SYNTAX_ERROR_1) {
// now, get the detailed exception
p = parse(sql, true);
} else {
throw Message.addSQL(e, sql);
}
}
p.setPrepareAlways(recompileAlways);
p.setParameterList(parameters);
return p;
}
private Prepared parse(String sql, boolean withExpectedList) throws SQLException {
initialize(sql);
if (withExpectedList) {
expected = new ObjectArray();
} else {
expected = null;
}
parameters = new ObjectArray();
currentSelect = null;
currentPrepared = null;
prepared = null;
recompileAlways = false;
indexedParameterList = null;
read();
return parsePrepared();
}
private Prepared parsePrepared() throws SQLException {
int start = lastParseIndex;
Prepared c = null;
String token = currentToken;
if (token.length() == 0) {
c = new NoOperation(session);
} else {
char first = token.charAt(0);
switch (first) {
case '(':
c = parseSelect();
break;
case 'A':
if (readIf("ALTER")) {
c = parseAlter();
} else if (readIf("ANALYZE")) {
c = parseAnalyze();
}
break;
case 'B':
if (readIf("BACKUP")) {
c = parseBackup();
} else if (readIf("BEGIN")) {
c = parseBegin();
}
break;
case 'C':
if (readIf("COMMIT")) {
c = parseCommit();
} else if (readIf("CREATE")) {
c = parseCreate();
} else if (readIf("CALL")) {
c = parserCall();
} else if (readIf("CHECKPOINT")) {
c = parseCheckpoint();
} else if (readIf("COMMENT")) {
c = parseComment();
}
break;
case 'D':
if (readIf("DELETE")) {
c = parseDelete();
} else if (readIf("DROP")) {
c = parseDrop();
} else if (readIf("DECLARE")) {
// support for DECLARE GLOBAL TEMPORARY TABLE...
c = parseCreate();
} else if (readIf("DEALLOCATE")) {
c = parseDeallocate();
}
break;
case 'E':
if (readIf("EXPLAIN")) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?