From 1e1e42d1f1e20807b71d0217e6a7908afb4e309c Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Wed, 11 Jan 2023 22:54:06 +0100 Subject: [PATCH 1/7] Cleanup whitespace in SQL query text --- go/logic/applier.go | 54 +++++++-------- go/logic/inspect.go | 161 +++++++++++++++++++++----------------------- go/sql/builder.go | 105 ++++++++++++++--------------- 3 files changed, 155 insertions(+), 165 deletions(-) diff --git a/go/logic/applier.go b/go/logic/applier.go index ad6368e61..2f06d3252 100644 --- a/go/logic/applier.go +++ b/go/logic/applier.go @@ -109,7 +109,7 @@ func (this *Applier) InitDBConnections() (err error) { // validateAndReadTimeZone potentially reads server time-zone func (this *Applier) validateAndReadTimeZone() error { - query := `select @@global.time_zone` + query := `select /* gh-ost */ @@global.time_zone` if err := this.db.QueryRow(query).Scan(&this.migrationContext.ApplierTimeZone); err != nil { return err } @@ -393,14 +393,13 @@ func (this *Applier) WriteChangelog(hint, value string) (string, error) { explicitId = 3 } query := fmt.Sprintf(` - insert /* gh-ost */ into %s.%s - (id, hint, value) - values - (NULLIF(?, 0), ?, ?) - on duplicate key update - last_update=NOW(), - value=VALUES(value) - `, + insert /* gh-ost */ into %s.%s + (id, hint, value) + values + (NULLIF(?, 0), ?, ?) + on duplicate key update + last_update=NOW(), + value=VALUES(value)`, sql.EscapeName(this.migrationContext.DatabaseName), sql.EscapeName(this.migrationContext.GetChangelogTableName()), ) @@ -855,7 +854,7 @@ func (this *Applier) GetSessionLockName(sessionId int64) string { // ExpectUsedLock expects the special hint voluntary lock to exist on given session func (this *Applier) ExpectUsedLock(sessionId int64) error { var result int64 - query := `select is_used_lock(?)` + query := `select /* gh-ost */ is_used_lock(?)` lockName := this.GetSessionLockName(sessionId) this.migrationContext.Log.Infof("Checking session lock: %s", lockName) if err := this.db.QueryRow(query, lockName).Scan(&result); err != nil || result != sessionId { @@ -868,14 +867,13 @@ func (this *Applier) ExpectUsedLock(sessionId int64) error { func (this *Applier) ExpectProcess(sessionId int64, stateHint, infoHint string) error { found := false query := ` - select id + select /* gh-ost */ id from information_schema.processlist - where - id != connection_id() - and ? in (0, id) - and state like concat('%', ?, '%') - and info like concat('%', ?, '%') - ` + where + id != connection_id() + and ? in (0, id) + and state like concat('%', ?, '%') + and info like concat('%', ?, '%')` err := sqlutils.QueryRowsMap(this.db, query, func(m sqlutils.RowMap) error { found = true return nil @@ -913,10 +911,10 @@ func (this *Applier) CreateAtomicCutOverSentryTable() error { } tableName := this.migrationContext.GetOldTableName() - query := fmt.Sprintf(`create /* gh-ost */ table %s.%s ( + query := fmt.Sprintf(` + create /* gh-ost */ table %s.%s ( id int auto_increment primary key - ) engine=%s comment='%s' - `, + ) engine=%s comment='%s'`, sql.EscapeName(this.migrationContext.DatabaseName), sql.EscapeName(tableName), this.migrationContext.TableEngine, @@ -949,14 +947,14 @@ func (this *Applier) AtomicCutOverMagicLock(sessionIdChan chan int64, tableLocke }() var sessionId int64 - if err := tx.QueryRow(`select connection_id()`).Scan(&sessionId); err != nil { + if err := tx.QueryRow(`select /* gh-ost */ connection_id()`).Scan(&sessionId); err != nil { tableLocked <- err return err } sessionIdChan <- sessionId lockResult := 0 - query := `select get_lock(?, 0)` + query := `select /* gh-ost */ get_lock(?, 0)` lockName := this.GetSessionLockName(sessionId) this.migrationContext.Log.Infof("Grabbing voluntary lock: %s", lockName) if err := tx.QueryRow(query, lockName).Scan(&lockResult); err != nil || lockResult != 1 { @@ -967,7 +965,7 @@ func (this *Applier) AtomicCutOverMagicLock(sessionIdChan chan int64, tableLocke tableLockTimeoutSeconds := this.migrationContext.CutOverLockTimeoutSeconds * 2 this.migrationContext.Log.Infof("Setting LOCK timeout as %d seconds", tableLockTimeoutSeconds) - query = fmt.Sprintf(`set session lock_wait_timeout:=%d`, tableLockTimeoutSeconds) + query = fmt.Sprintf(`set /* gh-ost */ session lock_wait_timeout:=%d`, tableLockTimeoutSeconds) if _, err := tx.Exec(query); err != nil { tableLocked <- err return err @@ -1028,7 +1026,7 @@ func (this *Applier) AtomicCutOverMagicLock(sessionIdChan chan int64, tableLocke sql.EscapeName(this.migrationContext.DatabaseName), sql.EscapeName(this.migrationContext.GetOldTableName()), ) - query = `unlock tables` + query = `unlock /* gh-ost */ tables` if _, err := tx.Exec(query); err != nil { tableUnlocked <- err return this.migrationContext.Log.Errore(err) @@ -1050,13 +1048,13 @@ func (this *Applier) AtomicCutoverRename(sessionIdChan chan int64, tablesRenamed tablesRenamed <- fmt.Errorf("Unexpected error in AtomicCutoverRename(), injected to release blocking channel reads") }() var sessionId int64 - if err := tx.QueryRow(`select connection_id()`).Scan(&sessionId); err != nil { + if err := tx.QueryRow(`select /* gh-ost */ connection_id()`).Scan(&sessionId); err != nil { return err } sessionIdChan <- sessionId this.migrationContext.Log.Infof("Setting RENAME timeout as %d seconds", this.migrationContext.CutOverLockTimeoutSeconds) - query := fmt.Sprintf(`set session lock_wait_timeout:=%d`, this.migrationContext.CutOverLockTimeoutSeconds) + query := fmt.Sprintf(`set /* gh-ost */ session lock_wait_timeout:=%d`, this.migrationContext.CutOverLockTimeoutSeconds) if _, err := tx.Exec(query); err != nil { return err } @@ -1082,7 +1080,7 @@ func (this *Applier) AtomicCutoverRename(sessionIdChan chan int64, tablesRenamed } func (this *Applier) ShowStatusVariable(variableName string) (result int64, err error) { - query := fmt.Sprintf(`show global status like '%s'`, variableName) + query := fmt.Sprintf(`show /* gh-ost */ global status like '%s'`, variableName) if err := this.db.QueryRow(query).Scan(&variableName, &result); err != nil { return 0, err } @@ -1152,7 +1150,7 @@ func (this *Applier) ApplyDMLEventQueries(dmlEvents [](*binlog.BinlogDMLEvent)) return err } - sessionQuery := "SET SESSION time_zone = '+00:00'" + sessionQuery := "SET /* gh-ost */ SESSION time_zone = '+00:00'" sessionQuery = fmt.Sprintf("%s, %s", sessionQuery, this.generateSqlModeQuery()) if _, err := tx.Exec(sessionQuery); err != nil { diff --git a/go/logic/inspect.go b/go/logic/inspect.go index 3ece8ab26..069ca166b 100644 --- a/go/logic/inspect.go +++ b/go/logic/inspect.go @@ -338,7 +338,7 @@ func (this *Inspector) applyBinlogFormat() error { // validateBinlogs checks that binary log configuration is good to go func (this *Inspector) validateBinlogs() error { - query := `select @@global.log_bin, @@global.binlog_format` + query := `select /* gh-ost */ @@global.log_bin, @@global.binlog_format` var hasBinaryLogs bool if err := this.db.QueryRow(query).Scan(&hasBinaryLogs, &this.migrationContext.OriginalBinlogFormat); err != nil { return err @@ -364,7 +364,7 @@ func (this *Inspector) validateBinlogs() error { } this.migrationContext.Log.Infof("%s has %s binlog_format. I will change it to ROW, and will NOT change it back, even in the event of failure.", this.connectionConfig.Key.String(), this.migrationContext.OriginalBinlogFormat) } - query = `select @@global.binlog_row_image` + query = `select /* gh-ost */ @@global.binlog_row_image` if err := this.db.QueryRow(query).Scan(&this.migrationContext.OriginalBinlogRowImage); err != nil { return err } @@ -379,7 +379,7 @@ func (this *Inspector) validateBinlogs() error { // validateLogSlaveUpdates checks that binary log log_slave_updates is set. This test is not required when migrating on replica or when migrating directly on master func (this *Inspector) validateLogSlaveUpdates() error { - query := `select @@global.log_slave_updates` + query := `select /* gh-ost */ @@global.log_slave_updates` var logSlaveUpdates bool if err := this.db.QueryRow(query).Scan(&logSlaveUpdates); err != nil { return err @@ -441,16 +441,15 @@ func (this *Inspector) validateTableForeignKeys(allowChildForeignKeys bool) erro return nil } query := ` - SELECT + SELECT /* gh-ost */ SUM(REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_SCHEMA=? AND TABLE_NAME=?) as num_child_side_fk, SUM(REFERENCED_TABLE_NAME IS NOT NULL AND REFERENCED_TABLE_SCHEMA=? AND REFERENCED_TABLE_NAME=?) as num_parent_side_fk FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE - REFERENCED_TABLE_NAME IS NOT NULL - AND ((TABLE_SCHEMA=? AND TABLE_NAME=?) - OR (REFERENCED_TABLE_SCHEMA=? AND REFERENCED_TABLE_NAME=?) - ) - ` + REFERENCED_TABLE_NAME IS NOT NULL + AND ((TABLE_SCHEMA=? AND TABLE_NAME=?) + OR (REFERENCED_TABLE_SCHEMA=? AND REFERENCED_TABLE_NAME=?) + )` numParentForeignKeys := 0 numChildForeignKeys := 0 err := sqlutils.QueryRowsMap(this.db, query, func(m sqlutils.RowMap) error { @@ -487,12 +486,11 @@ func (this *Inspector) validateTableForeignKeys(allowChildForeignKeys bool) erro // validateTableTriggers makes sure no triggers exist on the migrated table func (this *Inspector) validateTableTriggers() error { query := ` - SELECT COUNT(*) AS num_triggers + SELECT /* gh-ost */ COUNT(*) AS num_triggers FROM INFORMATION_SCHEMA.TRIGGERS - WHERE - TRIGGER_SCHEMA=? - AND EVENT_OBJECT_TABLE=? - ` + WHERE + TRIGGER_SCHEMA=? + AND EVENT_OBJECT_TABLE=?` numTriggers := 0 err := sqlutils.QueryRowsMap(this.db, query, func(rowMap sqlutils.RowMap) error { numTriggers = rowMap.GetInt("num_triggers") @@ -577,14 +575,12 @@ func (this *Inspector) CountTableRows(ctx context.Context) error { // applyColumnTypes func (this *Inspector) applyColumnTypes(databaseName, tableName string, columnsLists ...*sql.ColumnList) error { query := ` - select - * - from - information_schema.columns - where - table_schema=? - and table_name=? - ` + select /* gh-ost */ * + from + information_schema.columns + where + table_schema=? + and table_name=?` err := sqlutils.QueryRowsMap(this.db, query, func(m sqlutils.RowMap) error { columnName := m.GetString("COLUMN_NAME") columnType := m.GetString("COLUMN_TYPE") @@ -633,14 +629,13 @@ func (this *Inspector) applyColumnTypes(databaseName, tableName string, columnsL // getAutoIncrementValue get's the original table's AUTO_INCREMENT value, if exists (0 value if not exists) func (this *Inspector) getAutoIncrementValue(tableName string) (autoIncrement uint64, err error) { query := ` - SELECT + SELECT /* gh-ost */ AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLES.TABLE_SCHEMA = ? AND TABLES.TABLE_NAME = ? - AND AUTO_INCREMENT IS NOT NULL - ` + AND AUTO_INCREMENT IS NOT NULL` err = sqlutils.QueryRowsMap(this.db, query, func(m sqlutils.RowMap) error { autoIncrement = m.GetUint64("AUTO_INCREMENT") return nil @@ -652,62 +647,61 @@ func (this *Inspector) getAutoIncrementValue(tableName string) (autoIncrement ui // candidate for chunking func (this *Inspector) getCandidateUniqueKeys(tableName string) (uniqueKeys [](*sql.UniqueKey), err error) { query := ` - SELECT - COLUMNS.TABLE_SCHEMA, - COLUMNS.TABLE_NAME, - COLUMNS.COLUMN_NAME, - UNIQUES.INDEX_NAME, - UNIQUES.COLUMN_NAMES, - UNIQUES.COUNT_COLUMN_IN_INDEX, - COLUMNS.DATA_TYPE, - COLUMNS.CHARACTER_SET_NAME, - LOCATE('auto_increment', EXTRA) > 0 as is_auto_increment, - has_nullable - FROM INFORMATION_SCHEMA.COLUMNS INNER JOIN ( - SELECT - TABLE_SCHEMA, - TABLE_NAME, - INDEX_NAME, - COUNT(*) AS COUNT_COLUMN_IN_INDEX, - GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COLUMN_NAMES, - SUBSTRING_INDEX(GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC), ',', 1) AS FIRST_COLUMN_NAME, - SUM(NULLABLE='YES') > 0 AS has_nullable - FROM INFORMATION_SCHEMA.STATISTICS - WHERE - NON_UNIQUE=0 - AND TABLE_SCHEMA = ? - AND TABLE_NAME = ? - GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME - ) AS UNIQUES - ON ( - COLUMNS.COLUMN_NAME = UNIQUES.FIRST_COLUMN_NAME - ) - WHERE - COLUMNS.TABLE_SCHEMA = ? - AND COLUMNS.TABLE_NAME = ? - ORDER BY - COLUMNS.TABLE_SCHEMA, COLUMNS.TABLE_NAME, - CASE UNIQUES.INDEX_NAME - WHEN 'PRIMARY' THEN 0 - ELSE 1 - END, - CASE has_nullable - WHEN 0 THEN 0 - ELSE 1 - END, - CASE IFNULL(CHARACTER_SET_NAME, '') - WHEN '' THEN 0 - ELSE 1 - END, - CASE DATA_TYPE - WHEN 'tinyint' THEN 0 - WHEN 'smallint' THEN 1 - WHEN 'int' THEN 2 - WHEN 'bigint' THEN 3 - ELSE 100 - END, - COUNT_COLUMN_IN_INDEX - ` + SELECT /* gh-ost */ + COLUMNS.TABLE_SCHEMA, + COLUMNS.TABLE_NAME, + COLUMNS.COLUMN_NAME, + UNIQUES.INDEX_NAME, + UNIQUES.COLUMN_NAMES, + UNIQUES.COUNT_COLUMN_IN_INDEX, + COLUMNS.DATA_TYPE, + COLUMNS.CHARACTER_SET_NAME, + LOCATE('auto_increment', EXTRA) > 0 as is_auto_increment, + has_nullable + FROM INFORMATION_SCHEMA.COLUMNS INNER JOIN ( + SELECT + TABLE_SCHEMA, + TABLE_NAME, + INDEX_NAME, + COUNT(*) AS COUNT_COLUMN_IN_INDEX, + GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COLUMN_NAMES, + SUBSTRING_INDEX(GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC), ',', 1) AS FIRST_COLUMN_NAME, + SUM(NULLABLE='YES') > 0 AS has_nullable + FROM INFORMATION_SCHEMA.STATISTICS + WHERE + NON_UNIQUE=0 + AND TABLE_SCHEMA = ? + AND TABLE_NAME = ? + GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME + ) AS UNIQUES + ON ( + COLUMNS.COLUMN_NAME = UNIQUES.FIRST_COLUMN_NAME + ) + WHERE + COLUMNS.TABLE_SCHEMA = ? + AND COLUMNS.TABLE_NAME = ? + ORDER BY + COLUMNS.TABLE_SCHEMA, COLUMNS.TABLE_NAME, + CASE UNIQUES.INDEX_NAME + WHEN 'PRIMARY' THEN 0 + ELSE 1 + END, + CASE has_nullable + WHEN 0 THEN 0 + ELSE 1 + END, + CASE IFNULL(CHARACTER_SET_NAME, '') + WHEN '' THEN 0 + ELSE 1 + END, + CASE DATA_TYPE + WHEN 'tinyint' THEN 0 + WHEN 'smallint' THEN 1 + WHEN 'int' THEN 2 + WHEN 'bigint' THEN 3 + ELSE 100 + END, + COUNT_COLUMN_IN_INDEX` err = sqlutils.QueryRowsMap(this.db, query, func(m sqlutils.RowMap) error { uniqueKey := &sql.UniqueKey{ Name: m.GetString("INDEX_NAME"), @@ -797,8 +791,9 @@ func (this *Inspector) showCreateTable(tableName string) (createTableStatement s // readChangelogState reads changelog hints func (this *Inspector) readChangelogState(hint string) (string, error) { query := fmt.Sprintf(` - select hint, value from %s.%s where hint = ? and id <= 255 - `, + select /* gh-ost */ hint, value from %s.%s + where + hint = ? and id <= 255`, sql.EscapeName(this.migrationContext.DatabaseName), sql.EscapeName(this.migrationContext.GetChangelogTableName()), ) diff --git a/go/sql/builder.go b/go/sql/builder.go index 0169390c2..ad60f98b3 100644 --- a/go/sql/builder.go +++ b/go/sql/builder.go @@ -222,11 +222,12 @@ func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName strin transactionalClause = "lock in share mode" } result = fmt.Sprintf(` - insert /* gh-ost %s.%s */ ignore into %s.%s (%s) - (select %s from %s.%s force index (%s) - where (%s and %s) %s - ) - `, databaseName, originalTableName, databaseName, ghostTableName, mappedSharedColumnsListing, + insert /* gh-ost %s.%s */ ignore into %s.%s (%s) ( + select %s from %s.%s + force index (%s) + where (%s and %s) %s + )`, + databaseName, originalTableName, databaseName, ghostTableName, mappedSharedColumnsListing, sharedColumnsListing, databaseName, originalTableName, uniqueKey, rangeStartComparison, rangeEndComparison, transactionalClause) return result, explodedArgs, nil @@ -274,16 +275,16 @@ func BuildUniqueKeyRangeEndPreparedQueryViaOffset(databaseName, tableName string } } result = fmt.Sprintf(` - select /* gh-ost %s.%s %s */ - %s - from - %s.%s - where %s and %s - order by - %s - limit 1 - offset %d - `, databaseName, tableName, hint, + select /* gh-ost %s.%s %s */ + %s + from + %s.%s + where %s and %s + order by + %s + limit 1 + offset %d`, + databaseName, tableName, hint, strings.Join(uniqueKeyColumnNames, ", "), databaseName, tableName, rangeStartComparison, rangeEndComparison, @@ -329,21 +330,19 @@ func BuildUniqueKeyRangeEndPreparedQueryViaTemptable(databaseName, tableName str } } result = fmt.Sprintf(` - select /* gh-ost %s.%s %s */ %s - from ( - select - %s - from - %s.%s - where %s and %s - order by - %s - limit %d - ) select_osc_chunk + select /* gh-ost %s.%s %s */ %s from ( + select + %s + from + %s.%s + where %s and %s order by %s - limit 1 - `, databaseName, tableName, hint, strings.Join(uniqueKeyColumnNames, ", "), + limit %d) select_osc_chunk + order by + %s + limit 1`, + databaseName, tableName, hint, strings.Join(uniqueKeyColumnNames, ", "), strings.Join(uniqueKeyColumnNames, ", "), databaseName, tableName, rangeStartComparison, rangeEndComparison, strings.Join(uniqueKeyColumnAscending, ", "), chunkSize, @@ -378,13 +377,12 @@ func buildUniqueKeyMinMaxValuesPreparedQuery(databaseName, tableName string, uni } } query := fmt.Sprintf(` - select /* gh-ost %s.%s */ %s - from - %s.%s - order by - %s - limit 1 - `, databaseName, tableName, strings.Join(uniqueKeyColumnNames, ", "), + select /* gh-ost %s.%s */ %s from + %s.%s + order by + %s + limit 1`, + databaseName, tableName, strings.Join(uniqueKeyColumnNames, ", "), databaseName, tableName, strings.Join(uniqueKeyColumnOrder, ", "), ) @@ -410,12 +408,11 @@ func BuildDMLDeleteQuery(databaseName, tableName string, tableColumns, uniqueKey return result, uniqueKeyArgs, err } result = fmt.Sprintf(` - delete /* gh-ost %s.%s */ - from - %s.%s - where - %s - `, databaseName, tableName, + delete /* gh-ost %s.%s */ from + %s.%s + where + %s`, + databaseName, tableName, databaseName, tableName, equalsComparison, ) @@ -448,12 +445,12 @@ func BuildDMLInsertQuery(databaseName, tableName string, tableColumns, sharedCol preparedValues := buildColumnsPreparedValues(mappedSharedColumns) result = fmt.Sprintf(` - replace /* gh-ost %s.%s */ into - %s.%s - (%s) - values - (%s) - `, databaseName, tableName, + replace /* gh-ost %s.%s */ into + %s.%s + (%s) + values + (%s)`, + databaseName, tableName, databaseName, tableName, strings.Join(mappedSharedColumnNames, ", "), strings.Join(preparedValues, ", "), @@ -505,13 +502,13 @@ func BuildDMLUpdateQuery(databaseName, tableName string, tableColumns, sharedCol return "", sharedArgs, uniqueKeyArgs, err } result = fmt.Sprintf(` - update /* gh-ost %s.%s */ - %s.%s - set - %s - where - %s - `, databaseName, tableName, + update /* gh-ost %s.%s */ + %s.%s + set + %s + where + %s`, + databaseName, tableName, databaseName, tableName, setClause, equalsComparison, From dae048231d5af138735e31ace0277a8dd8154e85 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Wed, 11 Jan 2023 23:03:57 +0100 Subject: [PATCH 2/7] cleanup --- go/logic/applier.go | 7 ++- go/logic/inspect.go | 132 +++++++++++++++++++++++--------------------- go/sql/builder.go | 18 ++++-- 3 files changed, 88 insertions(+), 69 deletions(-) diff --git a/go/logic/applier.go b/go/logic/applier.go index 2f06d3252..3c26eaba8 100644 --- a/go/logic/applier.go +++ b/go/logic/applier.go @@ -393,7 +393,9 @@ func (this *Applier) WriteChangelog(hint, value string) (string, error) { explicitId = 3 } query := fmt.Sprintf(` - insert /* gh-ost */ into %s.%s + insert /* gh-ost */ + into + %s.%s (id, hint, value) values (NULLIF(?, 0), ?, ?) @@ -868,7 +870,8 @@ func (this *Applier) ExpectProcess(sessionId int64, stateHint, infoHint string) found := false query := ` select /* gh-ost */ id - from information_schema.processlist + from + information_schema.processlist where id != connection_id() and ? in (0, id) diff --git a/go/logic/inspect.go b/go/logic/inspect.go index 069ca166b..2f0f8d495 100644 --- a/go/logic/inspect.go +++ b/go/logic/inspect.go @@ -444,11 +444,14 @@ func (this *Inspector) validateTableForeignKeys(allowChildForeignKeys bool) erro SELECT /* gh-ost */ SUM(REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_SCHEMA=? AND TABLE_NAME=?) as num_child_side_fk, SUM(REFERENCED_TABLE_NAME IS NOT NULL AND REFERENCED_TABLE_SCHEMA=? AND REFERENCED_TABLE_NAME=?) as num_parent_side_fk - FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + FROM + INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME IS NOT NULL - AND ((TABLE_SCHEMA=? AND TABLE_NAME=?) - OR (REFERENCED_TABLE_SCHEMA=? AND REFERENCED_TABLE_NAME=?) + AND ( + (TABLE_SCHEMA=? AND TABLE_NAME=?) + OR + (REFERENCED_TABLE_SCHEMA=? AND REFERENCED_TABLE_NAME=?) )` numParentForeignKeys := 0 numChildForeignKeys := 0 @@ -487,7 +490,8 @@ func (this *Inspector) validateTableForeignKeys(allowChildForeignKeys bool) erro func (this *Inspector) validateTableTriggers() error { query := ` SELECT /* gh-ost */ COUNT(*) AS num_triggers - FROM INFORMATION_SCHEMA.TRIGGERS + FROM + INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA=? AND EVENT_OBJECT_TABLE=?` @@ -629,9 +633,9 @@ func (this *Inspector) applyColumnTypes(databaseName, tableName string, columnsL // getAutoIncrementValue get's the original table's AUTO_INCREMENT value, if exists (0 value if not exists) func (this *Inspector) getAutoIncrementValue(tableName string) (autoIncrement uint64, err error) { query := ` - SELECT /* gh-ost */ - AUTO_INCREMENT - FROM INFORMATION_SCHEMA.TABLES + SELECT /* gh-ost */ AUTO_INCREMENT + FROM + INFORMATION_SCHEMA.TABLES WHERE TABLES.TABLE_SCHEMA = ? AND TABLES.TABLE_NAME = ? @@ -647,61 +651,63 @@ func (this *Inspector) getAutoIncrementValue(tableName string) (autoIncrement ui // candidate for chunking func (this *Inspector) getCandidateUniqueKeys(tableName string) (uniqueKeys [](*sql.UniqueKey), err error) { query := ` - SELECT /* gh-ost */ - COLUMNS.TABLE_SCHEMA, - COLUMNS.TABLE_NAME, - COLUMNS.COLUMN_NAME, - UNIQUES.INDEX_NAME, - UNIQUES.COLUMN_NAMES, - UNIQUES.COUNT_COLUMN_IN_INDEX, - COLUMNS.DATA_TYPE, - COLUMNS.CHARACTER_SET_NAME, - LOCATE('auto_increment', EXTRA) > 0 as is_auto_increment, - has_nullable - FROM INFORMATION_SCHEMA.COLUMNS INNER JOIN ( - SELECT - TABLE_SCHEMA, - TABLE_NAME, - INDEX_NAME, - COUNT(*) AS COUNT_COLUMN_IN_INDEX, - GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COLUMN_NAMES, - SUBSTRING_INDEX(GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC), ',', 1) AS FIRST_COLUMN_NAME, - SUM(NULLABLE='YES') > 0 AS has_nullable - FROM INFORMATION_SCHEMA.STATISTICS + SELECT /* gh-ost */ + COLUMNS.TABLE_SCHEMA, + COLUMNS.TABLE_NAME, + COLUMNS.COLUMN_NAME, + UNIQUES.INDEX_NAME, + UNIQUES.COLUMN_NAMES, + UNIQUES.COUNT_COLUMN_IN_INDEX, + COLUMNS.DATA_TYPE, + COLUMNS.CHARACTER_SET_NAME, + LOCATE('auto_increment', EXTRA) > 0 as is_auto_increment, + has_nullable + FROM + INFORMATION_SCHEMA.COLUMNS + INNER JOIN ( + SELECT + TABLE_SCHEMA, + TABLE_NAME, + INDEX_NAME, + COUNT(*) AS COUNT_COLUMN_IN_INDEX, + GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COLUMN_NAMES, + SUBSTRING_INDEX(GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC), ',', 1) AS FIRST_COLUMN_NAME, + SUM(NULLABLE='YES') > 0 AS has_nullable + FROM INFORMATION_SCHEMA.STATISTICS + WHERE + NON_UNIQUE=0 + AND TABLE_SCHEMA = ? + AND TABLE_NAME = ? + GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME + ) AS UNIQUES + ON ( + COLUMNS.COLUMN_NAME = UNIQUES.FIRST_COLUMN_NAME + ) WHERE - NON_UNIQUE=0 - AND TABLE_SCHEMA = ? - AND TABLE_NAME = ? - GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME - ) AS UNIQUES - ON ( - COLUMNS.COLUMN_NAME = UNIQUES.FIRST_COLUMN_NAME - ) - WHERE - COLUMNS.TABLE_SCHEMA = ? - AND COLUMNS.TABLE_NAME = ? - ORDER BY - COLUMNS.TABLE_SCHEMA, COLUMNS.TABLE_NAME, - CASE UNIQUES.INDEX_NAME - WHEN 'PRIMARY' THEN 0 - ELSE 1 - END, - CASE has_nullable - WHEN 0 THEN 0 - ELSE 1 - END, - CASE IFNULL(CHARACTER_SET_NAME, '') - WHEN '' THEN 0 - ELSE 1 - END, - CASE DATA_TYPE - WHEN 'tinyint' THEN 0 - WHEN 'smallint' THEN 1 - WHEN 'int' THEN 2 - WHEN 'bigint' THEN 3 - ELSE 100 - END, - COUNT_COLUMN_IN_INDEX` + COLUMNS.TABLE_SCHEMA = ? + AND COLUMNS.TABLE_NAME = ? + ORDER BY + COLUMNS.TABLE_SCHEMA, COLUMNS.TABLE_NAME, + CASE UNIQUES.INDEX_NAME + WHEN 'PRIMARY' THEN 0 + ELSE 1 + END, + CASE has_nullable + WHEN 0 THEN 0 + ELSE 1 + END, + CASE IFNULL(CHARACTER_SET_NAME, '') + WHEN '' THEN 0 + ELSE 1 + END, + CASE DATA_TYPE + WHEN 'tinyint' THEN 0 + WHEN 'smallint' THEN 1 + WHEN 'int' THEN 2 + WHEN 'bigint' THEN 3 + ELSE 100 + END, + COUNT_COLUMN_IN_INDEX` err = sqlutils.QueryRowsMap(this.db, query, func(m sqlutils.RowMap) error { uniqueKey := &sql.UniqueKey{ Name: m.GetString("INDEX_NAME"), @@ -791,7 +797,9 @@ func (this *Inspector) showCreateTable(tableName string) (createTableStatement s // readChangelogState reads changelog hints func (this *Inspector) readChangelogState(hint string) (string, error) { query := fmt.Sprintf(` - select /* gh-ost */ hint, value from %s.%s + select /* gh-ost */ hint, value + from + %s.%s where hint = ? and id <= 255`, sql.EscapeName(this.migrationContext.DatabaseName), diff --git a/go/sql/builder.go b/go/sql/builder.go index ad60f98b3..5045dec94 100644 --- a/go/sql/builder.go +++ b/go/sql/builder.go @@ -222,7 +222,11 @@ func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName strin transactionalClause = "lock in share mode" } result = fmt.Sprintf(` - insert /* gh-ost %s.%s */ ignore into %s.%s (%s) ( + insert /* gh-ost %s.%s */ ignore + into + %s.%s + (%s) + ( select %s from %s.%s force index (%s) where (%s and %s) %s @@ -330,7 +334,8 @@ func BuildUniqueKeyRangeEndPreparedQueryViaTemptable(databaseName, tableName str } } result = fmt.Sprintf(` - select /* gh-ost %s.%s %s */ %s from ( + select /* gh-ost %s.%s %s */ %s + from ( select %s from @@ -377,7 +382,8 @@ func buildUniqueKeyMinMaxValuesPreparedQuery(databaseName, tableName string, uni } } query := fmt.Sprintf(` - select /* gh-ost %s.%s */ %s from + select /* gh-ost %s.%s */ %s + from %s.%s order by %s @@ -408,7 +414,8 @@ func BuildDMLDeleteQuery(databaseName, tableName string, tableColumns, uniqueKey return result, uniqueKeyArgs, err } result = fmt.Sprintf(` - delete /* gh-ost %s.%s */ from + delete /* gh-ost %s.%s */ + from %s.%s where %s`, @@ -445,7 +452,8 @@ func BuildDMLInsertQuery(databaseName, tableName string, tableColumns, sharedCol preparedValues := buildColumnsPreparedValues(mappedSharedColumns) result = fmt.Sprintf(` - replace /* gh-ost %s.%s */ into + replace /* gh-ost %s.%s */ + into %s.%s (%s) values From 4042892090892b212d75b9c4fb7c7fc0e31d5a25 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Wed, 11 Jan 2023 23:24:09 +0100 Subject: [PATCH 3/7] Add indent --- go/logic/inspect.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/go/logic/inspect.go b/go/logic/inspect.go index 2f0f8d495..3b56c7fe7 100644 --- a/go/logic/inspect.go +++ b/go/logic/inspect.go @@ -673,12 +673,16 @@ func (this *Inspector) getCandidateUniqueKeys(tableName string) (uniqueKeys [](* GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COLUMN_NAMES, SUBSTRING_INDEX(GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC), ',', 1) AS FIRST_COLUMN_NAME, SUM(NULLABLE='YES') > 0 AS has_nullable - FROM INFORMATION_SCHEMA.STATISTICS + FROM + INFORMATION_SCHEMA.STATISTICS WHERE NON_UNIQUE=0 AND TABLE_SCHEMA = ? AND TABLE_NAME = ? - GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME + GROUP BY + TABLE_SCHEMA, + TABLE_NAME, + INDEX_NAME ) AS UNIQUES ON ( COLUMNS.COLUMN_NAME = UNIQUES.FIRST_COLUMN_NAME From 6f1de5dea82dffb51f93cb9574b7d12eed7fa728 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Wed, 11 Jan 2023 23:37:05 +0100 Subject: [PATCH 4/7] Update unit tests --- go/sql/builder_test.go | 124 ++++++++++++++++++++++++++++------------- 1 file changed, 85 insertions(+), 39 deletions(-) diff --git a/go/sql/builder_test.go b/go/sql/builder_test.go index 299824269..dd0efc979 100644 --- a/go/sql/builder_test.go +++ b/go/sql/builder_test.go @@ -175,11 +175,19 @@ func TestBuildRangeInsertQuery(t *testing.T) { query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false) test.S(t).ExpectNil(err) expected := ` - insert /* gh-ost mydb.tbl */ ignore into mydb.ghost (id, name, position) - (select id, name, position from mydb.tbl force index (PRIMARY) - where (((id > @v1s) or ((id = @v1s))) and ((id < @v1e) or ((id = @v1e)))) - ) - ` + insert /* gh-ost mydb.tbl */ ignore + into + mydb.ghost + (id, name, position) + ( + select id, name, position + from + mydb.tbl + force index (PRIMARY) + where + (((id > @v1s) or ((id = @v1s))) + and ((id < @v1e) or ((id = @v1e)))) + )` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 103, 103})) } @@ -194,11 +202,25 @@ func TestBuildRangeInsertQuery(t *testing.T) { query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false) test.S(t).ExpectNil(err) expected := ` - insert /* gh-ost mydb.tbl */ ignore into mydb.ghost (id, name, position) - (select id, name, position from mydb.tbl force index (name_position_uidx) - where (((name > @v1s) or (((name = @v1s)) AND (position > @v2s)) or ((name = @v1s) and (position = @v2s))) and ((name < @v1e) or (((name = @v1e)) AND (position < @v2e)) or ((name = @v1e) and (position = @v2e)))) - ) - ` + insert /* gh-ost mydb.tbl */ ignore + into + mydb.ghost + (id, name, position) + ( + select id, name, position + from + mydb.tbl + force index (name_position_uidx) + where + (((name > @v1s) or (((name = @v1s)) + AND (position > @v2s)) + or ((name = @v1s) + and (position = @v2s))) + and ((name < @v1e) + or (((name = @v1e)) + AND (position < @v2e)) + or ((name = @v1e) and (position = @v2e)))) + )` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 103, 103, 117, 103, 117})) } @@ -221,11 +243,20 @@ func TestBuildRangeInsertQueryRenameMap(t *testing.T) { query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, mappedSharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false) test.S(t).ExpectNil(err) expected := ` - insert /* gh-ost mydb.tbl */ ignore into mydb.ghost (id, name, location) - (select id, name, position from mydb.tbl force index (PRIMARY) - where (((id > @v1s) or ((id = @v1s))) and ((id < @v1e) or ((id = @v1e)))) - ) - ` + insert /* gh-ost mydb.tbl */ ignore + into + mydb.ghost + (id, name, location) + ( + select id, name, position + from + mydb.tbl + force index (PRIMARY) + where + (((id > @v1s) or ((id = @v1s))) + and + ((id < @v1e) or ((id = @v1e)))) + )` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 103, 103})) } @@ -240,11 +271,21 @@ func TestBuildRangeInsertQueryRenameMap(t *testing.T) { query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, mappedSharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true, false) test.S(t).ExpectNil(err) expected := ` - insert /* gh-ost mydb.tbl */ ignore into mydb.ghost (id, name, location) - (select id, name, position from mydb.tbl force index (name_position_uidx) - where (((name > @v1s) or (((name = @v1s)) AND (position > @v2s)) or ((name = @v1s) and (position = @v2s))) and ((name < @v1e) or (((name = @v1e)) AND (position < @v2e)) or ((name = @v1e) and (position = @v2e)))) - ) - ` + insert /* gh-ost mydb.tbl */ ignore + into + mydb.ghost + (id, name, location) + ( + select id, name, position + from + mydb.tbl + force index (name_position_uidx) + where + (((name > @v1s) or (((name = @v1s)) + AND (position > @v2s)) or ((name = @v1s) and (position = @v2s))) + and ((name < @v1e) or (((name = @v1e)) AND (position < @v2e)) + or ((name = @v1e) and (position = @v2e)))) + )` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 103, 103, 117, 103, 117})) } @@ -264,11 +305,18 @@ func TestBuildRangeInsertPreparedQuery(t *testing.T) { query, explodedArgs, err := BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName, sharedColumns, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartArgs, rangeEndArgs, true, true) test.S(t).ExpectNil(err) expected := ` - insert /* gh-ost mydb.tbl */ ignore into mydb.ghost (id, name, position) - (select id, name, position from mydb.tbl force index (name_position_uidx) - where (((name > ?) or (((name = ?)) AND (position > ?)) or ((name = ?) and (position = ?))) and ((name < ?) or (((name = ?)) AND (position < ?)) or ((name = ?) and (position = ?)))) - lock in share mode ) - ` + insert /* gh-ost mydb.tbl */ ignore + into + mydb.ghost + (id, name, position) + ( + select id, name, position + from + mydb.tbl + force index (name_position_uidx) + where (((name > ?) or (((name = ?)) AND (position > ?)) or ((name = ?) and (position = ?))) and ((name < ?) or (((name = ?)) AND (position < ?)) or ((name = ?) and (position = ?)))) + lock in share mode + )` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 103, 103, 117, 103, 117})) } @@ -286,21 +334,19 @@ func TestBuildUniqueKeyRangeEndPreparedQuery(t *testing.T) { query, explodedArgs, err := BuildUniqueKeyRangeEndPreparedQueryViaTemptable(databaseName, originalTableName, uniqueKeyColumns, rangeStartArgs, rangeEndArgs, chunkSize, false, "test") test.S(t).ExpectNil(err) expected := ` - select /* gh-ost mydb.tbl test */ name, position - from ( - select - name, position - from - mydb.tbl - where ((name > ?) or (((name = ?)) AND (position > ?))) and ((name < ?) or (((name = ?)) AND (position < ?)) or ((name = ?) and (position = ?))) - order by - name asc, position asc - limit 500 - ) select_osc_chunk + select /* gh-ost mydb.tbl test */ name, position + from ( + select + name, position + from + mydb.tbl + where ((name > ?) or (((name = ?)) AND (position > ?))) and ((name < ?) or (((name = ?)) AND (position < ?)) or ((name = ?) and (position = ?))) order by - name desc, position desc - limit 1 - ` + name asc, position asc + limit 500) select_osc_chunk + order by + name desc, position desc + limit 1` test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected)) test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 103, 103, 117, 103, 117})) } From 704c4120d3630ce5db2c392490034ded84396702 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Wed, 11 Jan 2023 23:42:34 +0100 Subject: [PATCH 5/7] Update unit tests, pt 2 --- go/logic/applier_test.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/go/logic/applier_test.go b/go/logic/applier_test.go index a3563511f..36c28d9e8 100644 --- a/go/logic/applier_test.go +++ b/go/logic/applier_test.go @@ -114,13 +114,12 @@ func TestApplierBuildDMLEventQuery(t *testing.T) { res := applier.buildDMLEventQuery(binlogEvent) test.S(t).ExpectEquals(len(res), 1) test.S(t).ExpectNil(res[0].err) - test.S(t).ExpectEquals(strings.TrimSpace(res[0].query), - `delete /* gh-ost `+"`test`.`_test_gho`"+` */ - from - `+"`test`.`_test_gho`"+` - where - ((`+"`id`"+` = ?) and (`+"`item_id`"+` = ?))`) - + test.S(t).ExpectEquals(strings.TrimSpace(res[0].query), `delete /* gh-ost `+"`test`.`_test_gho`"+` */ + from + `+"`test`.`_test_gho`"+` + where + ((`+"`id`"+` = ?) and (`+"`item_id`"+` = ?))`, + ) test.S(t).ExpectEquals(len(res[0].args), 2) test.S(t).ExpectEquals(res[0].args[0], 123456) test.S(t).ExpectEquals(res[0].args[1], 42) @@ -136,11 +135,12 @@ func TestApplierBuildDMLEventQuery(t *testing.T) { test.S(t).ExpectEquals(len(res), 1) test.S(t).ExpectNil(res[0].err) test.S(t).ExpectEquals(strings.TrimSpace(res[0].query), - `replace /* gh-ost `+"`test`.`_test_gho`"+` */ into - `+"`test`.`_test_gho`"+` - `+"(`id`, `item_id`)"+` - values - (?, ?)`) + `replace /* gh-ost `+"`test`.`_test_gho`"+` */ + into + `+"`test`.`_test_gho`"+` + `+"(`id`, `item_id`)"+` + values + (?, ?)`) test.S(t).ExpectEquals(len(res[0].args), 2) test.S(t).ExpectEquals(res[0].args[0], 123456) test.S(t).ExpectEquals(res[0].args[1], 42) @@ -158,11 +158,11 @@ func TestApplierBuildDMLEventQuery(t *testing.T) { test.S(t).ExpectNil(res[0].err) test.S(t).ExpectEquals(strings.TrimSpace(res[0].query), `update /* gh-ost `+"`test`.`_test_gho`"+` */ - `+"`test`.`_test_gho`"+` - set - `+"`id`"+`=?, `+"`item_id`"+`=? - where - ((`+"`id`"+` = ?) and (`+"`item_id`"+` = ?))`) + `+"`test`.`_test_gho`"+` + set + `+"`id`"+`=?, `+"`item_id`"+`=? + where + ((`+"`id`"+` = ?) and (`+"`item_id`"+` = ?))`) test.S(t).ExpectEquals(len(res[0].args), 4) test.S(t).ExpectEquals(res[0].args[0], 123456) test.S(t).ExpectEquals(res[0].args[1], 42) From 7766a35651b8fcecf2d41426caf033d46eaa399f Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Wed, 11 Jan 2023 23:45:27 +0100 Subject: [PATCH 6/7] Fix tweaks --- go/logic/applier.go | 2 +- go/sql/builder.go | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/go/logic/applier.go b/go/logic/applier.go index 3c26eaba8..516a3e727 100644 --- a/go/logic/applier.go +++ b/go/logic/applier.go @@ -876,7 +876,7 @@ func (this *Applier) ExpectProcess(sessionId int64, stateHint, infoHint string) id != connection_id() and ? in (0, id) and state like concat('%', ?, '%') - and info like concat('%', ?, '%')` + and info like concat('%', ?, '%')` err := sqlutils.QueryRowsMap(this.db, query, func(m sqlutils.RowMap) error { found = true return nil diff --git a/go/sql/builder.go b/go/sql/builder.go index 5045dec94..36571c312 100644 --- a/go/sql/builder.go +++ b/go/sql/builder.go @@ -227,9 +227,13 @@ func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName strin %s.%s (%s) ( - select %s from %s.%s + select %s + from + %s.%s force index (%s) - where (%s and %s) %s + where + (%s and %s) + %s )`, databaseName, originalTableName, databaseName, ghostTableName, mappedSharedColumnsListing, sharedColumnsListing, databaseName, originalTableName, uniqueKey, @@ -283,7 +287,8 @@ func BuildUniqueKeyRangeEndPreparedQueryViaOffset(databaseName, tableName string %s from %s.%s - where %s and %s + where + %s and %s order by %s limit 1 @@ -340,7 +345,8 @@ func BuildUniqueKeyRangeEndPreparedQueryViaTemptable(databaseName, tableName str %s from %s.%s - where %s and %s + where + %s and %s order by %s limit %d) select_osc_chunk From 17e8fba93f6a915c49a6e744a4db5067b670e08f Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Fri, 8 Dec 2023 23:21:03 +0100 Subject: [PATCH 7/7] Fix merge conflict resolution Signed-off-by: Tim Vaillancourt --- go/sql/builder.go | 1 + 1 file changed, 1 insertion(+) diff --git a/go/sql/builder.go b/go/sql/builder.go index 6dd51de12..7be428f93 100644 --- a/go/sql/builder.go +++ b/go/sql/builder.go @@ -391,6 +391,7 @@ func buildUniqueKeyMinMaxValuesPreparedQuery(databaseName, tableName string, uni select /* gh-ost %s.%s */ %s from %s.%s + force index (%s) order by %s limit 1`,