📄 sqlparser.java
字号:
if(token.value != SQLTokenizer.PARENTHESIS_L) throw createSyntaxError(token, MISSING_PARENTHESIS_L );
Loop:
while(true){
int offset = token.offset + token.length;
token = nextToken();
if(token != null) offset = token.offset;
previousToken();
expressions.add( expression(cmd, 0) );
SQLToken last = lastToken();
int length = last.offset + last.length - offset;
columns.add( new String( sql, offset, length ) );
token = nextToken(MISSING_COMMA_PARENTHESIS);
switch(token.value){
case SQLTokenizer.PARENTHESIS_R:
break Loop;
case SQLTokenizer.COMMA:
continue;
default:
throw new Error();
}
}
}
/**
* Read a complex expression that can be build from multiple atomic expressions.
* @param cmd is needed to add parameters "?" with addParameter()
* @param previousOperationLevel the level of the left operation.
*/
private Expression expression(Command cmd, int previousOperationLevel) throws SQLException{
SQLToken token = nextToken();
if(token == null) return null;
Expression leftExpr;
switch(token.value){
case SQLTokenizer.NOT:
leftExpr = new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.NOT / 10), ExpressionArithmetic.NOT);
break;
case SQLTokenizer.MINUS:
leftExpr = new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.NEGATIVE / 10), ExpressionArithmetic.NEGATIVE);
break;
case SQLTokenizer.TILDE:
leftExpr = new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.BIT_NOT / 10), ExpressionArithmetic.BIT_NOT);
break;
case SQLTokenizer.PARENTHESIS_L:
leftExpr = expression( cmd, 0);
token = nextToken(MISSING_PARENTHESIS_R);
break;
default:
leftExpr = expressionSingle( cmd, token);
}
boolean isNot = false;
while((token = nextToken()) != null){
Expression rightExpr;
int operation = ExpressionArithmetic.getOperationFromToken(token.value);
int level = operation / 10;
if(previousOperationLevel >= level){
previousToken();
return leftExpr;
}
switch(token.value){
case SQLTokenizer.PLUS:
case SQLTokenizer.MINUS:
case SQLTokenizer.ASTERISK:
case SQLTokenizer.SLACH:
case SQLTokenizer.PERCENT:
case SQLTokenizer.EQUALS:
case SQLTokenizer.LESSER:
case SQLTokenizer.LESSER_EQU:
case SQLTokenizer.GREATER:
case SQLTokenizer.GREATER_EQU:
case SQLTokenizer.UNEQUALS:
case SQLTokenizer.LIKE:
case SQLTokenizer.OR:
case SQLTokenizer.AND:
case SQLTokenizer.BIT_AND:
case SQLTokenizer.BIT_OR:
case SQLTokenizer.BIT_XOR:
rightExpr = expression( cmd, level );
leftExpr = new ExpressionArithmetic( leftExpr, rightExpr, operation );
break;
case SQLTokenizer.BETWEEN:
rightExpr = expression( cmd, ExpressionArithmetic.AND );
nextToken( MISSING_AND );
Expression rightExpr2 = expression( cmd, level );
leftExpr = new ExpressionArithmetic( leftExpr, rightExpr, rightExpr2, operation );
break;
case SQLTokenizer.IN:
nextToken(MISSING_PARENTHESIS_L);
token = nextToken(MISSING_EXPRESSION);
if(token.value == SQLTokenizer.SELECT){
CommandSelect cmdSel = select();
leftExpr = new ExpressionInSelect( con, leftExpr, cmdSel, operation );
nextToken(MISSING_PARENTHESIS_R);
}else{
previousToken();
Expressions list = expressionParenthesisList( cmd );
leftExpr = new ExpressionArithmetic( leftExpr, list, operation );
}
break;
case SQLTokenizer.IS:
token = nextToken(MISSING_NOT_NULL);
if(token.value == SQLTokenizer.NOT){
nextToken(MISSING_NULL);
operation++;
}
leftExpr = new ExpressionArithmetic( leftExpr, operation );
break;
case SQLTokenizer.NOT:
token = nextToken(MISSING_BETWEEN_IN);
previousToken();
isNot = true;
continue;
default:
previousToken();
return leftExpr;
}
if(isNot){
isNot = false;
leftExpr = new ExpressionArithmetic( leftExpr, ExpressionArithmetic.NOT);
}
}
previousToken();
return leftExpr;
}
/**
* parst einen einzelne Expression, wie 12, 'qwert', 0x3F oder column name
*
* @param cmd is needed to add parameters "?" with addParameter()
*/
private Expression expressionSingle(Command cmd, SQLToken token) throws SQLException{
boolean isMinus = false;
if(token != null){
switch(token.value){
case SQLTokenizer.NULL:
return new ExpressionValue( null, SQLTokenizer.NULL );
case SQLTokenizer.STRING:
return new ExpressionValue( token.getName(null), SQLTokenizer.VARCHAR );
case SQLTokenizer.IDENTIFIER:
{
String name = getIdentifier( token );
ExpressionName expr = new ExpressionName( name );
SQLToken token2 = nextToken();
if(token2 != null && token2.value == SQLTokenizer.POINT){
expr.setNameAfterTableAlias( nextIdentifier() );
}else{
previousToken();
}
return expr;
}
case SQLTokenizer.TRUE:
return new ExpressionValue( Boolean.TRUE, SQLTokenizer.BOOLEAN );
case SQLTokenizer.FALSE:
return new ExpressionValue( Boolean.FALSE, SQLTokenizer.BOOLEAN );
case SQLTokenizer.ESCAPE_L:{
token = nextToken(COMMANDS_ESCAPE);
SQLToken para = nextToken(MISSING_EXPRESSION);
Expression expr;
switch(token.value){
case SQLTokenizer.D: // date escape sequence
expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.DATE), SQLTokenizer.DATE );
break;
case SQLTokenizer.T: // time escape sequnce
expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.TIME), SQLTokenizer.TIME );
break;
case SQLTokenizer.TS: // timestamp escape sequence
expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.TIMESTAMP), SQLTokenizer.TIMESTAMP );
break;
case SQLTokenizer.FN: // function escape sequence
nextToken(MISSING_PARENTHESIS_L);
expr = function(cmd, para, true);
break;
case SQLTokenizer.CALL: // call escape sequence
throw new java.lang.UnsupportedOperationException("call escape sequence");
default: throw new Error();
}
token = nextToken( ESCAPE_MISSING_CLOSE );
return expr;
}
case SQLTokenizer.QUESTION:
ExpressionValue param = new ExpressionValue();
cmd.addParameter( param );
return param;
case SQLTokenizer.CASE:
return caseExpr(cmd);
case SQLTokenizer.MINUS:
case SQLTokenizer.PLUS:
// Vorzeichenerkennung
do{
if(token.value == SQLTokenizer.MINUS)
isMinus = !isMinus;
token = nextToken();
if(token == null) throw createSyntaxError( token, MISSING_EXPRESSION );
}while(token.value == SQLTokenizer.MINUS || token.value == SQLTokenizer.PLUS);
// kein Break
default:
SQLToken token2 = nextToken();
if(token2 != null && token2.value == SQLTokenizer.PARENTHESIS_L){
if(isMinus)
return new ExpressionArithmetic( function( cmd, token, false ), ExpressionArithmetic.NEGATIVE );
return function( cmd, token, false );
}else{
// Konstanter Ausdruck oder Identifer
char chr1 = sql[ token.offset ];
if(chr1 == '$'){
previousToken();
String tok = new String(sql, token.offset+1, token.length-1);
if(isMinus) tok = "-" + tok;
return new ExpressionValue( new Money(Double.parseDouble(tok)), SQLTokenizer.MONEY );
}
String tok = new String(sql, token.offset, token.length);
if((chr1 >= '0' && '9' >= chr1) || chr1 == '.'){
previousToken();
//erstes Zeichen ein digit
if(token.length>1 && (sql[ token.offset +1 ] | 0x20) == 'x'){
// bin鋜 Daten als Hex
if(isMinus) throw createSyntaxError( token, "Invalid operator minus for data type varbinary.");
return new ExpressionValue( Utils.hex2bytes( sql, token.offset+2, token.length-2), SQLTokenizer.VARBINARY );
}
if(isMinus) tok = "-" + tok;
if(Utils.indexOf( '.', sql, token.offset, token.length ) >= 0 ||
Utils.indexOf( 'e', sql, token.offset, token.length ) >= 0){
return new ExpressionValue( new Double(tok), SQLTokenizer.DOUBLE );
}else{
try{
return new ExpressionValue( new Integer(tok), SQLTokenizer.INT );
}catch(NumberFormatException e){
return new ExpressionValue( new Long(tok), SQLTokenizer.BIGINT );
}
}
}else{
// Bezeichner
checkValidIdentifier( tok, token );
ExpressionName expr = new ExpressionName(tok);
if(token2 != null && token2.value == SQLTokenizer.POINT){
expr.setNameAfterTableAlias( nextIdentifier() );
}else{
previousToken();
}
if(isMinus)
return new ExpressionArithmetic( expr, ExpressionArithmetic.NEGATIVE );
return expr;
}
}
}
}
return null;
}
ExpressionFunctionCase caseExpr(final Command cmd) throws SQLException{
ExpressionFunctionCase expr = new ExpressionFunctionCase();
SQLToken token = nextToken(MISSING_EXPRESSION);
Expression input = null;
if(token.value != SQLTokenizer.WHEN){
// simple CASE Syntax
previousToken();
input = expression(cmd, 0);
token = nextToken(MISSING_WHEN_ELSE_END);
}
while(true){
switch(token.value){
case SQLTokenizer.WHEN:
Expression condition = expression(cmd, 0);
if(input != null){
// simple CASE Syntax
condition = new ExpressionArithmetic( input, condition, ExpressionArithmetic.EQUALS);
}
nextToken(MISSING_THEN);
Expression result = expression(cmd, 0);
expr.addCase(condition, result);
break;
case SQLTokenizer.ELSE:
expr.setElseResult(expression(cmd, 0));
break;
case SQLTokenizer.END:
expr.setEnd();
return expr;
default:
throw new Error();
}
token = nextToken(MISSING_WHEN_ELSE_END);
}
}
/**
* Parse any functions. The left parenthesis is already consumed from token list.
* @param token the SQLToken of the function
* @param isEscape If the function is a FN ESCAPE sequence
*/
private Expression function( Command cmd, SQLToken token, boolean isEscape ) throws SQLException{
Expression expr;
switch(token.value){
case SQLTokenizer.CONVERT:{
Column col;
Expression style = null;
if(isEscape){
expr = expression( cmd, 0);
nextToken(MISSING_COMMA);
col = datatype(isEscape);
}else{
col = datatype(isEscape);
nextToken(MISSING_COMMA);
expr = expression( cmd, 0);
token = nextToken(MISSING_COMMA_PARENTHESIS);
if(token.value == SQLTokenizer.COMMA){
style = expression( cmd, 0);
}else
previousToken();
}
nextToken(MISSING_PARENTHESIS_R);
return new ExpressionFunctionConvert( col, expr, style );
}
case SQLTokenizer.CAST:
expr = expression( cmd, 0);
nextToken(MISSING_AS);
Column col = datatype(false);
nextToken(MISSING_PARENTHESIS_R);
return new ExpressionFunctionConvert( col, expr, null );
case SQLTokenizer.TIMESTAMPDIFF:
token = nextToken(MISSING_INTERVALS);
nextToken(MISSING_COMMA);
expr = expression( cmd, 0);
nextToken(MISSING_COMMA);
expr = new ExpressionFunctionTimestampDiff( token.value, expr, expression( cmd, 0));
nextToken(MISSING_PARENTHESIS_R);
return expr;
case SQLTokenizer.TIMESTAMPADD:
token = nextToken(MISSING_INTERVALS);
nextToken(MISSING_COMMA);
expr = expression( cmd, 0);
nextToken(MISSING_COMMA);
expr = new ExpressionFunctionTimestampAdd( token.value, expr, expression( cmd, 0));
nextToken(MISSING_PARENTHESIS_R);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -