Skip to content

Commit 2b9cd53

Browse files
authored
Merge pull request #1 from wix-playground/where-clause
online schema changes with deletion. architecture as detailed explained here: https://kb.wixpress.com/x/8pocBQ Where clause condition will always receive the default 1=1. in case we would like to delete table data we will use the where clause as in a "select" meaning we will put the data we want to save in the where clause. to include values on the where clause - use the condition as it is. for exclude values please put "not" before. Please note : Where clause condition will be enforced only from the source table and not from the binlog. meaning if I put a where clause of id < 100, and id # 2 was updated \ inserted, it will be in the new table because this DML will be taken from the binlog. this is a feature since this is newly update\insert otherwise it should be inserted into the binlogs as a deleted row. If you are using one filter operation with in , please don't put more than 5 values. otherwise please use the sub-select option. For hash \ string it is better to use the sub-select option, avoiding string manipulation issues in the middle (Jenkins, ansible, Casper). Where clause can not be edited in the middle of ghost run.
2 parents 8d99e46 + 6de0e3e commit 2b9cd53

File tree

10 files changed

+142
-54
lines changed

10 files changed

+142
-54
lines changed

.github/CODEOWNERS

Lines changed: 0 additions & 1 deletion
This file was deleted.

.github/ISSUE_TEMPLATE.md

Lines changed: 0 additions & 13 deletions
This file was deleted.

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 0 additions & 19 deletions
This file was deleted.

build.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
#
33
#
44

5-
RELEASE_VERSION=
6-
buildpath=
5+
RELEASE_VERSION=2
6+
buildpath=/tmp
77

88
function setuptree() {
99
b=$( mktemp -d $buildpath/gh-ostXXXXXX ) || return 1

go/base/context.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ type MigrationContext struct {
123123
MaxLagMillisecondsThrottleThreshold int64
124124
throttleControlReplicaKeys *mysql.InstanceKeyMap
125125
ThrottleFlagFile string
126+
copyWhereClause string
126127
ThrottleAdditionalFlagFile string
127128
throttleQuery string
128129
throttleHTTP string
@@ -724,6 +725,19 @@ func (this *MigrationContext) GetCriticalLoad() LoadMap {
724725
return this.criticalLoad.Duplicate()
725726
}
726727

728+
func (this *MigrationContext) GetWhereClause() string {
729+
this.throttleMutex.Lock()
730+
defer this.throttleMutex.Unlock()
731+
732+
return this.copyWhereClause
733+
}
734+
735+
func (this *MigrationContext) SetWhereClause(WhereClause string) {
736+
this.throttleMutex.Lock()
737+
defer this.throttleMutex.Unlock()
738+
this.copyWhereClause = WhereClause
739+
}
740+
727741
func (this *MigrationContext) GetNiceRatio() float64 {
728742
this.throttleMutex.Lock()
729743
defer this.throttleMutex.Unlock()

go/cmd/gh-ost/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ func main() {
116116
throttleControlReplicas := flag.String("throttle-control-replicas", "", "List of replicas on which to check for lag; comma delimited. Example: myhost1.com:3306,myhost2.com,myhost3.com:3307")
117117
throttleQuery := flag.String("throttle-query", "", "when given, issued (every second) to check if operation should throttle. Expecting to return zero for no-throttle, >0 for throttle. Query is issued on the migrated server. Make sure this query is lightweight")
118118
throttleHTTP := flag.String("throttle-http", "", "when given, gh-ost checks given URL via HEAD request; any response code other than 200 (OK) causes throttling; make sure it has low latency response")
119+
copyWhereClause := flag.String("where-clause", "1=1", "added where clause for the insert query, filtering table rows")
119120
flag.Int64Var(&migrationContext.ThrottleHTTPIntervalMillis, "throttle-http-interval-millis", 100, "Number of milliseconds to wait before triggering another HTTP throttle check")
120121
flag.Int64Var(&migrationContext.ThrottleHTTPTimeoutMillis, "throttle-http-timeout-millis", 1000, "Number of milliseconds to use as an HTTP throttle check timeout")
121122
ignoreHTTPErrors := flag.Bool("ignore-http-errors", false, "ignore HTTP connection errors during throttle check")
@@ -304,6 +305,7 @@ func main() {
304305
migrationContext.SetThrottleHTTP(*throttleHTTP)
305306
migrationContext.SetIgnoreHTTPErrors(*ignoreHTTPErrors)
306307
migrationContext.SetDefaultNumRetries(*defaultRetries)
308+
migrationContext.SetWhereClause(*copyWhereClause)
307309
migrationContext.ApplyCredentials()
308310
if err := migrationContext.SetupTLS(); err != nil {
309311
migrationContext.Log.Fatale(err)

go/logic/applier.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strings"
1212
"sync/atomic"
1313
"time"
14+
"context"
1415

1516
"github.com/github/gh-ost/go/base"
1617
"github.com/github/gh-ost/go/binlog"
@@ -628,13 +629,20 @@ func (this *Applier) ApplyIterationInsertQuery() (chunkSize int64, rowsAffected
628629
this.migrationContext.MigrationIterationRangeMaxValues.AbstractValues(),
629630
this.migrationContext.GetIteration() == 0,
630631
this.migrationContext.IsTransactionalTable(),
632+
this.migrationContext.GetWhereClause(),
631633
)
632634
if err != nil {
633635
return chunkSize, rowsAffected, duration, err
634636
}
635637

636638
sqlResult, err := func() (gosql.Result, error) {
637-
tx, err := this.db.Begin()
639+
var conn *gosql.Conn
640+
conn, err = this.db.Conn(context.Background())
641+
if (conn == nil || err != nil) {
642+
fmt.Sprintf("failed to get connection")
643+
return nil, err
644+
}
645+
tx, err := conn.BeginTx(context.Background(), nil)
638646
if err != nil {
639647
return nil, err
640648
}
@@ -643,16 +651,17 @@ func (this *Applier) ApplyIterationInsertQuery() (chunkSize int64, rowsAffected
643651
sessionQuery := fmt.Sprintf(`SET SESSION time_zone = '%s'`, this.migrationContext.ApplierTimeZone)
644652
sessionQuery = fmt.Sprintf("%s, %s", sessionQuery, this.generateSqlModeQuery())
645653

646-
if _, err := tx.Exec(sessionQuery); err != nil {
654+
if _, err := tx.ExecContext(context.Background(), sessionQuery); err != nil {
647655
return nil, err
648656
}
649-
result, err := tx.Exec(query, explodedArgs...)
657+
result, err := tx.ExecContext(context.Background(), query, explodedArgs...)
650658
if err != nil {
651659
return nil, err
652660
}
653661
if err := tx.Commit(); err != nil {
654662
return nil, err
655663
}
664+
conn.Close()
656665
return result, nil
657666
}()
658667

go/logic/migrator.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,13 +838,14 @@ func (this *Migrator) printMigrationStatusHint(writers ...io.Writer) {
838838
)
839839
maxLoad := this.migrationContext.GetMaxLoad()
840840
criticalLoad := this.migrationContext.GetCriticalLoad()
841-
fmt.Fprintf(w, "# chunk-size: %+v; max-lag-millis: %+vms; dml-batch-size: %+v; max-load: %s; critical-load: %s; nice-ratio: %f\n",
841+
fmt.Fprintf(w, "# chunk-size: %+v; max-lag-millis: %+vms; dml-batch-size: %+v; max-load: %s; critical-load: %s; nice-ratio: %f; where-clause: %s\n",
842842
atomic.LoadInt64(&this.migrationContext.ChunkSize),
843843
atomic.LoadInt64(&this.migrationContext.MaxLagMillisecondsThrottleThreshold),
844844
atomic.LoadInt64(&this.migrationContext.DMLBatchSize),
845845
maxLoad.String(),
846846
criticalLoad.String(),
847847
this.migrationContext.GetNiceRatio(),
848+
this.migrationContext.GetWhereClause(),
848849
)
849850
if this.migrationContext.ThrottleFlagFile != "" {
850851
setIndicator := ""

go/sql/builder.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ func BuildRangePreparedComparison(columns *ColumnList, args []interface{}, compa
182182
return BuildRangeComparison(columns.Names(), values, args, comparisonSign)
183183
}
184184

185-
func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, mappedSharedColumns []string, uniqueKey string, uniqueKeyColumns *ColumnList, rangeStartValues, rangeEndValues []string, rangeStartArgs, rangeEndArgs []interface{}, includeRangeStartValues bool, transactionalTable bool) (result string, explodedArgs []interface{}, err error) {
185+
func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, mappedSharedColumns []string, uniqueKey string, uniqueKeyColumns *ColumnList, rangeStartValues, rangeEndValues []string, rangeStartArgs, rangeEndArgs []interface{}, includeRangeStartValues bool, transactionalTable bool, whereClause string) (result string, explodedArgs []interface{}, err error) {
186186
if len(sharedColumns) == 0 {
187187
return "", explodedArgs, fmt.Errorf("Got 0 shared columns in BuildRangeInsertQuery")
188188
}
@@ -232,19 +232,19 @@ func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName strin
232232
%s.%s
233233
force index (%s)
234234
where
235-
(%s and %s)
235+
(%s and %s and %s)
236236
%s
237237
)`,
238238
databaseName, originalTableName, databaseName, ghostTableName, mappedSharedColumnsListing,
239239
sharedColumnsListing, databaseName, originalTableName, uniqueKey,
240-
rangeStartComparison, rangeEndComparison, transactionalClause)
240+
rangeStartComparison, rangeEndComparison, whereClause, transactionalClause)
241241
return result, explodedArgs, nil
242242
}
243243

244-
func BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, mappedSharedColumns []string, uniqueKey string, uniqueKeyColumns *ColumnList, rangeStartArgs, rangeEndArgs []interface{}, includeRangeStartValues bool, transactionalTable bool) (result string, explodedArgs []interface{}, err error) {
244+
func BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, mappedSharedColumns []string, uniqueKey string, uniqueKeyColumns *ColumnList, rangeStartArgs, rangeEndArgs []interface{}, includeRangeStartValues bool, transactionalTable bool, whereClause string) (result string, explodedArgs []interface{}, err error) {
245245
rangeStartValues := buildColumnsPreparedValues(uniqueKeyColumns)
246246
rangeEndValues := buildColumnsPreparedValues(uniqueKeyColumns)
247-
return BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, mappedSharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, includeRangeStartValues, transactionalTable)
247+
return BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, mappedSharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, includeRangeStartValues, transactionalTable, whereClause)
248248
}
249249

250250
func BuildUniqueKeyRangeEndPreparedQueryViaOffset(databaseName, tableName string, uniqueKeyColumns *ColumnList, rangeStartArgs, rangeEndArgs []interface{}, chunkSize int64, includeRangeStartValues bool, hint string) (result string, explodedArgs []interface{}, err error) {

go/sql/builder_test.go

Lines changed: 105 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ func TestBuildRangeInsertQuery(t *testing.T) {
163163
databaseName := "mydb"
164164
originalTableName := "tbl"
165165
ghostTableName := "ghost"
166+
whereClause := "1=1"
166167
sharedColumns := []string{"id", "name", "position"}
167168
{
168169
uniqueKey := "PRIMARY"
@@ -172,7 +173,7 @@ func TestBuildRangeInsertQuery(t *testing.T) {
172173
rangeStartArgs := []interface{}{3}
173174
rangeEndArgs := []interface{}{103}
174175

175-
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false)
176+
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false, whereClause)
176177
test.S(t).ExpectNil(err)
177178
expected := `
178179
insert /* gh-ost mydb.tbl */ ignore
@@ -186,7 +187,7 @@ func TestBuildRangeInsertQuery(t *testing.T) {
186187
force index (PRIMARY)
187188
where
188189
(((id > @v1s) or ((id = @v1s)))
189-
and ((id < @v1e) or ((id = @v1e))))
190+
and ((id < @v1e) or ((id = @v1e))) and 1=1)
190191
)`
191192
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
192193
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 103, 103}))
@@ -199,7 +200,7 @@ func TestBuildRangeInsertQuery(t *testing.T) {
199200
rangeStartArgs := []interface{}{3, 17}
200201
rangeEndArgs := []interface{}{103, 117}
201202

202-
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false)
203+
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false, whereClause)
203204
test.S(t).ExpectNil(err)
204205
expected := `
205206
insert /* gh-ost mydb.tbl */ ignore
@@ -219,17 +220,110 @@ func TestBuildRangeInsertQuery(t *testing.T) {
219220
and ((name < @v1e)
220221
or (((name = @v1e))
221222
AND (position < @v2e))
222-
or ((name = @v1e) and (position = @v2e))))
223+
or ((name = @v1e) and (position = @v2e))) and 1=1)
223224
)`
224225
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
225226
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 103, 103, 117, 103, 117}))
226227
}
227228
}
228229

230+
231+
func TestBuildRangeInsertQueryWhereClauseFiltering(t *testing.T) {
232+
databaseName := "mydb"
233+
originalTableName := "tbl"
234+
ghostTableName := "ghost"
235+
sharedColumns := []string{"id", "name", "position"}
236+
{
237+
uniqueKey := "PRIMARY"
238+
uniqueKeyColumns := NewColumnList([]string{"id"})
239+
rangeStartValues := []string{"@v1s"}
240+
rangeEndValues := []string{"@v1e"}
241+
rangeStartArgs := []interface{}{3}
242+
rangeEndArgs := []interface{}{103}
243+
whereClause := "id = 1"
244+
245+
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false, whereClause)
246+
test.S(t).ExpectNil(err)
247+
expected := `
248+
insert /* gh-ost mydb.tbl */ ignore
249+
into
250+
mydb.ghost
251+
(id, name, position)
252+
(
253+
select id, name, position
254+
from
255+
mydb.tbl
256+
force index (PRIMARY)
257+
where
258+
(((id > @v1s) or ((id = @v1s)))
259+
and ((id < @v1e) or ((id = @v1e))) and id = 1)
260+
)`
261+
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
262+
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 103, 103}))
263+
}
264+
{
265+
uniqueKey := "PRIMARY"
266+
uniqueKeyColumns := NewColumnList([]string{"id"})
267+
rangeStartValues := []string{"@v1s"}
268+
rangeEndValues := []string{"@v1e"}
269+
rangeStartArgs := []interface{}{3}
270+
rangeEndArgs := []interface{}{103}
271+
whereClause := "id not in (1,2,3)"
272+
273+
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false, whereClause)
274+
test.S(t).ExpectNil(err)
275+
expected := `
276+
insert /* gh-ost mydb.tbl */ ignore
277+
into
278+
mydb.ghost
279+
(id, name, position)
280+
(
281+
select id, name, position
282+
from
283+
mydb.tbl
284+
force index (PRIMARY)
285+
where
286+
(((id > @v1s) or ((id = @v1s)))
287+
and ((id < @v1e) or ((id = @v1e))) and id not in (1,2,3))
288+
)`
289+
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
290+
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 103, 103}))
291+
}
292+
{
293+
uniqueKey := "PRIMARY"
294+
uniqueKeyColumns := NewColumnList([]string{"id"})
295+
rangeStartValues := []string{"@v1s"}
296+
rangeEndValues := []string{"@v1e"}
297+
rangeStartArgs := []interface{}{3}
298+
rangeEndArgs := []interface{}{103}
299+
whereClause := "id in (select id from ids)"
300+
301+
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false, whereClause)
302+
test.S(t).ExpectNil(err)
303+
expected := `
304+
insert /* gh-ost mydb.tbl */ ignore
305+
into
306+
mydb.ghost
307+
(id, name, position)
308+
(
309+
select id, name, position
310+
from
311+
mydb.tbl
312+
force index (PRIMARY)
313+
where
314+
(((id > @v1s) or ((id = @v1s)))
315+
and ((id < @v1e) or ((id = @v1e))) and id in (select id from ids))
316+
)`
317+
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
318+
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 103, 103}))
319+
}
320+
}
321+
229322
func TestBuildRangeInsertQueryRenameMap(t *testing.T) {
230323
databaseName := "mydb"
231324
originalTableName := "tbl"
232325
ghostTableName := "ghost"
326+
whereClause := "1=1"
233327
sharedColumns := []string{"id", "name", "position"}
234328
mappedSharedColumns := []string{"id", "name", "location"}
235329
{
@@ -240,7 +334,7 @@ func TestBuildRangeInsertQueryRenameMap(t *testing.T) {
240334
rangeStartArgs := []interface{}{3}
241335
rangeEndArgs := []interface{}{103}
242336

243-
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, mappedSharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false)
337+
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, mappedSharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false, whereClause)
244338
test.S(t).ExpectNil(err)
245339
expected := `
246340
insert /* gh-ost mydb.tbl */ ignore
@@ -255,7 +349,7 @@ func TestBuildRangeInsertQueryRenameMap(t *testing.T) {
255349
where
256350
(((id > @v1s) or ((id = @v1s)))
257351
and
258-
((id < @v1e) or ((id = @v1e))))
352+
((id < @v1e) or ((id = @v1e))) and 1=1)
259353
)`
260354
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
261355
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 103, 103}))
@@ -268,7 +362,7 @@ func TestBuildRangeInsertQueryRenameMap(t *testing.T) {
268362
rangeStartArgs := []interface{}{3, 17}
269363
rangeEndArgs := []interface{}{103, 117}
270364

271-
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, mappedSharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false)
365+
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, mappedSharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false, whereClause)
272366
test.S(t).ExpectNil(err)
273367
expected := `
274368
insert /* gh-ost mydb.tbl */ ignore
@@ -284,7 +378,7 @@ func TestBuildRangeInsertQueryRenameMap(t *testing.T) {
284378
(((name > @v1s) or (((name = @v1s))
285379
AND (position > @v2s)) or ((name = @v1s) and (position = @v2s)))
286380
and ((name < @v1e) or (((name = @v1e)) AND (position < @v2e))
287-
or ((name = @v1e) and (position = @v2e))))
381+
or ((name = @v1e) and (position = @v2e))) and 1=1)
288382
)`
289383
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
290384
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 103, 103, 117, 103, 117}))
@@ -295,14 +389,15 @@ func TestBuildRangeInsertPreparedQuery(t *testing.T) {
295389
databaseName := "mydb"
296390
originalTableName := "tbl"
297391
ghostTableName := "ghost"
392+
whereClause := "1=1"
298393
sharedColumns := []string{"id", "name", "position"}
299394
{
300395
uniqueKey := "name_position_uidx"
301396
uniqueKeyColumns := NewColumnList([]string{"name", "position"})
302397
rangeStartArgs := []interface{}{3, 17}
303398
rangeEndArgs := []interface{}{103, 117}
304399

305-
query, explodedArgs, err := BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartArgs, rangeEndArgs, true, true)
400+
query, explodedArgs, err := BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartArgs, rangeEndArgs, true, true, whereClause)
306401
test.S(t).ExpectNil(err)
307402
expected := `
308403
insert /* gh-ost mydb.tbl */ ignore
@@ -314,7 +409,7 @@ func TestBuildRangeInsertPreparedQuery(t *testing.T) {
314409
from
315410
mydb.tbl
316411
force index (name_position_uidx)
317-
where (((name > ?) or (((name = ?)) AND (position > ?)) or ((name = ?) and (position = ?))) and ((name < ?) or (((name = ?)) AND (position < ?)) or ((name = ?) and (position = ?))))
412+
where (((name > ?) or (((name = ?)) AND (position > ?)) or ((name = ?) and (position = ?))) and ((name < ?) or (((name = ?)) AND (position < ?)) or ((name = ?) and (position = ?))) and 1=1)
318413
lock in share mode
319414
)`
320415
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))

0 commit comments

Comments
 (0)