protected void parseValueClauseNative()

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;
            }
        }
    }