in core/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java [5982:6311]
protected void parseValueClauseNative(
List<SQLInsertStatement.ValuesClause> valueClauseList,
List<SQLColumnDefinition> columnDefinitionList,
int columnSize,
SQLObject parent
) {
final TimeZone timeZone = lexer.getTimeZone();
SQLInsertStatement.ValuesClause values;
for (int i = 0; ; ++i) {
int startPos = lexer.pos - 1;
if (lexer.token != Token.LPAREN) {
throw new ParserException("syntax error, expect ')', " + lexer.info());
}
// lexer.nextTokenValue();
if (lexer.ch == '\'') { // for performance
lexer.bufPos = 0;
lexer.scanString();
} else if (lexer.ch == '0') {
lexer.bufPos = 0;
if (lexer.charAt(lexer.pos + 1) == 'x') {
lexer.scanChar();
lexer.scanChar();
lexer.scanHexaDecimal();
} else {
lexer.scanNumber();
}
} else if (lexer.ch > '0' && lexer.ch <= '9') {
lexer.bufPos = 0;
lexer.scanNumber();
} else if (lexer.ch == '-' && lexer.charAt(lexer.pos + 1) != '-') {
lexer.scanNumber();
} else {
lexer.nextTokenValue();
}
if (lexer.token() != Token.RPAREN) {
List valueExprList;
if (columnSize > 0) {
valueExprList = new ArrayList(columnSize);
} else {
valueExprList = new ArrayList();
}
values = new SQLInsertStatement.ValuesClause(valueExprList, parent);
int funcExecCount = 0;
for (int j = 0; ; ++j) {
SQLExpr expr = null;
Object value = null;
SQLColumnDefinition columnDefinition = null;
if (columnDefinitionList != null && j < columnDefinitionList.size()) {
columnDefinition = columnDefinitionList.get(j);
}
SQLDataType dataType = null;
if (columnDefinition != null) {
dataType = columnDefinition.getDataType();
}
switch (lexer.token) {
case LITERAL_INT: {
Number integerValue = lexer.integerValue();
if (lexer.ch == ',') {
lexer.ch = lexer.charAt(++lexer.pos);
lexer.token = COMMA;
} else {
lexer.nextTokenCommaValue();
}
if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) {
expr = new SQLIntegerExpr(integerValue, values);
expr = this.exprParser.exprRest(expr);
expr.setParent(values);
} else {
value = integerValue;
}
break;
}
case LITERAL_CHARS: {
String strVal = lexer.stringVal();
if (lexer.ch == ',') {
lexer.ch = lexer.charAt(++lexer.pos);
lexer.token = COMMA;
} else {
lexer.nextTokenCommaValue();
}
if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) {
expr = new SQLCharExpr(strVal, values);
expr = this.exprParser.exprRest(expr);
expr.setParent(values);
} else {
value = strVal;
}
break;
}
case LITERAL_NCHARS: {
String strVal = lexer.stringVal();
if (lexer.ch == ',') {
lexer.ch = lexer.charAt(++lexer.pos);
lexer.token = COMMA;
} else {
lexer.nextTokenCommaValue();
}
if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) {
expr = new SQLNCharExpr(strVal, values);
expr = this.exprParser.exprRest(expr);
expr.setParent(values);
} else {
value = strVal;
}
break;
}
case LITERAL_FLOAT: {
BigDecimal number = lexer.decimalValue();
if (dataType != null
&& dataType.nameHashCode64() == Constants.DECIMAL) {
int precision = 0, scale = 0;
List<SQLExpr> arguments = dataType.getArguments();
if (arguments.size() > 0) {
SQLExpr arg0 = arguments.get(0);
if (arg0 instanceof SQLIntegerExpr) {
precision = ((SQLIntegerExpr) arg0).getNumber().intValue();
}
}
if (arguments.size() > 1) {
SQLExpr arg0 = arguments.get(1);
if (arg0 instanceof SQLIntegerExpr) {
scale = ((SQLIntegerExpr) arg0).getNumber().intValue();
}
}
if (number instanceof BigDecimal) {
number = MySqlUtils.decimal(number, precision, scale);
}
}
if (lexer.ch == ',') {
lexer.ch = lexer.charAt(++lexer.pos);
lexer.token = COMMA;
} else {
lexer.nextTokenCommaValue();
}
if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) {
expr = new SQLDecimalExpr(number);
expr = this.exprParser.exprRest(expr);
expr.setParent(values);
} else {
value = number;
}
break;
}
case NULL: {
lexer.nextTokenCommaValue();
if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) {
expr = new SQLNullExpr(parent);
expr = this.exprParser.exprRest(expr);
expr.setParent(values);
} else {
value = null;
}
break;
}
case IDENTIFIER: {
long hash = lexer.hashLCase();
if (hash == Constants.DATE) {
lexer.nextTokenValue();
String strVal = lexer.stringVal();
value = java.sql.Date.valueOf(strVal);
lexer.nextTokenComma();
} else if (hash == Constants.TIMESTAMP && timeZone != null) {
lexer.nextTokenValue();
String strVal = lexer.stringVal();
value = new java.sql.Timestamp(MySqlUtils.parseDate(strVal, timeZone)
.getTime());
lexer.nextTokenComma();
} else if (hash == Constants.CURDATE
|| hash == Constants.CUR_DATE
|| hash == Constants.CURRENT_DATE) {
lexer.nextTokenValue();
if (lexer.token == Token.LPAREN) {
lexer.nextToken();
accept(Token.RPAREN);
}
if (now == null) {
now = new java.sql.Timestamp(System.currentTimeMillis());
}
if (currentDate == null) {
currentDate = new java.sql.Date(now.getTime());
}
value = currentDate;
funcExecCount++;
} else if ((hash == Constants.SYSDATE
|| hash == Constants.NOW
|| hash == Constants.CURRENT_TIMESTAMP)
&& timeZone != null) {
lexer.nextTokenValue();
if (lexer.token == Token.LPAREN) {
lexer.nextToken();
accept(Token.RPAREN);
}
if (now == null) {
now = new java.sql.Timestamp(System.currentTimeMillis());
}
value = now;
funcExecCount++;
} else if (hash == Constants.UUID) {
lexer.nextTokenLParen();
accept(Token.LPAREN);
accept(Token.RPAREN);
value = UUID.randomUUID().toString();
funcExecCount++;
} else {
value = null;
Lexer.SavePoint mark = lexer.mark();
expr = exprParser.expr();
if (expr instanceof SQLName) {
lexer.reset(mark);
lexer.info();
throw new ParserException("insert value error, token " + lexer.stringVal() + ", line " + lexer.posLine + ", column " + lexer.posColumn, lexer.posLine, lexer.posColumn);
}
expr.setParent(values);
}
break;
}
default:
value = null;
expr = exprParser.expr();
expr.setParent(values);
break;
}
if (expr != null) {
expr.setParent(values);
value = expr;
}
if (lexer.token == Token.COMMA) {
valueExprList.add(value);
if (lexer.ch == '\'') { // for performance
lexer.bufPos = 0;
lexer.scanString();
} else if (lexer.ch == '0') {
lexer.bufPos = 0;
if (lexer.charAt(lexer.pos + 1) == 'x') {
lexer.scanChar();
lexer.scanChar();
lexer.scanHexaDecimal();
} else {
lexer.scanNumber();
}
} else if (lexer.ch > '0' && lexer.ch <= '9') {
lexer.bufPos = 0;
lexer.scanNumber();
} else if (lexer.ch == '-' && lexer.charAt(lexer.pos + 1) != '-') {
lexer.bufPos = 0;
lexer.scanNumber();
} else {
lexer.nextTokenValue();
}
continue;
} else if (lexer.token == Token.RPAREN) {
valueExprList.add(value);
break;
} else {
expr = this.exprParser.primaryRest(expr);
if (lexer.token != Token.COMMA && lexer.token() != Token.RPAREN) {
expr = this.exprParser.exprRest(expr);
}
expr.setParent(values);
valueExprList.add(expr);
if (lexer.token == Token.COMMA) {
lexer.nextTokenValue();
continue;
} else {
break;
}
}
}
if (funcExecCount == 0 && lexer.isEnabled(SQLParserFeature.KeepInsertValueClauseOriginalString)) {
int endPos = lexer.pos();
String orginalString = lexer.subString(startPos, endPos - startPos);
values.setOriginalString(orginalString);
}
} else {
values = new SQLInsertStatement.ValuesClause(new ArrayList<SQLExpr>(0));
}
valueClauseList.add(values);
if (lexer.token != Token.RPAREN) {
throw new ParserException("syntax error. " + lexer.info());
}
if (!parseCompleteValues && valueClauseList.size() >= parseValuesSize) {
lexer.skipToEOF();
break;
}
lexer.nextTokenComma();
while (lexer.token == Token.HINT) {
this.exprParser.parseHints();
}
if (lexer.token == Token.COMMA) {
lexer.nextTokenLParen();
if (values != null) {
columnSize = values.getValues().size();
}
continue;
} else {
break;
}
}
}