diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1377554 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/parser.go b/parser.go index ea93260..82b5c35 100644 --- a/parser.go +++ b/parser.go @@ -936,6 +936,22 @@ func (p *Parser) ParseExpr() (expr Expr, err error) { func (p *Parser) parseOperand() (expr Expr, err error) { _, tok, lit := p.lex() switch tok { + case VALUES: + _, tok, lit = p.lex() + var expr Expr + if tok == LP { + p.unlex() + var err error + expr, err = p.parseParenExpr() + if err != nil { + return nil, err + } + expr = expr.(*ParenExpr).X + } else { + return nil, p.errorExpected(p.pos, p.tok, "left paren") + } + return &Call{Name: &Ident{Name: "VALUES"}, Args: []Expr{expr}}, nil + case IDENT, QIDENT: ident := identByNameAndTok(lit, tok) if p.peek() == DOT { diff --git a/parser_test.go b/parser_test.go index 14c7290..42e27fc 100644 --- a/parser_test.go +++ b/parser_test.go @@ -1015,3 +1015,31 @@ func AssertParseExprError(tb testing.TB, s string, want string) { tb.Fatalf("ParseExpr()=%q, want %q", err, want) } } + +func TestSql_support_values_call(t *testing.T) { + sql := "INSERT INTO `daily_asset` (`trade_date`,`fund_account`,`client_id`,`day_income`,`hold_income`,`acc_income`,`day_income_ratio`,`acc_income_sw_ratio`,`acc_income_nav_ratio`,`market_value`,`fund_asset`,`total_asset`,`sw_total_net`,`bank_transfer_in`,`bank_transfer_out`,`acc_bank_transfer_in`,`acc_bank_transfer_out`,`net_in_balance`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE `fund_asset`=VALUES(`fund_asset`),`hold_income`=VALUES(`hold_income`),`market_value`=VALUES(`market_value`),`total_asset`=VALUES(`total_asset`),`bank_transfer_in`=VALUES(`bank_transfer_in`),`bank_transfer_out`=VALUES(`bank_transfer_out`),`net_in_balance`=VALUES(`net_in_balance`)" + stmt, err := sqlparser.NewParser(strings.NewReader(sql)).ParseStatement() + if err != nil { + t.Fatal(err) + } + + insert := stmt.(*sqlparser.InsertStatement) + result := insert.String() + expected := "INSERT INTO `daily_asset` (`trade_date`, `fund_account`, `client_id`, `day_income`, `hold_income`, `acc_income`, `day_income_ratio`, `acc_income_sw_ratio`, `acc_income_nav_ratio`, `market_value`, `fund_asset`, `total_asset`, `sw_total_net`, `bank_transfer_in`, `bank_transfer_out`, `acc_bank_transfer_in`, `acc_bank_transfer_out`, `net_in_balance`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE `fund_asset` = VALUES(`fund_asset`), `hold_income` = VALUES(`hold_income`), `market_value` = VALUES(`market_value`), `total_asset` = VALUES(`total_asset`), `bank_transfer_in` = VALUES(`bank_transfer_in`), `bank_transfer_out` = VALUES(`bank_transfer_out`), `net_in_balance` = VALUES(`net_in_balance`)" + if result != expected { + t.Fatal("sql not equal") + } +} + +func TestSql_support_values_error(t *testing.T) { + sql := "INSERT INTO `daily_asset` (`trade_date`,`fund_account`,`client_id`,`day_income`,`hold_income`,`acc_income`,`day_income_ratio`,`acc_income_sw_ratio`,`acc_income_nav_ratio`,`market_value`,`fund_asset`,`total_asset`,`sw_total_net`,`bank_transfer_in`,`bank_transfer_out`,`acc_bank_transfer_in`,`acc_bank_transfer_out`,`net_in_balance`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE `fund_asset`=VALUES `fund_asset`" + _, err := sqlparser.NewParser(strings.NewReader(sql)).ParseStatement() + if err == nil { + t.Fatal(err) + } + msg := err.Error() + expected := "1:422: expected left paren, found `fund_asset`" + if msg != expected { + t.Fatal("err msg not equal") + } +}