From bfaf10f6ece1ba903d11b5d419f49981f4f5c278 Mon Sep 17 00:00:00 2001 From: hantmac Date: Thu, 27 Nov 2025 21:38:41 +0800 Subject: [PATCH 1/4] feat: support batch replace into --- batch.go | 2 +- tests/main_test.go | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/batch.go b/batch.go index b9582ea..1da95be 100644 --- a/batch.go +++ b/batch.go @@ -16,7 +16,7 @@ import ( ) // \x60 represents a backtick -var httpInsertRe = regexp.MustCompile(`(?i)^INSERT INTO\s+\x60?([\w.^\(]+)\x60?\s*(\([^\)]*\))? VALUES`) +var httpInsertRe = regexp.MustCompile(`(?i)^(?:INSERT|REPLACE) INTO\s+\x60?([\w.^\(]+)\x60?\s*(\([^\)]*\))?(?:\s+ON\s*\([^\)]*\))?\s+VALUES`) type Batch interface { AppendToFile(v []driver.Value) error diff --git a/tests/main_test.go b/tests/main_test.go index 0dd794a..5dff55a 100644 --- a/tests/main_test.go +++ b/tests/main_test.go @@ -81,10 +81,11 @@ func TestDatabendSuite(t *testing.T) { type DatabendTestSuite struct { suite.Suite - cfg *dc.Config - table string - table2 string - r *require.Assertions + cfg *dc.Config + table string + table2 string + replaceTable string + r *require.Assertions } func (s *DatabendTestSuite) SetupSuite() { @@ -124,6 +125,8 @@ func (s *DatabendTestSuite) SetupTest() { s.r.NoError(err) _, err = db.Exec(fmt.Sprintf(createTable2, s.table2)) s.r.NoError(err) + _, err = db.Exec(fmt.Sprintf(createTable, s.replaceTable)) + s.r.NoError(err) } func (s *DatabendTestSuite) TearDownTest() { @@ -137,6 +140,8 @@ func (s *DatabendTestSuite) TearDownTest() { s.r.NoError(err) _, err = db.Exec(fmt.Sprintf("DROP TABLE %s", s.table2)) s.r.NoError(err) + _, err = db.Exec(fmt.Sprintf("DROP TABLE %s", s.replaceTable)) + s.r.NoError(err) } func (s *DatabendTestSuite) TestVersion() { @@ -253,6 +258,36 @@ func (s *DatabendTestSuite) TestBatchInsert() { r.NoError(err) } +func (s *DatabendTestSuite) TestBatchReplaceInto() { + r := require.New(s.T()) + db := sql.OpenDB(s.cfg) + defer db.Close() + + scope, err := db.Begin() + r.NoError(err) + + batch, err := scope.Prepare(fmt.Sprintf("REPLACE INTO %s ON(i64) VALUES", s.replaceTable)) + r.NoError(err) + + for i := 0; i < 10; i++ { + _, err = batch.Exec( + "1234", + "2345", + "3.1415", + "test", + "test2", + "[4, 5, 6]", + "[1, 2, 3]", + "2021-01-01", + "2021-01-01 00:00:00", + ) + r.NoError(err) + } + + err = scope.Commit() + r.NoError(err) +} + func (s *DatabendTestSuite) TestDDL() { ddls := []string{ `DROP TABLE IF EXISTS data`, From 5c10dcf78549a7dd69d5d34ceba4226437b63f7c Mon Sep 17 00:00:00 2001 From: hantmac Date: Thu, 27 Nov 2025 21:42:19 +0800 Subject: [PATCH 2/4] fix --- tests/main_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/main_test.go b/tests/main_test.go index 5dff55a..130838a 100644 --- a/tests/main_test.go +++ b/tests/main_test.go @@ -120,6 +120,7 @@ func (s *DatabendTestSuite) SetupTest() { s.table = fmt.Sprintf("test_%s_%d", tName, time.Now().Unix()) // t.Logf("setup test with table %s", s.table) s.table2 = fmt.Sprintf("test_%s_%d", tName, time.Now().Unix()+1) + s.replaceTable = fmt.Sprintf("test_%s_%d", tName, time.Now().Unix()+2) _, err := db.Exec(fmt.Sprintf(createTable, s.table)) s.r.NoError(err) From 49500496f532d456faff1216cd619135ef136ef6 Mon Sep 17 00:00:00 2001 From: hantmac Date: Thu, 27 Nov 2025 21:46:12 +0800 Subject: [PATCH 3/4] fix tests --- tests/main_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/main_test.go b/tests/main_test.go index 130838a..df15098 100644 --- a/tests/main_test.go +++ b/tests/main_test.go @@ -272,7 +272,7 @@ func (s *DatabendTestSuite) TestBatchReplaceInto() { for i := 0; i < 10; i++ { _, err = batch.Exec( - "1234", + i, "2345", "3.1415", "test", From 01ee0dc59bd5adc49b11945c9ed85bd2ebbfd01f Mon Sep 17 00:00:00 2001 From: hantmac Date: Thu, 27 Nov 2025 21:52:59 +0800 Subject: [PATCH 4/4] fix re --- batch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/batch.go b/batch.go index 1da95be..a5a6eeb 100644 --- a/batch.go +++ b/batch.go @@ -16,7 +16,7 @@ import ( ) // \x60 represents a backtick -var httpInsertRe = regexp.MustCompile(`(?i)^(?:INSERT|REPLACE) INTO\s+\x60?([\w.^\(]+)\x60?\s*(\([^\)]*\))?(?:\s+ON\s*\([^\)]*\))?\s+VALUES`) +var httpInsertRe = regexp.MustCompile(`(?i)^\s*(?:INSERT|REPLACE) INTO\s+\x60?([\w.^\(]+)\x60?(?:\s*\([^\)]*\))?(?:\s+ON\s*\([^\)]*\))?(?:\s*\([^\)]*\))?\s+VALUES`) type Batch interface { AppendToFile(v []driver.Value) error