diff --git a/database/gdb/gdb_driver_oracle.go b/database/gdb/gdb_driver_oracle.go index 59b06bae0..85612c780 100644 --- a/database/gdb/gdb_driver_oracle.go +++ b/database/gdb/gdb_driver_oracle.go @@ -78,44 +78,45 @@ func (d *DriverOracle) HandleSqlBeforeCommit(link Link, sql string, args []inter // parseSql does some replacement of the sql before commits it to underlying driver, // for support of oracle server. func (d *DriverOracle) parseSql(sql string) string { - patten := `^\s*(?i)(SELECT)|(LIMIT\s*(\d+)\s*,\s*(\d+))` - if gregex.IsMatchString(patten, sql) == false { + var ( + patten = `^\s*(?i)(SELECT)|(LIMIT\s*(\d+)\s*,{0,1}\s*(\d*))` + allMatch, _ = gregex.MatchAllString(patten, sql) + ) + if len(allMatch) == 0 { return sql } - - res, err := gregex.MatchAllString(patten, sql) - if err != nil { - return "" - } - var ( index = 0 - keyword = strings.ToUpper(strings.TrimSpace(res[index][0])) + keyword = strings.ToUpper(strings.TrimSpace(allMatch[index][0])) ) index++ switch keyword { case "SELECT": - if len(res) < 2 || (strings.HasPrefix(res[index][0], "LIMIT") == false && - strings.HasPrefix(res[index][0], "limit") == false) { + if len(allMatch) < 2 || strings.HasPrefix(allMatch[index][0], "LIMIT") == false { break } if gregex.IsMatchString("((?i)SELECT)(.+)((?i)LIMIT)", sql) == false { break } queryExpr, _ := gregex.MatchString("((?i)SELECT)(.+)((?i)LIMIT)", sql) - if len(queryExpr) != 4 || strings.EqualFold(queryExpr[1], "SELECT") == false || + if len(queryExpr) != 4 || + strings.EqualFold(queryExpr[1], "SELECT") == false || strings.EqualFold(queryExpr[3], "LIMIT") == false { break } first, limit := 0, 0 - for i := 1; i < len(res[index]); i++ { - if len(strings.TrimSpace(res[index][i])) == 0 { + for i := 1; i < len(allMatch[index]); i++ { + if len(strings.TrimSpace(allMatch[index][i])) == 0 { continue } - if strings.HasPrefix(res[index][i], "LIMIT") || strings.HasPrefix(res[index][i], "limit") { - first, _ = strconv.Atoi(res[index][i+1]) - limit, _ = strconv.Atoi(res[index][i+2]) + if strings.HasPrefix(allMatch[index][i], "LIMIT") { + if allMatch[index][i+2] != "" { + first, _ = strconv.Atoi(allMatch[index][i+1]) + limit, _ = strconv.Atoi(allMatch[index][i+2]) + } else { + limit, _ = strconv.Atoi(allMatch[index][i+1]) + } break } } diff --git a/database/gdb/gdb_z_oracle_internal_test.go b/database/gdb/gdb_z_oracle_internal_test.go new file mode 100644 index 000000000..14a3903de --- /dev/null +++ b/database/gdb/gdb_z_oracle_internal_test.go @@ -0,0 +1,42 @@ +// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gdb + +import ( + "github.com/gogf/gf/test/gtest" + "testing" +) + +func Test_Oracle_parseSql(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + o := new(DriverOracle) + sql := `UPDATE user SET name='john'` + newSql := o.parseSql(sql) + t.Assert(newSql, sql) + }) + + gtest.C(t, func(t *gtest.T) { + o := new(DriverOracle) + sql := `SELECT * FROM user` + newSql := o.parseSql(sql) + t.Assert(newSql, sql) + }) + + gtest.C(t, func(t *gtest.T) { + o := new(DriverOracle) + sql := `SELECT * FROM user LIMIT 0, 10` + newSql := o.parseSql(sql) + t.Assert(newSql, `SELECT * FROM (SELECT GFORM.*, ROWNUM ROWNUM_ FROM (SELECT * FROM user ) GFORM WHERE ROWNUM <= 10) WHERE ROWNUM_ >= 0`) + }) + + gtest.C(t, func(t *gtest.T) { + o := new(DriverOracle) + sql := `SELECT * FROM user LIMIT 1` + newSql := o.parseSql(sql) + t.Assert(newSql, `SELECT * FROM (SELECT GFORM.*, ROWNUM ROWNUM_ FROM (SELECT * FROM user ) GFORM WHERE ROWNUM <= 1) WHERE ROWNUM_ >= 0`) + }) +}